mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 05:45:37 +00:00
Merged JSMap & JSObject. Introduced JSNamespace.
This commit is contained in:
parent
2f139b43ae
commit
1f0e341d77
@ -210,13 +210,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
||||
case LOAD_NAME:
|
||||
{
|
||||
LoadName* ln = static_cast<LoadName*>(instruction);
|
||||
(*registers)[dst(ln)] = mGlobal->getProperty(*src1(ln));
|
||||
(*registers)[dst(ln)] = mGlobal->getVariable(*src1(ln));
|
||||
}
|
||||
break;
|
||||
case SAVE_NAME:
|
||||
{
|
||||
SaveName* sn = static_cast<SaveName*>(instruction);
|
||||
mGlobal->setProperty(*dst(sn), (*registers)[src1(sn)]);
|
||||
mGlobal->setVariable(*dst(sn), (*registers)[src1(sn)]);
|
||||
}
|
||||
break;
|
||||
case NEW_OBJECT:
|
||||
|
@ -35,16 +35,16 @@ namespace Interpreter {
|
||||
|
||||
class Context : public gc_base {
|
||||
public:
|
||||
explicit Context(World& world, JSObject* aGlobal)
|
||||
explicit Context(World& world, JSNamespace* aGlobal)
|
||||
: mWorld(world), mGlobal(aGlobal), mLinkage(0)
|
||||
{
|
||||
}
|
||||
|
||||
JSObject* getGlobalObject() { return mGlobal; }
|
||||
JSNamespace* getGlobalObject() { return mGlobal; }
|
||||
|
||||
JSObject* setGlobalObject(JSObject* aGlobal)
|
||||
JSNamespace* setGlobalObject(JSNamespace* aGlobal)
|
||||
{
|
||||
JSObject* t = mGlobal;
|
||||
JSNamespace* t = mGlobal;
|
||||
mGlobal = aGlobal;
|
||||
return t;
|
||||
}
|
||||
@ -72,7 +72,7 @@ namespace Interpreter {
|
||||
|
||||
private:
|
||||
World& mWorld;
|
||||
JSObject* mGlobal;
|
||||
JSNamespace* mGlobal;
|
||||
Linkage* mLinkage;
|
||||
std::vector<Listener*> mListeners;
|
||||
}; /* class Context */
|
||||
|
@ -272,7 +272,7 @@ static void testICG(World &world)
|
||||
|
||||
static float64 testFunctionCall(World &world, float64 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
Tracer t;
|
||||
cx.addListener(&t);
|
||||
@ -325,7 +325,7 @@ static float64 testFunctionCall(World &world, float64 n)
|
||||
|
||||
static float64 testFactorial(World &world, float64 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
// generate code for factorial, and interpret it.
|
||||
uint32 position = 0;
|
||||
@ -390,7 +390,7 @@ static float64 testFactorial(World &world, float64 n)
|
||||
|
||||
static float64 testObjects(World &world, int32 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
// create some objects, put some properties, and retrieve them.
|
||||
uint32 position = 0;
|
||||
@ -456,7 +456,7 @@ static float64 testObjects(World &world, int32 n)
|
||||
|
||||
static float64 testProto(World &world, int32 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
|
||||
Tracer t;
|
||||
@ -515,8 +515,8 @@ static float64 testProto(World &world, int32 n)
|
||||
cx.interpret(initCode, args);
|
||||
|
||||
// objects now exist, do real prototype chain manipulation.
|
||||
JSObject* globalObject = glob.getProperty(global).object;
|
||||
globalObject->setPrototype(glob.getProperty(proto).object);
|
||||
JSObject* globalObject = glob.getVariable(global).object;
|
||||
globalObject->setPrototype(glob.getVariable(proto).object);
|
||||
|
||||
// generate call to global.increment()
|
||||
ICodeGenerator callCG;
|
||||
@ -533,7 +533,7 @@ static float64 testProto(World &world, int32 n)
|
||||
while (n-- > 0)
|
||||
(void) cx.interpret(callCode, args);
|
||||
|
||||
JSValue result = glob.getProperty(global).object->getProperty(counter);
|
||||
JSValue result = glob.getVariable(global).object->getProperty(counter);
|
||||
|
||||
stdOut << "result = " << result.f64 << "\n";
|
||||
|
||||
|
@ -118,17 +118,20 @@ namespace JSTypes {
|
||||
extern const JSValue kUndefinedValue;
|
||||
|
||||
/**
|
||||
* Basic behavior of all JS objects, mapping a name to a value.
|
||||
* This is provided mainly to avoid having an awkward implementation
|
||||
* of JSObject & JSArray, which must each define its own
|
||||
* gc_allocator. This is all in flux.
|
||||
* Basic behavior of all JS objects, mapping a name to a value,
|
||||
* with prototype-based inheritance.
|
||||
*/
|
||||
class JSMap : public gc_base {
|
||||
class JSObject : public gc_base {
|
||||
protected:
|
||||
typedef std::map<String, JSValue, std::less<String>, gc_map_allocator> JSProperties;
|
||||
JSProperties mProperties;
|
||||
JSMap* mPrototype;
|
||||
JSObject* mPrototype;
|
||||
public:
|
||||
bool hasProperty(const String& name)
|
||||
{
|
||||
return (mProperties.count(name) != 0);
|
||||
}
|
||||
|
||||
const JSValue& getProperty(const String& name)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
@ -152,53 +155,33 @@ namespace JSTypes {
|
||||
return (mProperties[name] = value);
|
||||
}
|
||||
|
||||
void setPrototype(JSMap* prototype)
|
||||
void setPrototype(JSObject* prototype)
|
||||
{
|
||||
mPrototype = prototype;
|
||||
}
|
||||
|
||||
JSMap* getPrototype()
|
||||
JSObject* getPrototype()
|
||||
{
|
||||
return mPrototype;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Private representation of a JS function. This simply
|
||||
* holds a reference to the iCode module that is the
|
||||
* compiled code of the function.
|
||||
*/
|
||||
class JSFunction : public JSMap {
|
||||
class JSFunction : public JSObject {
|
||||
ICodeModule* mICode;
|
||||
public:
|
||||
JSFunction(ICodeModule* iCode) : mICode(iCode) {}
|
||||
ICodeModule* getICode() { return mICode; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Private representation of a JavaScript object.
|
||||
* This will change over time, so it is treated as an opaque
|
||||
* type everywhere else but here.
|
||||
*/
|
||||
class JSObject : public JSMap {
|
||||
public:
|
||||
JSValue& defineProperty(const String& name, const JSValue& value)
|
||||
{
|
||||
return (mProperties[name] = value);
|
||||
}
|
||||
|
||||
// FIXME: need to copy the ICodeModule's instruction stream.
|
||||
JSValue& defineFunction(const String& name, ICodeModule* iCode)
|
||||
{
|
||||
JSValue value(new JSFunction(iCode));
|
||||
return defineProperty(name, value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Private representation of a JavaScript array.
|
||||
*/
|
||||
class JSArray : public JSMap {
|
||||
class JSArray : public JSObject {
|
||||
JSValues elements;
|
||||
public:
|
||||
JSArray() : elements(1) {}
|
||||
@ -248,7 +231,46 @@ namespace JSTypes {
|
||||
JSException(JSValue v) : value(v) { }
|
||||
JSValue value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides a set of nested scopes.
|
||||
*/
|
||||
class JSNamespace : private JSObject {
|
||||
protected:
|
||||
JSNamespace* mParent;
|
||||
public:
|
||||
bool isDefined(const String& name)
|
||||
{
|
||||
if (hasProperty(name))
|
||||
return true;
|
||||
if (mParent)
|
||||
return mParent->isDefined(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
const JSValue& getVariable(const String& name)
|
||||
{
|
||||
return getProperty(name);
|
||||
}
|
||||
|
||||
JSValue& setVariable(const String& name, const JSValue& value)
|
||||
{
|
||||
return setProperty(name, value);
|
||||
}
|
||||
|
||||
JSValue& defineVariable(const String& name, const JSValue& value)
|
||||
{
|
||||
return setProperty(name, value);
|
||||
}
|
||||
|
||||
// FIXME: need to copy the ICodeModule's instruction stream.
|
||||
JSValue& defineFunction(const String& name, ICodeModule* iCode)
|
||||
{
|
||||
JSValue value(new JSFunction(iCode));
|
||||
return defineVariable(name, value);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
@ -210,13 +210,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
||||
case LOAD_NAME:
|
||||
{
|
||||
LoadName* ln = static_cast<LoadName*>(instruction);
|
||||
(*registers)[dst(ln)] = mGlobal->getProperty(*src1(ln));
|
||||
(*registers)[dst(ln)] = mGlobal->getVariable(*src1(ln));
|
||||
}
|
||||
break;
|
||||
case SAVE_NAME:
|
||||
{
|
||||
SaveName* sn = static_cast<SaveName*>(instruction);
|
||||
mGlobal->setProperty(*dst(sn), (*registers)[src1(sn)]);
|
||||
mGlobal->setVariable(*dst(sn), (*registers)[src1(sn)]);
|
||||
}
|
||||
break;
|
||||
case NEW_OBJECT:
|
||||
|
@ -35,16 +35,16 @@ namespace Interpreter {
|
||||
|
||||
class Context : public gc_base {
|
||||
public:
|
||||
explicit Context(World& world, JSObject* aGlobal)
|
||||
explicit Context(World& world, JSNamespace* aGlobal)
|
||||
: mWorld(world), mGlobal(aGlobal), mLinkage(0)
|
||||
{
|
||||
}
|
||||
|
||||
JSObject* getGlobalObject() { return mGlobal; }
|
||||
JSNamespace* getGlobalObject() { return mGlobal; }
|
||||
|
||||
JSObject* setGlobalObject(JSObject* aGlobal)
|
||||
JSNamespace* setGlobalObject(JSNamespace* aGlobal)
|
||||
{
|
||||
JSObject* t = mGlobal;
|
||||
JSNamespace* t = mGlobal;
|
||||
mGlobal = aGlobal;
|
||||
return t;
|
||||
}
|
||||
@ -72,7 +72,7 @@ namespace Interpreter {
|
||||
|
||||
private:
|
||||
World& mWorld;
|
||||
JSObject* mGlobal;
|
||||
JSNamespace* mGlobal;
|
||||
Linkage* mLinkage;
|
||||
std::vector<Listener*> mListeners;
|
||||
}; /* class Context */
|
||||
|
@ -118,17 +118,20 @@ namespace JSTypes {
|
||||
extern const JSValue kUndefinedValue;
|
||||
|
||||
/**
|
||||
* Basic behavior of all JS objects, mapping a name to a value.
|
||||
* This is provided mainly to avoid having an awkward implementation
|
||||
* of JSObject & JSArray, which must each define its own
|
||||
* gc_allocator. This is all in flux.
|
||||
* Basic behavior of all JS objects, mapping a name to a value,
|
||||
* with prototype-based inheritance.
|
||||
*/
|
||||
class JSMap : public gc_base {
|
||||
class JSObject : public gc_base {
|
||||
protected:
|
||||
typedef std::map<String, JSValue, std::less<String>, gc_map_allocator> JSProperties;
|
||||
JSProperties mProperties;
|
||||
JSMap* mPrototype;
|
||||
JSObject* mPrototype;
|
||||
public:
|
||||
bool hasProperty(const String& name)
|
||||
{
|
||||
return (mProperties.count(name) != 0);
|
||||
}
|
||||
|
||||
const JSValue& getProperty(const String& name)
|
||||
{
|
||||
#ifdef XP_MAC
|
||||
@ -152,53 +155,33 @@ namespace JSTypes {
|
||||
return (mProperties[name] = value);
|
||||
}
|
||||
|
||||
void setPrototype(JSMap* prototype)
|
||||
void setPrototype(JSObject* prototype)
|
||||
{
|
||||
mPrototype = prototype;
|
||||
}
|
||||
|
||||
JSMap* getPrototype()
|
||||
JSObject* getPrototype()
|
||||
{
|
||||
return mPrototype;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Private representation of a JS function. This simply
|
||||
* holds a reference to the iCode module that is the
|
||||
* compiled code of the function.
|
||||
*/
|
||||
class JSFunction : public JSMap {
|
||||
class JSFunction : public JSObject {
|
||||
ICodeModule* mICode;
|
||||
public:
|
||||
JSFunction(ICodeModule* iCode) : mICode(iCode) {}
|
||||
ICodeModule* getICode() { return mICode; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Private representation of a JavaScript object.
|
||||
* This will change over time, so it is treated as an opaque
|
||||
* type everywhere else but here.
|
||||
*/
|
||||
class JSObject : public JSMap {
|
||||
public:
|
||||
JSValue& defineProperty(const String& name, const JSValue& value)
|
||||
{
|
||||
return (mProperties[name] = value);
|
||||
}
|
||||
|
||||
// FIXME: need to copy the ICodeModule's instruction stream.
|
||||
JSValue& defineFunction(const String& name, ICodeModule* iCode)
|
||||
{
|
||||
JSValue value(new JSFunction(iCode));
|
||||
return defineProperty(name, value);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Private representation of a JavaScript array.
|
||||
*/
|
||||
class JSArray : public JSMap {
|
||||
class JSArray : public JSObject {
|
||||
JSValues elements;
|
||||
public:
|
||||
JSArray() : elements(1) {}
|
||||
@ -248,7 +231,46 @@ namespace JSTypes {
|
||||
JSException(JSValue v) : value(v) { }
|
||||
JSValue value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Provides a set of nested scopes.
|
||||
*/
|
||||
class JSNamespace : private JSObject {
|
||||
protected:
|
||||
JSNamespace* mParent;
|
||||
public:
|
||||
bool isDefined(const String& name)
|
||||
{
|
||||
if (hasProperty(name))
|
||||
return true;
|
||||
if (mParent)
|
||||
return mParent->isDefined(name);
|
||||
return false;
|
||||
}
|
||||
|
||||
const JSValue& getVariable(const String& name)
|
||||
{
|
||||
return getProperty(name);
|
||||
}
|
||||
|
||||
JSValue& setVariable(const String& name, const JSValue& value)
|
||||
{
|
||||
return setProperty(name, value);
|
||||
}
|
||||
|
||||
JSValue& defineVariable(const String& name, const JSValue& value)
|
||||
{
|
||||
return setProperty(name, value);
|
||||
}
|
||||
|
||||
// FIXME: need to copy the ICodeModule's instruction stream.
|
||||
JSValue& defineFunction(const String& name, ICodeModule* iCode)
|
||||
{
|
||||
JSValue value(new JSFunction(iCode));
|
||||
return defineVariable(name, value);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace JSTypes */
|
||||
} /* namespace JavaScript */
|
||||
|
||||
|
@ -272,7 +272,7 @@ static void testICG(World &world)
|
||||
|
||||
static float64 testFunctionCall(World &world, float64 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
Tracer t;
|
||||
cx.addListener(&t);
|
||||
@ -325,7 +325,7 @@ static float64 testFunctionCall(World &world, float64 n)
|
||||
|
||||
static float64 testFactorial(World &world, float64 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
// generate code for factorial, and interpret it.
|
||||
uint32 position = 0;
|
||||
@ -390,7 +390,7 @@ static float64 testFactorial(World &world, float64 n)
|
||||
|
||||
static float64 testObjects(World &world, int32 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
// create some objects, put some properties, and retrieve them.
|
||||
uint32 position = 0;
|
||||
@ -456,7 +456,7 @@ static float64 testObjects(World &world, int32 n)
|
||||
|
||||
static float64 testProto(World &world, int32 n)
|
||||
{
|
||||
JSObject glob;
|
||||
JSNamespace glob;
|
||||
Context cx(world, &glob);
|
||||
|
||||
Tracer t;
|
||||
@ -515,8 +515,8 @@ static float64 testProto(World &world, int32 n)
|
||||
cx.interpret(initCode, args);
|
||||
|
||||
// objects now exist, do real prototype chain manipulation.
|
||||
JSObject* globalObject = glob.getProperty(global).object;
|
||||
globalObject->setPrototype(glob.getProperty(proto).object);
|
||||
JSObject* globalObject = glob.getVariable(global).object;
|
||||
globalObject->setPrototype(glob.getVariable(proto).object);
|
||||
|
||||
// generate call to global.increment()
|
||||
ICodeGenerator callCG;
|
||||
@ -533,7 +533,7 @@ static float64 testProto(World &world, int32 n)
|
||||
while (n-- > 0)
|
||||
(void) cx.interpret(callCode, args);
|
||||
|
||||
JSValue result = glob.getProperty(global).object->getProperty(counter);
|
||||
JSValue result = glob.getVariable(global).object->getProperty(counter);
|
||||
|
||||
stdOut << "result = " << result.f64 << "\n";
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user