BROKEN, changing argument allocation strategy

This commit is contained in:
rogerl%netscape.com 2003-06-12 23:02:51 +00:00
Родитель 4d3d422822
Коммит 08faa0a338
9 изменённых файлов: 176 добавлений и 141 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);

Просмотреть файл

@ -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();

Просмотреть файл

@ -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<js2val>(slotCount);
args->mSplitValue = new js2val[slotCount];
args->mSplit[index] = true;
(*args->mSplitValue)[index] = JS2VAL_VOID;
args->mSplitValue[index] = JS2VAL_VOID;
return true;
}
else

Просмотреть файл

@ -1005,7 +1005,7 @@ namespace MetaData {
if (f->initializer->getKind() == StmtNode::Var) {
VariableStmtNode *vs = checked_cast<VariableStmtNode *>(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<Namespace *>(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<DotReference *>(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<LexicalReference *>(rVal));
returnRef = new (*referenceArena) DotReference(((LexicalReference *)rVal)->variableMultiname);
returnRef = new (*referenceArena) DotReference(((LexicalReference *)rVal)->variableMultiname, bCon);
referenceArena->registerDestructor(returnRef);
checked_cast<DotReference *>(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<ParameterFrame *>(container))->frameSlots)[fv->frameSlot];
ASSERT(fv->frameSlot < (checked_cast<ParameterFrame *>(container))->frameSlots->size());
*rval = (checked_cast<ParameterFrame *>(container))->argSlots[fv->frameSlot];
// *rval = (*(checked_cast<ParameterFrame *>(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<ParameterFrame *>(container))->frameSlots)[fv->frameSlot] = newValue;
ASSERT(fv->frameSlot < (checked_cast<ParameterFrame *>(container))->frameSlots->size());
(checked_cast<ParameterFrame *>(container))->argSlots[fv->frameSlot] = newValue;
// (*(checked_cast<ParameterFrame *>(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<ParameterFrame *>(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<js2val>(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<js2val>(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);
}

Просмотреть файл

@ -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<std::pair<Frame *, js2val> > FrameList;
typedef std::deque<Frame *> 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<Frame *, js2val>(nextToLast, JS2VAL_VOID));
frameList.push_back(std::pair<Frame *, js2val>(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<SystemFrame *>(frameList.back().first); }
SystemFrame *getSystemFrame() { return checked_cast<SystemFrame *>(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<Frame *, js2val>(f, JS2VAL_VOID)); }
void addFrame(Frame *f, js2val x) { frameList.push_front(std::pair<Frame *, js2val>(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();
};

Просмотреть файл

@ -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;

Просмотреть файл

@ -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;

Просмотреть файл

@ -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);
}