diff --git a/mozilla/js/js2/interpreter.cpp b/mozilla/js/js2/interpreter.cpp index 079550eac37..aaa88543700 100644 --- a/mozilla/js/js2/interpreter.cpp +++ b/mozilla/js/js2/interpreter.cpp @@ -210,13 +210,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) case LOAD_NAME: { LoadName* ln = static_cast(instruction); - (*registers)[dst(ln)] = mGlobal->getProperty(*src1(ln)); + (*registers)[dst(ln)] = mGlobal->getVariable(*src1(ln)); } break; case SAVE_NAME: { SaveName* sn = static_cast(instruction); - mGlobal->setProperty(*dst(sn), (*registers)[src1(sn)]); + mGlobal->setVariable(*dst(sn), (*registers)[src1(sn)]); } break; case NEW_OBJECT: diff --git a/mozilla/js/js2/interpreter.h b/mozilla/js/js2/interpreter.h index 973794ac767..43297fde002 100644 --- a/mozilla/js/js2/interpreter.h +++ b/mozilla/js/js2/interpreter.h @@ -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 mListeners; }; /* class Context */ diff --git a/mozilla/js/js2/js2.cpp b/mozilla/js/js2/js2.cpp index 1b472abc1e7..56c89dcbd12 100644 --- a/mozilla/js/js2/js2.cpp +++ b/mozilla/js/js2/js2.cpp @@ -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"; diff --git a/mozilla/js/js2/jstypes.h b/mozilla/js/js2/jstypes.h index 88f91d6da8c..1b89a01396a 100644 --- a/mozilla/js/js2/jstypes.h +++ b/mozilla/js/js2/jstypes.h @@ -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, 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 */ diff --git a/mozilla/js2/src/interpreter.cpp b/mozilla/js2/src/interpreter.cpp index 079550eac37..aaa88543700 100644 --- a/mozilla/js2/src/interpreter.cpp +++ b/mozilla/js2/src/interpreter.cpp @@ -210,13 +210,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) case LOAD_NAME: { LoadName* ln = static_cast(instruction); - (*registers)[dst(ln)] = mGlobal->getProperty(*src1(ln)); + (*registers)[dst(ln)] = mGlobal->getVariable(*src1(ln)); } break; case SAVE_NAME: { SaveName* sn = static_cast(instruction); - mGlobal->setProperty(*dst(sn), (*registers)[src1(sn)]); + mGlobal->setVariable(*dst(sn), (*registers)[src1(sn)]); } break; case NEW_OBJECT: diff --git a/mozilla/js2/src/interpreter.h b/mozilla/js2/src/interpreter.h index 973794ac767..43297fde002 100644 --- a/mozilla/js2/src/interpreter.h +++ b/mozilla/js2/src/interpreter.h @@ -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 mListeners; }; /* class Context */ diff --git a/mozilla/js2/src/jstypes.h b/mozilla/js2/src/jstypes.h index 88f91d6da8c..1b89a01396a 100644 --- a/mozilla/js2/src/jstypes.h +++ b/mozilla/js2/src/jstypes.h @@ -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, 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 */ diff --git a/mozilla/js2/tests/cpp/js2_shell.cpp b/mozilla/js2/tests/cpp/js2_shell.cpp index 1b472abc1e7..56c89dcbd12 100644 --- a/mozilla/js2/tests/cpp/js2_shell.cpp +++ b/mozilla/js2/tests/cpp/js2_shell.cpp @@ -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";