diff --git a/mozilla/js2/src/bytecodecontainer.h b/mozilla/js2/src/bytecodecontainer.h index 672f7ea2cf8..b045c237771 100644 --- a/mozilla/js2/src/bytecodecontainer.h +++ b/mozilla/js2/src/bytecodecontainer.h @@ -153,8 +153,8 @@ public: // Maintain list of associated pointers, so as to keep the objects safe across gc's - void addMultiname(Multiname *mn) { mMultinameList.push_back(mn); addShort((uint16)(mMultinameList.size() - 1)); } - void saveMultiname(Multiname *mn) { mMultinameList.push_back(mn); } +// void addMultiname(uint16 index) { addShort(index); } + uint16 saveMultiname(Multiname *mn) { mMultinameList.push_back(mn); return (uint16)(mMultinameList.size() - 1); } void addFrame(Frame *f); void saveFrame(Frame *f); diff --git a/mozilla/js2/src/js2engine.cpp b/mozilla/js2/src/js2engine.cpp index 4dfbd8a8d1d..e57a118bd79 100644 --- a/mozilla/js2/src/js2engine.cpp +++ b/mozilla/js2/src/js2engine.cpp @@ -155,6 +155,8 @@ namespace MetaData { localFrame = activationStackTop->localFrame; parameterFrame = activationStackTop->parameterFrame; parameterSlots = activationStackTop->parameterSlots; + if (parameterFrame) + parameterFrame->argSlots = parameterSlots; bCon = activationStackTop->bCon; if (hndlr->mActivation != curAct) { while (activationStackTop->newEnv->getTopFrame() != activationStackTop->topFrame) @@ -169,6 +171,8 @@ namespace MetaData { localFrame = activationStackTop->localFrame; parameterFrame = activationStackTop->parameterFrame; parameterSlots = activationStackTop->parameterSlots; + if (parameterFrame) + parameterFrame->argSlots = parameterSlots; bCon = activationStackTop->bCon; meta->env = activationStackTop->env; } @@ -1046,7 +1050,9 @@ namespace MetaData { activationStackTop->localFrame = localFrame; activationStackTop->parameterFrame = parameterFrame; activationStackTop->parameterSlots = parameterSlots; -// if (pFrame && pFrame->) + activationStackTop->parameterCount = parameterCount; + activationStackTop->superConstructorCalled = superConstructorCalled; + activationStackTop->thisVal = thisVal; activationStackTop++; if (new_bCon) { bCon = new_bCon; @@ -1078,6 +1084,15 @@ namespace MetaData { localFrame = activationStackTop->localFrame; parameterFrame = activationStackTop->parameterFrame; parameterSlots = activationStackTop->parameterSlots; + parameterCount = activationStackTop->parameterCount; + superConstructorCalled = activationStackTop->superConstructorCalled; + thisVal = activationStackTop->thisVal; + if (parameterFrame) { + parameterFrame->argSlots = parameterSlots; + parameterFrame->argCount = parameterCount; + parameterFrame->superConstructorCalled = superConstructorCalled; + parameterFrame->thisObject = thisVal; + } // reset the env. top while (activationStackTop->newEnv->getTopFrame() != activationStackTop->topFrame) activationStackTop->newEnv->removeTopFrame(); @@ -1114,8 +1129,8 @@ namespace MetaData { JS2Object::mark(float64Table[i]); } if (parameterSlots) { - for (i = 0; i < parameterSlots->size(); i++) { - GCMARKVALUE((*parameterSlots)[i]); + for (i = 0; i < parameterFrame->frameSlots->size(); i++) { + GCMARKVALUE(parameterSlots[i]); } } GCMARKVALUE(retval); diff --git a/mozilla/js2/src/js2engine.h b/mozilla/js2/src/js2engine.h index df78d20fa1a..6b187d648a0 100644 --- a/mozilla/js2/src/js2engine.h +++ b/mozilla/js2/src/js2engine.h @@ -312,7 +312,8 @@ public: Frame *topFrame; NonWithFrame *localFrame; ParameterFrame *parameterFrame; - ValueList *parameterSlots; + js2val *parameterSlots; + uint32 parameterCount; }; void jsr(Phase execPhase, BytecodeContainer *bCon, uint32 stackBase, js2val returnVal, Environment *env); bool activationStackEmpty() { return (activationStackTop == activationStack); } @@ -363,9 +364,13 @@ public: // For frame slot references: NonWithFrame *packageFrame; - ParameterFrame *parameterFrame; NonWithFrame *localFrame; - ValueList *parameterSlots; + + ParameterFrame *parameterFrame; + js2val *parameterSlots; // just local copies of paramterFrame->argSlots + uint32 parameterCount; // ... and parameterFrame->argCount + bool superConstructorCalled; + js2val thisVal; void pushHandler(uint8 *pc); void popHandler(); diff --git a/mozilla/js2/src/js2eval.cpp b/mozilla/js2/src/js2eval.cpp index c95c5d075cf..efc792d0c93 100644 --- a/mozilla/js2/src/js2eval.cpp +++ b/mozilla/js2/src/js2eval.cpp @@ -259,7 +259,7 @@ namespace MetaData { CompilationData *oldData = startCompilationUnit(NULL, bCon->mSource, bCon->mSourceLocation); try { - LexicalReference rVal(new (this) Multiname(world.identifiers[widenCString(fname)]), false); + LexicalReference rVal(new (this) Multiname(world.identifiers[widenCString(fname)]), false, bCon); rVal.emitReadForInvokeBytecode(bCon, 0); bCon->emitOp(eCall, 0, -(0 + 2) + 1); // pop argCount args, the base & function, and push a result bCon->addShort(0); @@ -319,24 +319,29 @@ namespace MetaData { uint8 *savePC = NULL; BytecodeContainer *bCon = fWrap->bCon; + // XXX why construct a new bCon at this point, why not just save off the old one (that's necessary + // because we may be in the process of generating into it) and restore it below like everything else? CompilationData *oldData = startCompilationUnit(bCon, bCon->mSource, bCon->mSourceLocation); DEFINE_ROOTKEEPER(this, rk, runtimeFrame); if (runtimeFrame == NULL) runtimeFrame = new (this) ParameterFrame(fWrap->compileFrame); runtimeFrame->instantiate(fWrap->env); runtimeFrame->thisObject = thisValue; - runtimeFrame->assignArguments(this, fnObj, argv, argc, argc); + uint32 newSlotsCount = 0; + js2val *newSlots = runtimeFrame->assignArguments(this, fnObj, argv, argc, newSlotsCount); Frame *oldTopFrame = fWrap->env->getTopFrame(); if (fInst->isMethodClosure) fWrap->env->addFrame(objectType(thisValue)); fWrap->env->addFrame(runtimeFrame); ParameterFrame *oldPFrame = engine->parameterFrame; - ValueList *oldPSlots = engine->parameterSlots; + js2val *oldPSlots = engine->parameterSlots; + uint32 oldPCount = engine->parameterCount; try { savePC = engine->pc; engine->pc = NULL; engine->parameterFrame = runtimeFrame; - engine->parameterSlots = runtimeFrame->frameSlots; + engine->parameterSlots = newSlots; + engine->parameterCount = newSlotsCount; result = engine->interpret(RunPhase, bCon, fWrap->env); } catch (Exception &x) { @@ -345,6 +350,8 @@ namespace MetaData { fWrap->env->setTopFrame(oldTopFrame); engine->parameterFrame = oldPFrame; engine->parameterSlots = oldPSlots; + if (engine->parameterFrame) + engine->parameterFrame->argSlots = engine->parameterSlots; throw x; } engine->pc = savePC; @@ -352,13 +359,15 @@ namespace MetaData { fWrap->env->setTopFrame(oldTopFrame); engine->parameterFrame = oldPFrame; engine->parameterSlots = oldPSlots; + if (engine->parameterFrame) + engine->parameterFrame->argSlots = engine->parameterSlots; } } return result; } // Save off info about the current compilation and begin a - // new one - using the given parser. + // new one - using the given source information. CompilationData *JS2Metadata::startCompilationUnit(BytecodeContainer *newBCon, const String &source, const String &sourceLocation) { CompilationData *result = new CompilationData(); @@ -860,11 +869,11 @@ namespace MetaData { if ((multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace) && isValidIndex(multiname->name, index) - && (index < args->mSlots->size())) { + && (index < args->count)) { if (args->mSplit[index]) - *rval = (*args->mSplitValue)[index]; + *rval = args->mSplitValue[index]; else - *rval = (*args->mSlots)[index]; + *rval = args->mSlots[index]; return true; } else @@ -881,11 +890,11 @@ namespace MetaData { if ((multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace) && isValidIndex(multiname->name, index) - && (index < args->mSlots->size())) { + && (index < args->count)) { if (args->mSplit[index]) - (*args->mSplitValue)[index] = newValue; + args->mSplitValue[index] = newValue; else - (*args->mSlots)[index] = newValue; + args->mSlots[index] = newValue; return true; } else @@ -902,11 +911,11 @@ namespace MetaData { if ((multiname->nsList->size() == 1) && (multiname->nsList->back() == meta->publicNamespace) && isValidIndex(multiname->name, index) - && (index < args->mSlots->size())) { + && (index < args->count)) { if (!args->mSplitValue) - args->mSplitValue = new std::vector(slotCount); + args->mSplitValue = new js2val[slotCount]; args->mSplit[index] = true; - (*args->mSplitValue)[index] = JS2VAL_VOID; + args->mSplitValue[index] = JS2VAL_VOID; return true; } else diff --git a/mozilla/js2/src/js2metadata.cpp b/mozilla/js2/src/js2metadata.cpp index 4b2fb477c37..5f708314c7d 100644 --- a/mozilla/js2/src/js2metadata.cpp +++ b/mozilla/js2/src/js2metadata.cpp @@ -1005,7 +1005,7 @@ namespace MetaData { if (f->initializer->getKind() == StmtNode::Var) { VariableStmtNode *vs = checked_cast(f->initializer); VariableBinding *vb = vs->bindings; - v = new (*referenceArena) LexicalReference(new (this) Multiname(*vb->name), cxt.strict); + v = new (*referenceArena) LexicalReference(new (this) Multiname(*vb->name), cxt.strict, bCon); referenceArena->registerDestructor(v); } else { @@ -1301,7 +1301,7 @@ namespace MetaData { } // write the exception object (on stack top) into the named // local variable - Reference *r = new (*referenceArena) LexicalReference(new (this) Multiname(c->name), false); + Reference *r = new (*referenceArena) LexicalReference(new (this) Multiname(c->name), false, bCon); referenceArena->registerDestructor(r); r->emitWriteBytecode(bCon, p->pos); bCon->emitOp(ePop, p->pos); @@ -1400,7 +1400,7 @@ namespace MetaData { throw x; Reference *r = SetupExprNode(env, phase, vb->initializer, &exprType); if (r) r->emitReadBytecode(bCon, p->pos); - LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict); + LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict, bCon); referenceArena->registerDestructor(lVal); lVal->emitWriteBytecode(bCon, p->pos); bCon->emitOp(ePop, p->pos); @@ -1419,13 +1419,13 @@ namespace MetaData { if (r) r->emitReadBytecode(bCon, p->pos); bCon->emitOp(eCoerce, p->pos); bCon->addType(v->type); - LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict); + LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict, bCon); referenceArena->registerDestructor(lVal); lVal->emitInitBytecode(bCon, p->pos); } else { v->type->emitDefaultValue(bCon, p->pos); - LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict); + LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(vb->mn), cxt.strict, bCon); referenceArena->registerDestructor(lVal); lVal->emitInitBytecode(bCon, p->pos); } @@ -1470,7 +1470,7 @@ namespace MetaData { if (vb->initializer) { Reference *r = SetupExprNode(env, phase, vb->initializer, &exprType); if (r) r->emitReadBytecode(bCon, p->pos); - LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(*vb->name), cxt.strict); + LexicalReference *lVal = new (*referenceArena) LexicalReference(new (this) Multiname(*vb->name), cxt.strict, bCon); referenceArena->registerDestructor(lVal); lVal->variableMultiname->addNamespace(publicNamespace); lVal->emitInitBytecode(bCon, p->pos); @@ -2407,7 +2407,7 @@ doUnary: reportError(Exception::badValueError, "Namespace expected in qualifier", p->pos); Namespace *ns = checked_cast(obj); - returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(name, ns), cxt.strict); + returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(name, ns), cxt.strict, bCon); referenceArena->registerDestructor(returnRef); } break; @@ -2433,7 +2433,7 @@ doUnary: fi++; } } - returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(i->name), cxt.strict); + returnRef = new (*referenceArena) LexicalReference(new (this) Multiname(i->name), cxt.strict, bCon); referenceArena->registerDestructor(returnRef); ((LexicalReference *)returnRef)->variableMultiname->addNamespace(cxt); // Try to find this identifier at compile time, we have to stop if we reach @@ -2470,7 +2470,7 @@ doUnary: break; } } - keepLooking = false; + keepLooking = false; // don't look beneath the current function, as the slot base pointers aren't relevant } break; case BlockFrameKind: @@ -2644,7 +2644,7 @@ doUnary: } if (returnRef == NULL) { - returnRef = new (*referenceArena) DotReference(new (this) Multiname(i->name)); + returnRef = new (*referenceArena) DotReference(new (this) Multiname(i->name), bCon); referenceArena->registerDestructor(returnRef); checked_cast(returnRef)->propertyMultiname->addNamespace(cxt); } @@ -2653,7 +2653,7 @@ doUnary: if (b->op2->getKind() == ExprNode::qualify) { Reference *rVal = SetupExprNode(env, phase, b->op2, exprType); ASSERT(rVal && checked_cast(rVal)); - returnRef = new (*referenceArena) DotReference(((LexicalReference *)rVal)->variableMultiname); + returnRef = new (*referenceArena) DotReference(((LexicalReference *)rVal)->variableMultiname, bCon); referenceArena->registerDestructor(returnRef); checked_cast(returnRef)->propertyMultiname->addNamespace(cxt); } @@ -3144,7 +3144,8 @@ doUnary: { FrameListIterator fi = getBegin(), end = getEnd(); while (fi != end) { - GCMARKOBJECT(fi->first) + GCMARKOBJECT(fi->first); + GCMARKVALUE(fi->second); fi++; } } @@ -4498,7 +4499,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... case FrameVariable::Parameter: { ASSERT(container->kind == ParameterFrameKind); - *rval = (*(checked_cast(container))->frameSlots)[fv->frameSlot]; + ASSERT(fv->frameSlot < (checked_cast(container))->frameSlots->size()); + *rval = (checked_cast(container))->argSlots[fv->frameSlot]; +// *rval = (*(checked_cast(container))->frameSlots)[fv->frameSlot]; } break; } @@ -4569,7 +4572,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... case FrameVariable::Parameter: { ASSERT(container->kind == ParameterFrameKind); - (*(checked_cast(container))->frameSlots)[fv->frameSlot] = newValue; + ASSERT(fv->frameSlot < (checked_cast(container))->frameSlots->size()); + (checked_cast(container))->argSlots[fv->frameSlot] = newValue; +// (*(checked_cast(container))->frameSlots)[fv->frameSlot] = newValue; } break; } @@ -4600,18 +4605,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... return (findCommonMember(&val, mn, ReadWriteAccess, true) != NULL); } - DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const char *name, js2val initVal, Access access, bool sealed, bool enumerable) - { - return createDynamicProperty(obj, world.identifiers[widenCString(name)], initVal, access, sealed, enumerable); - } -/* - DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const String *name, js2val initVal, Access access, bool sealed, bool enumerable) - { - DEFINE_ROOTKEEPER(this, rk, name); - QualifiedName qName(publicNamespace, name); - return createDynamicProperty(obj, &qName, initVal, access, sealed, enumerable); - } -*/ + // Add the local member with access etc. by name into the map, using the public namespace. An entry may or may not be in the map already void JS2Metadata::addPublicVariableToLocalMap(LocalBindingMap *lMap, const StringAtom &name, LocalMember *v, Access access, bool enumerable) { LocalBinding *new_b = new LocalBinding(access, v, enumerable); @@ -4639,20 +4633,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... else ASSERT(false); addPublicVariableToLocalMap(lMap, name, dv, access, enumerable); -/* - LocalBindingEntry **lbeP = (*lMap)[*qName->name]; - LocalBindingEntry *lbe; - if (lbeP == NULL) { - lbe = new LocalBindingEntry(*qName->name); - lMap->insert(*qName->name, lbe); - } - else - lbe = *lbeP; - lbe->bindingList.push_back(LocalBindingEntry::NamespaceBinding(qName->nameSpace, new_b)); -*/ return dv; } + // char * version of above (XXX inline?) + DynamicVariable *JS2Metadata::createDynamicProperty(JS2Object *obj, const char *name, js2val initVal, Access access, bool sealed, bool enumerable) + { + return createDynamicProperty(obj, world.identifiers[widenCString(name)], initVal, access, sealed, enumerable); + } + // Use the slotIndex from the instanceVariable to access the slot Slot *JS2Metadata::findSlot(js2val thisObjVal, InstanceVariable *id) { @@ -5162,12 +5151,12 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... { SimpleInstance::markChildren(); if (mSlots) { - for (uint32 i = 0; i < mSlots->size(); i++) - GCMARKVALUE((*mSlots)[i]); + for (uint32 i = 0; i < count; i++) + GCMARKVALUE(mSlots[i]); } if (mSplitValue) { - for (uint32 i = 0; i < mSlots->size(); i++) - GCMARKVALUE((*mSplitValue)[i]); + for (uint32 i = 0; i < count; i++) + GCMARKVALUE(mSplitValue[i]); } } @@ -5280,32 +5269,31 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... // the cloned Variables assigned into this (singular) frame. Use the // incoming values to initialize the positionals. // Pad out to 'length' args with undefined values if argCount is insufficient - void ParameterFrame::assignArguments(JS2Metadata *meta, JS2Object *fnObj, js2val *argBase, uint32 argCount, uint32 length) + js2val *ParameterFrame::assignArguments(JS2Metadata *meta, JS2Object *fnObj, js2val *argBase, uint32 argCount, uint32 &argsLength) { uint32 i; - ASSERT(pluralFrame->kind == ParameterFrameKind); - ParameterFrame *plural = checked_cast(pluralFrame); ArgumentsInstance *argsObj = NULL; DEFINE_ROOTKEEPER(meta, rk2, argsObj); // slotCount is the number of slots required by the parameter frame - uint32 slotCount = (plural->frameSlots) ? plural->frameSlots->size() : 0; + uint32 slotCount = (frameSlots) ? frameSlots->size() : 0; ASSERT(length == slotCount); - if (plural->buildArguments) { + if (buildArguments) { // If we're building an arguments object, the slots for the parameter frame are located // there so that the arguments object itself can survive beyond the life of the function. argsObj = new (meta) ArgumentsInstance(meta, meta->objectClass->prototype, meta->argumentsClass); if (argCount > slotCount) slotCount = argCount; if (slotCount) { - argsObj->mSlots = new std::vector(slotCount); + argsObj->mSlots = new js2val[slotCount]; + argsObj->count = slotCount; argsObj->mSplit = new bool[slotCount]; for (i = 0; (i < slotCount); i++) argsObj->mSplit[i] = false; } - frameSlots = argsObj->mSlots; + argSlots = argsObj->mSlots; // Add the 'arguments' property const StringAtom &name = meta->world.identifiers["arguments"]; ASSERT(localBindings[name] == NULL); @@ -5318,21 +5306,23 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... if (argCount > slotCount) slotCount = argCount; if (slotCount) - frameSlots = new std::vector(slotCount); + argSlots = new js2val[slotCount]; } + argsLength = slotCount; for (i = 0; (i < argCount); i++) { if (i < slotCount) { - (*frameSlots)[i] = argBase[i]; + argSlots[i] = argBase[i]; } } for ( ; (i < slotCount); i++) { - (*frameSlots)[i] = JS2VAL_UNDEFINED; + argSlots[i] = JS2VAL_UNDEFINED; } - if (plural->buildArguments) { + if (buildArguments) { setLength(meta, argsObj, argCount); meta->argumentsClass->WritePublic(meta, OBJECT_TO_JS2VAL(argsObj), meta->world.identifiers["callee"], true, OBJECT_TO_JS2VAL(fnObj)); } + return argSlots; } @@ -5481,9 +5471,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... p->resetMark(); // might have lingering mark from previous gc p->clearFlags(); p->setFlag(flag); -#ifdef DEBUG +//#ifdef DEBUG memset((p + 1), 0xB7, p->getSize() - sizeof(PondScum)); -#endif +//#endif return (p + 1); } pre = p; @@ -5501,9 +5491,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... } // there was room, so acquire it PondScum *p = (PondScum *)pondTop; -#ifdef DEBUG +//#ifdef DEBUG memset(p, 0xB7, sz); -#endif +//#endif p->owner = this; p->setSize(sz); p->setFlag(flag); @@ -5517,9 +5507,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now... { p->owner = (Pond *)freeHeader; uint8 *t = (uint8 *)(p + 1); -#ifdef DEBUG +//#ifdef DEBUG memset(t, 0xB3, p->getSize() - sizeof(PondScum)); -#endif +//#endif freeHeader = p; return p->getSize() - sizeof(PondScum); } diff --git a/mozilla/js2/src/js2metadata.h b/mozilla/js2/src/js2metadata.h index 850997fb55a..cb339201e04 100644 --- a/mozilla/js2/src/js2metadata.h +++ b/mozilla/js2/src/js2metadata.h @@ -715,7 +715,7 @@ public: // a list of two or more frames. Each frame corresponds to a scope. More specific frames are listed first // -each frame's scope is directly contained in the following frame's scope. The last frame is always the // SYSTEMFRAME. The next-to-last frame is always a PACKAGE or GLOBAL frame. -typedef std::deque > FrameList; +typedef std::deque FrameList; typedef FrameList::iterator FrameListIterator; // Deriving from JS2Object for gc sake only @@ -723,8 +723,8 @@ class Environment : public JS2Object { public: Environment(SystemFrame *systemFrame, Frame *nextToLast) : JS2Object(EnvironmentKind) { - frameList.push_back(std::pair(nextToLast, JS2VAL_VOID)); - frameList.push_back(std::pair(systemFrame, JS2VAL_VOID)); + frameList.push_back(nextToLast); + frameList.push_back(systemFrame); } virtual ~Environment() { } @@ -734,16 +734,15 @@ public: ParameterFrame *Environment::getEnclosingParameterFrame(js2val *thisP); FrameListIterator getRegionalFrame(); FrameListIterator getRegionalEnvironment(); - Frame *getTopFrame() { return frameList.front().first; } + Frame *getTopFrame() { return frameList.front(); } FrameListIterator getBegin() { return frameList.begin(); } FrameListIterator getEnd() { return frameList.end(); } Package *getPackageFrame(); - SystemFrame *getSystemFrame() { return checked_cast(frameList.back().first); } + SystemFrame *getSystemFrame() { return checked_cast(frameList.back()); } - void setTopFrame(Frame *f) { while (frameList.front().first != f) frameList.pop_front(); } + void setTopFrame(Frame *f) { while (frameList.front() != f) frameList.pop_front(); } - void addFrame(Frame *f) { frameList.push_front(std::pair(f, JS2VAL_VOID)); } - void addFrame(Frame *f, js2val x) { frameList.push_front(std::pair(f, x)); } + void addFrame(Frame *f) { frameList.push_front(f); } void removeTopFrame() { frameList.pop_front(); } js2val readImplicitThis(JS2Metadata *meta); @@ -1069,11 +1068,12 @@ public: class ArgumentsInstance : public SimpleInstance { public: ArgumentsInstance(JS2Metadata *meta, js2val parent, JS2Class *type) - : SimpleInstance(meta, parent, type), mSlots(NULL), mSplit(NULL), mSplitValue(NULL) { } + : SimpleInstance(meta, parent, type), mSlots(NULL), count(0), mSplit(NULL), mSplitValue(NULL) { } - ValueList *mSlots; + js2val *mSlots; + uint32 count; bool *mSplit; - ValueList *mSplitValue; + js2val *mSplitValue; virtual void markChildren(); virtual ~ArgumentsInstance(); @@ -1136,7 +1136,8 @@ class LexicalReference : public Reference { // of a given set of qualified names. LEXICALREFERENCE tuples arise from evaluating identifiers a and qualified identifiers // q::a. public: - LexicalReference(Multiname *mname, bool strict) : variableMultiname(mname), env(NULL), strict(strict) { } + LexicalReference(Multiname *mname, bool strict, BytecodeContainer *bCon) + : variableMultiname(mname), env(NULL), strict(strict), mn_index(bCon->saveMultiname(mname)) { } // LexicalReference(const String *name, bool strict) : variableMultiname(name), env(NULL), strict(strict) { } // LexicalReference(const String *name, Namespace *nameSpace, bool strict) : variableMultiname(name, nameSpace), env(NULL), strict(strict) { } virtual ~LexicalReference() { } @@ -1144,21 +1145,23 @@ public: Multiname *variableMultiname; // A nonempty set of qualified names to which this reference can refer Environment *env; // The environment in which the reference was created. bool strict; // The strict setting from the context in effect at the point where the reference was created + + uint16 mn_index; - void emitInitBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalInit, pos); bCon->addMultiname(variableMultiname); } + void emitInitBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalInit, pos); bCon->addShort(mn_index); } - virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRead, pos); bCon->addMultiname(variableMultiname); } - virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalWrite, pos); bCon->addMultiname(variableMultiname); } - virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRef, pos); bCon->addMultiname(variableMultiname); } + virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRead, pos); bCon->addShort(mn_index); } + virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalWrite, pos); bCon->addShort(mn_index); } + virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalRef, pos); bCon->addShort(mn_index); } virtual void emitReadForWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitReadBytecode(bCon, pos); } virtual void emitWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitWriteBytecode(bCon, pos); } - virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostInc, pos); bCon->addMultiname(variableMultiname); } - virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostDec, pos); bCon->addMultiname(variableMultiname); } - virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreInc, pos); bCon->addMultiname(variableMultiname); } - virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreDec, pos); bCon->addMultiname(variableMultiname); } + virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostInc, pos); bCon->addShort(mn_index); } + virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPostDec, pos); bCon->addShort(mn_index); } + virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreInc, pos); bCon->addShort(mn_index); } + virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreDec, pos); bCon->addShort(mn_index); } - virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalDelete, pos); bCon->addMultiname(variableMultiname); } + virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalDelete, pos); bCon->addShort(mn_index); } virtual int hasStackEffect() { return 0; } }; @@ -1169,7 +1172,7 @@ class DotReference : public Reference { // a.q::b. public: // DotReference(const String *name) : propertyMultiname(name) { } - DotReference(Multiname *mn) : propertyMultiname(mn) { } + DotReference(Multiname *mn, BytecodeContainer *bCon) : propertyMultiname(mn), mn_index(bCon->saveMultiname(propertyMultiname)) { } virtual ~DotReference() { } // In this implementation, the base is established by the execution of the preceding expression and @@ -1178,21 +1181,24 @@ public: // object may be a LIMITEDINSTANCE if a is a super expression, in which case // the property lookup will be restricted to members defined in proper ancestors // of base.limit. - Multiname *propertyMultiname; // A nonempty set of qualified names to which this reference can refer (b + Multiname *propertyMultiname; // A nonempty set of qualified names to which this reference can refer (b // qualified with the namespace q or all currently open namespaces in the // example above) - virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRead, pos); bCon->addMultiname(propertyMultiname); } - virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotWrite, pos); bCon->addMultiname(propertyMultiname); } - virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRef, pos); bCon->addMultiname(propertyMultiname); } + uint16 mn_index; + + + virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRead, pos); bCon->addShort(mn_index); } + virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotWrite, pos); bCon->addShort(mn_index); } + virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotRef, pos); bCon->addShort(mn_index); } virtual void emitReadForWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitReadForInvokeBytecode(bCon, pos); } virtual void emitWriteBackBytecode(BytecodeContainer *bCon, size_t pos) { emitWriteBytecode(bCon, pos); } - virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostInc, pos); bCon->addMultiname(propertyMultiname); } - virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostDec, pos); bCon->addMultiname(propertyMultiname); } - virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreInc, pos); bCon->addMultiname(propertyMultiname); } - virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreDec, pos); bCon->addMultiname(propertyMultiname); } + virtual void emitPostIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostInc, pos); bCon->addShort(mn_index); } + virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPostDec, pos); bCon->addShort(mn_index); } + virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreInc, pos); bCon->addShort(mn_index); } + virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreDec, pos); bCon->addShort(mn_index); } - virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotDelete, pos); bCon->addMultiname(propertyMultiname); } + virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotDelete, pos); bCon->addShort(mn_index); } virtual int hasStackEffect() { return 1; } }; @@ -1343,8 +1349,10 @@ public: isConstructor(false), isInstance(false), callsSuperConstructor(false), - superConstructorCalled(true) - { } + superConstructorCalled(true), + argSlots(NULL) + { } +/* ParameterFrame(ParameterFrame *pluralFrame) : NonWithFrame(ParameterFrameKind, pluralFrame), thisObject(JS2VAL_UNDEFINED), @@ -1353,9 +1361,11 @@ public: isConstructor(pluralFrame->isConstructor), isInstance(pluralFrame->isInstance), callsSuperConstructor(pluralFrame->callsSuperConstructor), - superConstructorCalled(false) // initialized to false for each construction of a singular frame + superConstructorCalled(false), // initialized to false for each construction of a singular frame // and then set true when/if the call occurs + argSlots(NULL) { } +*/ // Plurality plurality; js2val thisObject; // The value of this; none if this function doesn't define this; @@ -1370,11 +1380,19 @@ public: bool callsSuperConstructor; bool superConstructorCalled; + // these relate to the 'most active' invocation + js2val *argSlots; // if the corresponding function uses 'arguments', this pointer is borrowed + // from the arguments instance. + uint32 argCount; // may be more than frameSlots->size() if more arguments are passed + + + + // Variable **positional; // list of positional parameters, in order // uint32 positionalCount; virtual void instantiate(Environment *env); - void assignArguments(JS2Metadata *meta, JS2Object *fnObj, js2val *argBase, uint32 argCount, uint32 length); + js2val *assignArguments(JS2Metadata *meta, JS2Object *fnObj, js2val *argBase, uint32 argCount, uint32 &argsLength); virtual void markChildren(); virtual ~ParameterFrame(); }; diff --git a/mozilla/js2/src/js2op_access.cpp b/mozilla/js2/src/js2op_access.cpp index 58de71424ae..ea3a131a0a0 100644 --- a/mozilla/js2/src/js2op_access.cpp +++ b/mozilla/js2/src/js2op_access.cpp @@ -338,8 +338,8 @@ uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); a = top(); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); - (*parameterSlots)[slotIndex] = a; + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); + parameterSlots[slotIndex] = a; } break; @@ -347,7 +347,7 @@ { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); // XXX some kind of code here? push(JS2VAL_TRUE); } @@ -357,8 +357,8 @@ { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); - push((*parameterSlots)[slotIndex]); + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); + push(parameterSlots[slotIndex]); } break; @@ -367,8 +367,8 @@ uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); push(JS2VAL_NULL); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); - push((*parameterSlots)[slotIndex]); + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); + push(parameterSlots[slotIndex]); } break; diff --git a/mozilla/js2/src/js2op_arithmetic.cpp b/mozilla/js2/src/js2op_arithmetic.cpp index e40ea90dc80..3411c15c53f 100644 --- a/mozilla/js2/src/js2op_arithmetic.cpp +++ b/mozilla/js2/src/js2op_arithmetic.cpp @@ -1242,10 +1242,10 @@ { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); - a = (*parameterSlots)[slotIndex]; + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); + a = parameterSlots[slotIndex]; float64 num = meta->toFloat64(a); - (*parameterSlots)[slotIndex] = allocNumber(num + 1.0); + parameterSlots[slotIndex] = allocNumber(num + 1.0); pushNumber(num); } break; @@ -1253,10 +1253,10 @@ { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); - a = (*parameterSlots)[slotIndex]; + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); + a = parameterSlots[slotIndex]; float64 num = meta->toFloat64(a); - (*parameterSlots)[slotIndex] = allocNumber(num - 1.0); + parameterSlots[slotIndex] = allocNumber(num - 1.0); pushNumber(num); } break; @@ -1264,21 +1264,21 @@ { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); - a = (*parameterSlots)[slotIndex]; + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); + a = parameterSlots[slotIndex]; float64 num = meta->toFloat64(a); a = pushNumber(num + 1.0); - (*parameterSlots)[slotIndex] = a; + parameterSlots[slotIndex] = a; } break; case eParameterSlotPreDec: { uint16 slotIndex = BytecodeContainer::getShort(pc); pc += sizeof(short); - ASSERT(parameterSlots && slotIndex < parameterSlots->size()); - a = (*parameterSlots)[slotIndex]; + ASSERT(parameterSlots && slotIndex < parameterFrame->frameSlots->size()); + a = parameterSlots[slotIndex]; float64 num = meta->toFloat64(a); a = pushNumber(num - 1.0); - (*parameterSlots)[slotIndex] = a; + parameterSlots[slotIndex] = a; } break; diff --git a/mozilla/js2/src/js2op_invocation.cpp b/mozilla/js2/src/js2op_invocation.cpp index 673954f4977..ef56af64a26 100644 --- a/mozilla/js2/src/js2op_invocation.cpp +++ b/mozilla/js2/src/js2op_invocation.cpp @@ -85,9 +85,8 @@ pFrame->instantiate(meta->env); baseVal = OBJECT_TO_JS2VAL(new (meta) SimpleInstance(meta, protoVal, meta->objectType(protoVal))); pFrame->thisObject = baseVal; - pFrame->assignArguments(meta, obj, base(argCount), argCount, length); + parameterSlots = pFrame->assignArguments(meta, obj, base(argCount), argCount, length); jsr(phase, fWrap->bCon, base(argCount + 1) - execStack, baseVal, fWrap->env); - parameterSlots = pFrame->frameSlots; meta->env->addFrame(pFrame, baseVal); parameterFrame = pFrame; pFrame = NULL; @@ -143,13 +142,12 @@ doCall: } else { if (length || fInst->isMethodClosure || fWrap->compileFrame->buildArguments) { - pFrame = new (meta) ParameterFrame(fWrap->compileFrame); - pFrame->instantiate(meta->env); + pFrame = fWrap->compileFrame;//new (meta) ParameterFrame(fWrap->compileFrame); + //pFrame->instantiate(meta->env); pFrame->thisObject = a; // XXX (use fWrap->compileFrame->signature) - pFrame->assignArguments(meta, fObj, base(argCount), argCount, length); + parameterSlots = pFrame->assignArguments(meta, fObj, base(argCount), argCount, length); jsr(phase, fWrap->bCon, base(argCount + 2) - execStack, JS2VAL_VOID, fWrap->env); - parameterSlots = pFrame->frameSlots; if (fInst->isMethodClosure) meta->env->addFrame(meta->objectType(a)); meta->env->addFrame(pFrame, a); @@ -162,7 +160,7 @@ doCall: // need to find a more efficient way of stashing 'this' // used to be : "meta->env->addFrame(fWrap->compileFrame->prototype);" // Still need to mark the frame as a runtime frame (see stmtnode::return in validate) - pFrame = new (meta) ParameterFrame(a, fWrap->compileFrame->prototype); + pFrame = fWrap->compileFrame; //new (meta) ParameterFrame(a, fWrap->compileFrame->prototype); pFrame->pluralFrame = fWrap->compileFrame; meta->env->addFrame(pFrame, a); }