diff --git a/mozilla/js2/src/bytecodegen.cpp b/mozilla/js2/src/bytecodegen.cpp index 2073903c837..0bcb8169462 100644 --- a/mozilla/js2/src/bytecodegen.cpp +++ b/mozilla/js2/src/bytecodegen.cpp @@ -1389,11 +1389,13 @@ bool ByteCodeGen::genCodeForStatement(StmtNode *p, ByteCodeGen *static_cg, uint3 } break; + case StmtNode::Package: + case StmtNode::Import: case StmtNode::Namespace: { // do anything at bytecodegen? } - break; + break; default: NOT_REACHED("Not Implemented Yet"); } diff --git a/mozilla/js2/src/collector.cpp b/mozilla/js2/src/collector.cpp index 3220c20c179..b8951d60819 100644 --- a/mozilla/js2/src/collector.cpp +++ b/mozilla/js2/src/collector.cpp @@ -170,9 +170,9 @@ struct ConsCell { private: typedef Collector::InstanceOwner ConsCellOwner; - friend class ConsCellOwner; + friend class Collector::InstanceOwner; typedef Collector::ArrayOwner ConsCellArrayOwner; - friend class ConsCellArrayOwner; + friend class Collector::ArrayOwner; /** * Scans through the object, and copies all references. @@ -188,23 +188,29 @@ public: { static ConsCellOwner owner; return gc.allocateObject(n, &owner); - } - + } + + void operator delete(void* ptr, Collector& gc) {} + void* operator new[] (size_t n, Collector& gc) { static ConsCellArrayOwner owner; return gc.allocateObject(n, &owner); - } + } }; + +#if 0 struct ConsCellArray { ConsCell* cells; - ConsCellArray(size_t count, Collector& gc) : cells(new (gc) ConsCell[count]) {} + ConsCellArray(size_t count, Collector& gc) : cells(NULL) { + cells = new (gc) ConsCell[count]; + } private: typedef Collector::InstanceOwner ConsCellArrayOwner; - friend class ConsCellArrayOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. @@ -221,8 +227,12 @@ public: static ConsCellArrayOwner owner; return gc.allocateObject(n, &owner); } + + void operator delete(void* ptr, Collector& gc) {} }; - + +#endif + void testCollector() { Collector gc; diff --git a/mozilla/js2/src/collector.h b/mozilla/js2/src/collector.h index 2efbd528057..0cf2faeb066 100644 --- a/mozilla/js2/src/collector.h +++ b/mozilla/js2/src/collector.h @@ -124,7 +124,7 @@ namespace JavaScript enum { ARRAY_HEADER_SIZE = 4 }; enum { ARRAY_HEADER_COUNT = 0 }; #else - #warning "define me for your compiler." +// #warning "define me for your compiler." enum { ARRAY_HEADER_SIZE = 4 }; enum { ARRAY_HEADER_COUNT = 0 }; #endif diff --git a/mozilla/js2/src/js2runtime.cpp b/mozilla/js2/src/js2runtime.cpp index 07f64bcec4c..00c3a9962b0 100644 --- a/mozilla/js2/src/js2runtime.cpp +++ b/mozilla/js2/src/js2runtime.cpp @@ -79,7 +79,8 @@ JSType *Type_Type; JSType *Void_Type; JSType *Null_Type; JSType *Unit_Type; -JSType *Attribute_Type; +JSType *Attribute_Type; +JSType *Package_Type; JSType *NamedArgument_Type; JSArrayType *Array_Type; JSType *Date_Type; @@ -906,23 +907,12 @@ JSType *Context::getParameterType(FunctionDefinition &function, int index) return NULL; } -// counts the number of pigs that can fit in small wicker basket -uint32 Context::getParameterCount(FunctionDefinition &function) -{ - uint32 count = 0; - VariableBinding *v = function.parameters; - while (v) { - count++; - v = v->next; - } - return count; -} - // Iterates over the linked list of statements, p. -// 1. Adds 'symbol table' entries for each class, var & function +// 1. Adds 'symbol table' entries for each class, var & function by defining +// them in the object at the top of the scope chain // 2. Using information from pass 1, evaluate types (and XXX later XXX other -// compile-time constants) +// compile-time constants) to complete the definitions void Context::buildRuntime(StmtNode *p) { ContextStackReplacement csr(this); @@ -971,8 +961,25 @@ bool ScopeChain::isPossibleUncheckedFunction(FunctionDefinition &f) } } return result; +} + +/* + Build a name for the package from the identifier list +*/ +String ScopeChain::getPackageName(IdentifierList *packageIdList) +{ + String packagePath; + IdentifierList *idList = packageIdList; + while (idList) { + packagePath += idList->name; + idList = idList->next; + if (idList) + packagePath += '/'; // XXX how to get path separator for OS? + } + return packagePath; } +// counts the number of pigs that can fit in a small wicker basket void JSFunction::countParameters(Context *cx, FunctionDefinition &f) { uint32 requiredParameterCount = 0; @@ -1230,6 +1237,28 @@ void ScopeChain::collectNames(StmtNode *p) } } break; + case StmtNode::Import: + { + // if loaded already - just skip. + ImportStmtNode *i = checked_cast(p); + String packagePath; + if (i->packageIdList) { + packagePath = getPackageName(i->packageIdList); + if (!m_cx->checkForPackage(packagePath)) { + m_cx->loadPackage(packagePath, packagePath + ".js"); + + + + } + } + else { + packagePath = *i->packageString + ".js"; + if (!m_cx->checkForPackage(*i->packageString)) { + m_cx->loadPackage(*i->packageString, packagePath); + } + } + } + break; case StmtNode::Namespace: { NamespaceStmtNode *n = checked_cast(p); @@ -1237,6 +1266,21 @@ void ScopeChain::collectNames(StmtNode *p) x->mNamespaceList = new NamespaceList(n->name, x->mNamespaceList); m_cx->getGlobalObject()->defineVariable(m_cx, n->name, (NamespaceList *)(NULL), Property::NoAttribute, Attribute_Type, JSValue(x)); } + break; + case StmtNode::Package: + { + PackageStmtNode *ps = checked_cast(p); + String packageName = getPackageName(ps->packageIdList); + Package *package = new Package(packageName); + ps->scope = package; + m_cx->getGlobalObject()->defineVariable(m_cx, packageName, (NamespaceList *)(NULL), Property::NoAttribute, Package_Type, JSValue(package)); + m_cx->mPackages.push_back(package); + + addScope(ps->scope); + collectNames(ps->body); + popScope(); + package->mStatus = Package::InHand; + } break; default: break; @@ -1770,6 +1814,14 @@ void Context::buildRuntimeForStmt(StmtNode *p) { // do anything ? } + break; + case StmtNode::Package: + { + PackageStmtNode *ps = checked_cast(p); + mScopeChain->addScope(ps->scope); + buildRuntimeForStmt(ps->body); + mScopeChain->popScope(); + } break; default: break; @@ -2773,7 +2825,8 @@ void Context::initBuiltins() { "SyntaxError", SyntaxError_Constructor, &kNullValue }, { "TypeError", TypeError_Constructor, &kNullValue }, { "UriError", UriError_Constructor, &kNullValue }, - { "RegExp", RegExp_Constructor, &kNullValue }, + { "RegExp", RegExp_Constructor, &kNullValue }, + { "Package", NULL, &kNullValue }, }; Object_Type = new JSType(this, &mWorld.identifiers[widenCString(builtInClasses[0].name)], NULL); @@ -2829,6 +2882,7 @@ void Context::initBuiltins() // XXX RegExp.prototype is set to a RegExp instance, which isn't ECMA (it's supposed to be an Object instance) bu // is SpiderMonkey compatible. RegExp_Type = new JSType(this, &mWorld.identifiers[widenCString(builtInClasses[21].name)], Object_Type); + Package_Type = new JSType(this, &mWorld.identifiers[widenCString(builtInClasses[22].name)], Object_Type); @@ -3168,6 +3222,37 @@ Context::Context(JSObject **global, World &world, Arena &a, Pragma::Flags flags) getGlobalObject()->defineVariable(this, Infinity_StringAtom, (NamespaceList *)(NULL), Property::NoAttribute, Void_Type, kPositiveInfinity); } + +/* + See if the specified package is already loaded - return true + Throw an exception if the package is being loaded already +*/ +bool Context::checkForPackage(const String &packageName) +{ + // XXX linear search + for (PackageList::iterator pi = mPackages.begin(), end = mPackages.end(); (pi != end); pi++) { + if (PACKAGE_NAME(pi).compare(packageName) == 0) { + if (PACKAGE_STATUS(pi) == Package::OnItsWay) + reportError(Exception::referenceError, "Package circularity"); + else + return true; + } + } + return false; +} + +/* + Load the specified package +*/ +Package *Context::loadPackage(const String &packageName, const String &filename) +{ + // XXX need some rules for search path + + readEvalFile(filename); + + return NULL; + +} void Context::reportError(Exception::Kind kind, char *message, size_t pos, const char *arg) { diff --git a/mozilla/js2/src/js2runtime.h b/mozilla/js2/src/js2runtime.h index 1e19333e4de..672a5984508 100644 --- a/mozilla/js2/src/js2runtime.h +++ b/mozilla/js2/src/js2runtime.h @@ -39,7 +39,6 @@ #pragma warning(disable: 4786) #endif - #include #include #include @@ -116,7 +115,8 @@ static const double two31 = 2147483648.0; extern JSType *Unit_Type; extern JSType *Function_Type; - extern JSType *Attribute_Type; // used to define 'prototype' 'static' etc & Namespace values + extern JSType *Attribute_Type; // used to define 'prototype' 'static' etc & Namespace values + extern JSType *Package_Type; extern JSType *NamedArgument_Type; extern JSType *Date_Type; @@ -222,7 +222,7 @@ static const double two31 = 2147483648.0; int operator==(const JSValue& value) const; - /** + /** * Scans through the object, and copies all references. */ Collector::size_type scan(Collector* collector) @@ -241,7 +241,7 @@ static const double two31 = 2147483648.0; static Collector::InstanceOwner owner; return gc.allocateObject(n, &owner); } - + #ifdef DEBUG void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSValue", s, t); return t; } void operator delete(void* t) { trace_release("JSValue", t); STD::free(t); } @@ -629,9 +629,9 @@ XXX ...couldn't get this to work... } } - protected: - typedef Collector::InstanceOwner JSObjectOwner; - friend class JSObjectOwner; + protected: + typedef Collector::InstanceOwner JSObjectOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. */ @@ -651,8 +651,9 @@ XXX ...couldn't get this to work... static JSObjectOwner owner; return gc.allocateObject(n, &owner); } - + #ifdef DEBUG + public: void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSObject", s, t); return t; } void operator delete(void* t) { trace_release("JSObject", t); STD::free(t); } #endif @@ -705,7 +706,7 @@ XXX ...couldn't get this to work... protected: typedef Collector::InstanceOwner JSInstanceOwner; - friend class JSInstanceOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. */ @@ -725,8 +726,9 @@ XXX ...couldn't get this to work... static JSInstanceOwner owner; return gc.allocateObject(n, &owner); } - + #ifdef DEBUG + public: void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSInstance", s, t); return t; } void operator delete(void* t) { trace_release("JSInstance", t); STD::free(t); } #endif @@ -856,7 +858,7 @@ XXX ...couldn't get this to work... protected: typedef Collector::InstanceOwner JSTypeOwner; - friend class JSTypeOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. */ @@ -877,7 +879,7 @@ XXX ...couldn't get this to work... mPrototypeObject = (JSObject*) collector->copy(mPrototypeObject); return sizeof(JSType); } - + public: void* operator new(size_t n, Collector& gc) { @@ -886,6 +888,7 @@ XXX ...couldn't get this to work... } #ifdef DEBUG + public: void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSType", s, t); return t; } void operator delete(void* t) { trace_release("JSType", t); STD::free(t); } #endif @@ -993,8 +996,7 @@ XXX ...couldn't get this to work... }; - - + @@ -1086,8 +1088,6 @@ XXX ...couldn't get this to work... }; - - class ScopeChain { public: @@ -1282,7 +1282,9 @@ XXX ...couldn't get this to work... // Get a type from an ExprNode JSType *extractType(ExprNode *t); - + + // concoct a package name from an id list + String ScopeChain::getPackageName(IdentifierList *packageIdList); }; @@ -1403,7 +1405,7 @@ XXX ...couldn't get this to work... protected: typedef Collector::InstanceOwner JSFunctionOwner; - friend class JSFunctionOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. */ @@ -1425,6 +1427,7 @@ XXX ...couldn't get this to work... } #ifdef DEBUG + public: void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSFunction", s, t); return t; } void operator delete(void* t) { trace_release("JSFunction", t); STD::free(t); } #endif @@ -1495,7 +1498,7 @@ XXX ...couldn't get this to work... protected: typedef Collector::InstanceOwner JBoundFunctionOwner; - friend class JBoundFunctionOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. */ @@ -1515,6 +1518,7 @@ XXX ...couldn't get this to work... } #ifdef DEBUG + public: void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("JSBoundFunction", s, t); return t; } void operator delete(void* t) { trace_release("JSBoundFunction", t); STD::free(t); } #endif @@ -1566,7 +1570,22 @@ XXX ...couldn't get this to work... // called directly by String.match extern JSValue RegExp_exec(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc); - class Attribute; + class Attribute; + + class Package : public JSObject { + public: + typedef enum { OnItsWay, InHand } PackageStatus; + + Package(const String &name) : mName(name), mStatus(OnItsWay) { } + + String mName; + PackageStatus mStatus; + }; + + typedef std::vector PackageList; + +#define PACKAGE_NAME(pi) ((*pi)->mName) +#define PACKAGE_STATUS(pi) ((*pi)->mStatus) class Context { public: @@ -1801,10 +1820,10 @@ XXX ...couldn't get this to work... OperatorList mOperatorTable[OperatorCount]; - typedef String PackageName; - typedef std::vector PackageList; PackageList mPackages; // the currently loaded packages, mPackages.back() is the current package + bool checkForPackage(const String &packageName); // return true if loaded, throw exception if loading + Package *loadPackage(const String &packageName, const String &filename); // load package from file JSValue readEvalFile(const String& fileName); JSValue readEvalString(const String &str, const String& fileName, ScopeChain *scopeChain, const JSValue& thisValue); @@ -1833,8 +1852,6 @@ XXX ...couldn't get this to work... // Get the type of the nth parameter. JSType *getParameterType(FunctionDefinition &function, int index); - // Get the number of parameters. - uint32 getParameterCount(FunctionDefinition &function); Reader *mReader; @@ -1892,7 +1909,7 @@ XXX ...couldn't get this to work... protected: typedef Collector::InstanceOwner NamedArgumentOwner; - friend class NamedArgumentOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. */ @@ -1911,6 +1928,7 @@ XXX ...couldn't get this to work... } #ifdef DEBUG + public: void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("NamedArgument", s, t); return t; } void operator delete(void* t) { trace_release("NamedArgument", t); STD::free(t); } #endif @@ -1930,7 +1948,7 @@ XXX ...couldn't get this to work... protected: typedef Collector::InstanceOwner AttributeOwner; - friend class AttributeOwner; + friend class Collector::InstanceOwner; /** * Scans through the object, and copies all references. */ @@ -1949,6 +1967,7 @@ XXX ...couldn't get this to work... } #ifdef DEBUG + public: void* operator new(size_t s) { void *t = STD::malloc(s); trace_alloc("Attribute", s, t); return t; } void operator delete(void* t) { trace_release("Attribute", t); STD::free(t); } #endif diff --git a/mozilla/js2/src/parser.h b/mozilla/js2/src/parser.h index e06ae5ea436..190ad63c9b6 100644 --- a/mozilla/js2/src/parser.h +++ b/mozilla/js2/src/parser.h @@ -716,6 +716,8 @@ namespace JavaScript { IdentifierList *packageIdList; // The package name as a list of identifiers; may be nil BlockStmtNode *body; // The package's body; non-nil only + JS2Runtime::JSObject *scope; // the sematics/codegen passes stuff their data in here. + PackageStmtNode(size_t pos, IdentifierList *packageIdList, BlockStmtNode *body): StmtNode(pos, Package), packageIdList(packageIdList), body(body) {ASSERT(body);} diff --git a/mozilla/js2/src/winbuild/dikdik.dsp b/mozilla/js2/src/winbuild/dikdik.dsp index 1e2504d77ed..7f7daeeffa1 100644 --- a/mozilla/js2/src/winbuild/dikdik.dsp +++ b/mozilla/js2/src/winbuild/dikdik.dsp @@ -8,12 +8,12 @@ CFG=DikDik - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE -!MESSAGE NMAKE /f "DikDik.mak". +!MESSAGE NMAKE /f "dikdik.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "DikDik.mak" CFG="DikDik - Win32 Debug" +!MESSAGE NMAKE /f "dikdik.mak" CFG="DikDik - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE diff --git a/mozilla/js2/tests/cpp/DikDik_Shell.cpp b/mozilla/js2/tests/cpp/DikDik_Shell.cpp index 6979279ce12..669beb5d841 100644 --- a/mozilla/js2/tests/cpp/DikDik_Shell.cpp +++ b/mozilla/js2/tests/cpp/DikDik_Shell.cpp @@ -265,8 +265,8 @@ int main(int argc, char **argv) stdOut << "Welcome to DikDik.\n"; #endif -#if DEBUG - testCollector(); +#if DEBUG + testCollector(); #endif try {