Various bug fixings. Added 'dynamic' attribute.

git-svn-id: svn://10.0.0.236/trunk@135505 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rogerl%netscape.com 2002-12-19 23:57:32 +00:00
parent 487ae18e8b
commit c0a00027a6
11 changed files with 157 additions and 111 deletions

View File

@ -339,23 +339,24 @@ js2val dump(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint
js2val load(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint32 argc)
{
// Set the environment to global object and system frame so that the
// load happens into the top frame.
if (argc) {
// Save off the current top frame and root it.
Frame *curTopFrame = meta->env.getTopFrame();
JS2Object::RootIterator ri = JS2Object::addRoot(&curTopFrame);
meta->env.setTopFrame(meta->env.getPackageOrGlobalFrame());
Environment *curEnv = meta->env;
JS2Object::RootIterator ri = JS2Object::addRoot(&curEnv);
// Set the environment to global object and system frame so that the
// load happens into the top frame.
meta->env = new Environment(curEnv->getSystemFrame(), curEnv->getPackageOrGlobalFrame());
js2val result = JS2VAL_UNDEFINED;
try {
result = meta->readEvalFile(*meta->toString(argv[0]));
}
catch (Exception x) {
meta->env.setTopFrame(curTopFrame);
meta->env = curEnv;
JS2Object::removeRoot(ri);
throw x;
}
meta->env.setTopFrame(curTopFrame);
meta->env = curEnv;
JS2Object::removeRoot(ri);
return result;
}

View File

@ -754,7 +754,7 @@ namespace MetaData {
activationStackTop->bCon = bCon;
activationStackTop->pc = pc;
activationStackTop->phase = phase;
activationStackTop->topFrame = meta->env.getTopFrame();
activationStackTop->topFrame = meta->env->getTopFrame();
activationStackTop->execStackBase = stackBase;
activationStackTop->retval = returnVal;
activationStackTop++;
@ -774,8 +774,8 @@ namespace MetaData {
bCon = activationStackTop->bCon;
pc = activationStackTop->pc;
phase = activationStackTop->phase;
while (meta->env.getTopFrame() != activationStackTop->topFrame)
meta->env.removeTopFrame();
while (meta->env->getTopFrame() != activationStackTop->topFrame)
meta->env->removeTopFrame();
sp = activationStackTop->execStackBase;
if (!JS2VAL_IS_VOID(activationStackTop->retval)) // XXX might need an actual 'returnValue' flag instead
retval = activationStackTop->retval;

View File

@ -306,13 +306,13 @@ void initMathObject(JS2Metadata *meta)
publicNamespaceList.push_back(meta->publicNamespace);
uint32 i;
meta->env.addFrame(meta->mathClass);
meta->env->addFrame(meta->mathClass);
for (i = 0; i < M_CONSTANTS_COUNT; i++)
{
Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(MathObjectConstants[i].value), true);
meta->defineStaticMember(&meta->env, &meta->world.identifiers[MathObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineStaticMember(meta->env, &meta->world.identifiers[MathObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
}
meta->env.removeTopFrame();
meta->env->removeTopFrame();
typedef struct {
char *name;
@ -343,16 +343,16 @@ void initMathObject(JS2Metadata *meta)
{ NULL },
};
meta->env.addFrame(meta->mathClass);
meta->env->addFrame(meta->mathClass);
PrototypeFunction *pf = &prototypeFunctions[0];
while (pf->name) {
CallableInstance *fInst = new CallableInstance(meta->functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(fInst), true);
meta->defineStaticMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineStaticMember(meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
pf++;
}
meta->env.removeTopFrame();
meta->env->removeTopFrame();

View File

@ -147,7 +147,7 @@ namespace MetaData {
*/
void JS2Metadata::ValidateStmtList(StmtNode *p) {
while (p) {
ValidateStmt(&cxt, &env, Singular, p);
ValidateStmt(&cxt, env, Singular, p);
p = p->next;
}
}
@ -162,37 +162,47 @@ namespace MetaData {
CallableInstance *JS2Metadata::validateStaticFunction(FunctionStmtNode *f, js2val compileThis, bool prototype, bool unchecked, Context *cxt, Environment *env)
{
ParameterFrame *compileFrame = new ParameterFrame(compileThis, prototype);
CompilationData *oldData = startCompilationUnit(f->fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
env->addFrame(compileFrame);
VariableBinding *pb = f->function.parameters;
if (pb) {
NamespaceList publicNamespaceList;
publicNamespaceList.push_back(publicNamespace);
uint32 pCount = 0;
while (pb) {
pCount++;
pb = pb->next;
}
pb = f->function.parameters;
compileFrame->positional = new Variable *[pCount];
compileFrame->positionalCount = pCount;
pCount = 0;
while (pb) {
// XXX define a static binding for each parameter
Variable *v = new Variable();
compileFrame->positional[pCount++] = v;
pb->mn = defineStaticMember(env, pb->name, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos);
pb = pb->next;
}
}
ValidateStmt(cxt, env, Plural, f->function.body);
env->removeTopFrame();
restoreCompilationUnit(oldData);
CallableInstance *fInst = new CallableInstance(functionClass);
fInst->fWrap = new FunctionWrapper(unchecked, compileFrame);
f->fWrap = fInst->fWrap;
JS2Object::RootIterator ri = JS2Object::addRoot(&fInst);
Frame *curTopFrame = env->getTopFrame();
try {
CompilationData *oldData = startCompilationUnit(f->fWrap->bCon, bCon->mSource, bCon->mSourceLocation);
env->addFrame(compileFrame);
VariableBinding *pb = f->function.parameters;
if (pb) {
NamespaceList publicNamespaceList;
publicNamespaceList.push_back(publicNamespace);
uint32 pCount = 0;
while (pb) {
pCount++;
pb = pb->next;
}
pb = f->function.parameters;
compileFrame->positional = new Variable *[pCount];
compileFrame->positionalCount = pCount;
pCount = 0;
while (pb) {
// XXX define a static binding for each parameter
Variable *v = new Variable();
compileFrame->positional[pCount++] = v;
pb->mn = defineStaticMember(env, pb->name, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, pb->pos);
pb = pb->next;
}
}
ValidateStmt(cxt, env, Plural, f->function.body);
env->removeTopFrame();
restoreCompilationUnit(oldData);
}
catch (Exception x) {
env->setTopFrame(curTopFrame);
JS2Object::removeRoot(ri);
throw x;
}
JS2Object::removeRoot(ri);
return fInst;
}
@ -478,8 +488,6 @@ namespace MetaData {
compileThis = JS2VAL_INACCESSIBLE;
Frame *topFrame = env->getTopFrame();
CallableInstance *fInst = validateStaticFunction(f, compileThis, prototype, unchecked, cxt, env);
switch (memberMod) {
case Attribute::NoModifier:
case Attribute::Static:
@ -488,6 +496,7 @@ namespace MetaData {
// XXX getter/setter --> ????
}
else {
CallableInstance *fInst = validateStaticFunction(f, compileThis, prototype, unchecked, cxt, env);
if (unchecked
&& (f->attributes == NULL)
&& ((topFrame->kind == GlobalObjectKind)
@ -507,6 +516,7 @@ namespace MetaData {
case Attribute::Final:
{
// XXX Here the spec. has ???, so the following is tentative
CallableInstance *fInst = validateStaticFunction(f, compileThis, prototype, unchecked, cxt, env);
JS2Class *c = checked_cast<JS2Class *>(env->getTopFrame());
InstanceMember *m = new InstanceMethod(fInst);
defineInstanceMember(c, cxt, f->function.name, a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, m, p->pos);
@ -515,6 +525,7 @@ namespace MetaData {
case Attribute::Constructor:
{
// XXX Here the spec. has ???, so the following is tentative
CallableInstance *fInst = validateStaticFunction(f, compileThis, prototype, unchecked, cxt, env);
ConstructorMethod *cm = new ConstructorMethod(OBJECT_TO_JS2VAL(fInst));
defineStaticMember(env, f->function.name, a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, cm, p->pos);
}
@ -702,7 +713,7 @@ namespace MetaData {
{
size_t lastPos = p->pos;
while (p) {
SetupStmt(&env, phase, p);
SetupStmt(env, phase, p);
lastPos = p->pos;
p = p->next;
}
@ -729,7 +740,7 @@ namespace MetaData {
ASSERT(phase == CompilePhase);
if (v->vb->type) {
v->type = NULL;
v->type = EvalTypeExpression(&env, CompilePhase, v->vb->type);
v->type = EvalTypeExpression(env, CompilePhase, v->vb->type);
}
else
v->type = objectClass;
@ -1423,6 +1434,12 @@ namespace MetaData {
ca->memberMod = Attribute::Virtual;
return ca;
}
else
if (name == world.identifiers["dynamic"]) {
ca = new CompoundAttribute();
ca->dynamic = true;
return ca;
}
}
}
// fall thru to execute a readReference on the identifier...
@ -2376,7 +2393,7 @@ doUnary:
break;
fi++;
}
if ((fi != getEnd()) && ((*fi)->kind == ClassKind))
if ((fi != getBegin()) && ((*fi)->kind == ClassKind))
fi--;
return fi;
}
@ -2384,7 +2401,7 @@ doUnary:
// Returns the penultimate frame, either Package or Global
Frame *Environment::getPackageOrGlobalFrame()
{
return *(getEnd() - 1);
return *(getEnd() - 2);
}
// findThis returns the value of this. If allowPrototypeThis is true, allow this to be defined
@ -2497,7 +2514,7 @@ doUnary:
// need to mark all the frames in the environment - otherwise a marked frame that
// came initially from the bytecodeContainer may prevent the markChildren call
// from finding frames further down the list.
void Environment::mark()
void Environment::markChildren()
{
FrameListIterator fi = getBegin();
while (fi != getEnd()) {
@ -2606,6 +2623,16 @@ doUnary:
}
fr = *++fi;
}
fi = env->getBegin();
fr = *++fi;
while (fr != regionalFrame) {
for (b = fr->staticWriteBindings.lower_bound(*id),
end = fr->staticWriteBindings.upper_bound(*id); (b != end); b++) {
if (mn->matches(b->second->qname) && (b->second->content->kind != StaticMember::Forbidden))
reportError(Exception::definitionError, "Duplicate definition {0}", pos, id);
}
fr = *++fi;
}
}
if (regionalFrame->kind == GlobalObjectKind) {
GlobalObject *gObj = checked_cast<GlobalObject *>(regionalFrame);
@ -2625,6 +2652,7 @@ doUnary:
}
if (localFrame != regionalFrame) {
fi = env->getBegin();
Frame *fr = *++fi;
while (fr != regionalFrame) {
for (NamespaceListIterator nli = mn->nsList.begin(), nlend = mn->nsList.end(); (nli != nlend); nli++) {
@ -2642,7 +2670,7 @@ doUnary:
return mn;
}
// Look through 'c' and all it's super classes for a identifier
// Look through 'c' and all it's super classes for an identifier
// matching the qualified name and access.
InstanceMember *JS2Metadata::findInstanceMember(JS2Class *c, QualifiedName *qname, Access access)
{
@ -2933,7 +2961,7 @@ doUnary:
publicNamespace(new Namespace(engine->public_StringAtom)),
bCon(new BytecodeContainer()),
glob(new GlobalObject(world)),
env(new MetaData::SystemFrame(), glob),
env(new Environment(new MetaData::SystemFrame(), glob)),
showTrees(false)
{
engine->meta = this;
@ -2959,6 +2987,22 @@ doUnary:
// A 'forbidden' member, used to mark hidden bindings
forbiddenMember = new StaticMember(Member::Forbidden);
// needed for class instance variables etc...
NamespaceList publicNamespaceList;
publicNamespaceList.push_back(publicNamespace);
Variable *v;
// XXX Built-in Attributes... XXX
/*
XXX see EvalAttributeExpression, where identifiers are being handled for now...
CompoundAttribute *attr = new CompoundAttribute();
attr->dynamic = true;
v = new Variable(attributeClass, OBJECT_TO_JS2VAL(attr), true);
defineStaticMember(env, &world.identifiers["dynamic"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
*/
/*** ECMA 3 Global Object ***/
// Non-function properties of the global object : 'undefined', 'NaN' and 'Infinity'
@ -2978,49 +3022,44 @@ doUnary:
writeDynamicProperty(objectClass->prototype, new Multiname(engine->toString_StringAtom, publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
// needed for class instance variables etc...
NamespaceList publicNamespaceList;
publicNamespaceList.push_back(publicNamespace);
Variable *v;
/*** ECMA 3 Date Class ***/
MAKEBUILTINCLASS(dateClass, objectClass, true, true, true, &world.identifiers["Date"]);
v = new Variable(classClass, OBJECT_TO_JS2VAL(dateClass), true);
defineStaticMember(&env, &world.identifiers["Date"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
defineStaticMember(env, &world.identifiers["Date"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
// dateClass->prototype = new PrototypeInstance(NULL, dateClass);
initDateObject(this);
/*** ECMA 3 RegExp Class ***/
MAKEBUILTINCLASS(regexpClass, objectClass, true, true, true, &world.identifiers["RegExp"]);
v = new Variable(classClass, OBJECT_TO_JS2VAL(regexpClass), true);
defineStaticMember(&env, &world.identifiers["RegExp"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
defineStaticMember(env, &world.identifiers["RegExp"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
initRegExpObject(this);
/*** ECMA 3 String Class ***/
v = new Variable(classClass, OBJECT_TO_JS2VAL(stringClass), true);
defineStaticMember(&env, &world.identifiers["String"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
defineStaticMember(env, &world.identifiers["String"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
initStringObject(this);
/*** ECMA 3 Number Class ***/
v = new Variable(classClass, OBJECT_TO_JS2VAL(numberClass), true);
defineStaticMember(&env, &world.identifiers["Number"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
defineStaticMember(env, &world.identifiers["Number"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
initNumberObject(this);
/*** ECMA 3 Math Class ***/
MAKEBUILTINCLASS(mathClass, objectClass, true, true, true, &world.identifiers["Math"]);
v = new Variable(classClass, OBJECT_TO_JS2VAL(mathClass), true);
defineStaticMember(&env, &world.identifiers["Math"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
defineStaticMember(env, &world.identifiers["Math"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
initMathObject(this);
/*** ECMA 3 Array Class ***/
MAKEBUILTINCLASS(arrayClass, objectClass, true, true, true, &world.identifiers["Array"]);
v = new Variable(classClass, OBJECT_TO_JS2VAL(arrayClass), true);
defineStaticMember(&env, &world.identifiers["Array"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
defineStaticMember(env, &world.identifiers["Array"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
initArrayObject(this);
/*** ECMA 3 Function Class ***/
v = new Variable(classClass, OBJECT_TO_JS2VAL(functionClass), true);
defineStaticMember(&env, &world.identifiers["Function"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
defineStaticMember(env, &world.identifiers["Function"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
// XXX more here!
}
@ -3090,7 +3129,7 @@ doUnary:
bool JS2Metadata::relaxedHasType(js2val objVal, JS2Class *c)
{
JS2Class *t = objectType(objVal);
return c->isAncestor(t) || (JS2VAL_IS_NULL(objVal) && t->allowNull);
return t->isAncestor(c) || (JS2VAL_IS_NULL(objVal) && t->allowNull);
}
@ -3237,6 +3276,8 @@ doUnary:
dMap = &(checked_cast<GlobalObject *>(container))->dynamicProperties;
else
dMap = &(checked_cast<PrototypeInstance *>(container))->dynamicProperties;
if (dMap == NULL)
return false; // 'None'
for (DynamicPropertyIterator i = dMap->begin(), end = dMap->end(); (i != end); i++) {
if (i->first == *name) {
i->second = newValue;
@ -3879,7 +3920,7 @@ deleteClassProperty:
bCon->mark();
if (engine)
engine->mark();
env.mark();
GCMARKOBJECT(env);
GCMARKOBJECT(glob);
@ -4206,7 +4247,7 @@ deleteClassProperty:
}
}
// return true if 'heir' is a member of this class or of any antecedent
// return true if 'heir' is this class or is any antecedent
bool JS2Class::isAncestor(JS2Class *heir)
{
JS2Class *kinsman = this;

View File

@ -94,7 +94,9 @@ enum ObjectKind {
MultinameKind,
MethodClosureKind,
AlienInstanceKind,
ForIteratorKind
ForIteratorKind,
EnvironmentKind // Not an available JS2 runtime kind
};
enum Plurality { Singular, Plural };
@ -877,9 +879,10 @@ public:
typedef std::deque<Frame *> FrameList;
typedef FrameList::iterator FrameListIterator;
class Environment {
// Deriving from JS2Object for gc sake only, these are supposed to be found as JS2 values
class Environment : public JS2Object {
public:
Environment(SystemFrame *systemFrame, Frame *nextToLast) { frameList.push_back(nextToLast); frameList.push_back(systemFrame); }
Environment(SystemFrame *systemFrame, Frame *nextToLast) : JS2Object(EnvironmentKind) { frameList.push_back(nextToLast); frameList.push_back(systemFrame); }
JS2Class *getEnclosingClass();
FrameListIterator getRegionalFrame();
@ -887,7 +890,7 @@ public:
FrameListIterator getBegin() { return frameList.begin(); }
FrameListIterator getEnd() { return frameList.end(); }
Frame *getPackageOrGlobalFrame();
Frame *getSystemFrame() { return frameList.back(); }
SystemFrame *getSystemFrame() { return checked_cast<SystemFrame *>(frameList.back()); }
void setTopFrame(Frame *f) { while (frameList.front() != f) frameList.pop_front(); }
@ -901,7 +904,7 @@ public:
void instantiateFrame(Frame *pluralFrame, Frame *singularFrame);
void mark();
void markChildren();
private:
FrameList frameList;
@ -986,6 +989,7 @@ public:
js2val readEvalFile(const String& fileName);
js2val readEvalFile(const char *fileName);
// XXX - passing (Context *cxt, Environment *env) throughout - but do these really change?
void ValidateStmtList(Context *cxt, Environment *env, Plurality pl, StmtNode *p);
void ValidateTypeExpression(Context *cxt, Environment *env, ExprNode *e) { ValidateExpression(cxt, env, e); }
@ -1110,7 +1114,7 @@ public:
BConList bConList;
GlobalObject *glob;
Environment env;
Environment *env;
Context cxt;
TargetList targetList; // stack of potential break/continue targets

View File

@ -100,13 +100,13 @@ namespace MetaData {
publicNamespaceList.push_back(meta->publicNamespace);
uint32 i;
meta->env.addFrame(meta->numberClass);
meta->env->addFrame(meta->numberClass);
for (i = 0; i < N_CONSTANTS_COUNT; i++)
{
Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(NumberObjectConstants[i].value), true);
meta->defineStaticMember(&meta->env, &meta->world.identifiers[NumberObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
meta->defineStaticMember(meta->env, &meta->world.identifiers[NumberObjectConstants[i].name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
}
meta->env.removeTopFrame();
meta->env->removeTopFrame();
}

View File

@ -90,7 +90,7 @@
{
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
push(meta->env.lexicalRead(meta, mn, phase));
push(meta->env->lexicalRead(meta, mn, phase));
}
break;
@ -98,7 +98,7 @@
{
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
push(BOOLEAN_TO_JS2VAL(meta->env.lexicalDelete(meta, mn, phase)));
push(BOOLEAN_TO_JS2VAL(meta->env->lexicalDelete(meta, mn, phase)));
}
break;
@ -109,7 +109,7 @@
a = top();
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
meta->env.lexicalWrite(meta, mn, a, true, phase);
meta->env->lexicalWrite(meta, mn, a, true, phase);
}
break;
@ -118,7 +118,7 @@
{
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
a = meta->env.lexicalRead(meta, mn, phase);
a = meta->env->lexicalRead(meta, mn, phase);
push(JS2VAL_NULL);
push(a);
}
@ -221,7 +221,7 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
Frame *f = meta->env.getTopFrame();
Frame *f = meta->env->getTopFrame();
a = pop();
(*f->temps)[slotIndex] = a;
}
@ -231,7 +231,7 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
Frame *f = meta->env.getTopFrame();
Frame *f = meta->env->getTopFrame();
push((*f->temps)[slotIndex]);
}
break;

View File

@ -834,23 +834,23 @@
{
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
a = meta->env.lexicalRead(meta, mn, phase);
a = meta->env->lexicalRead(meta, mn, phase);
if (JS2VAL_IS_LONG(a)) {
int64 i = *JS2VAL_TO_LONG(a);
JSLL_ADD(i, i, 1);
meta->env.lexicalWrite(meta, mn, allocLong(i), true, phase);
meta->env->lexicalWrite(meta, mn, allocLong(i), true, phase);
push(a);
}
else {
if (JS2VAL_IS_ULONG(a)) {
uint64 i = *JS2VAL_TO_ULONG(a);
JSLL_ADD(i, i, 1);
meta->env.lexicalWrite(meta, mn, allocULong(i), true, phase);
meta->env->lexicalWrite(meta, mn, allocULong(i), true, phase);
push(a);
}
else {
float64 num = meta->toFloat64(a);
meta->env.lexicalWrite(meta, mn, allocNumber(num + 1.0), true, phase);
meta->env->lexicalWrite(meta, mn, allocNumber(num + 1.0), true, phase);
pushNumber(num);
}
}
@ -860,9 +860,9 @@
{
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
a = meta->env.lexicalRead(meta, mn, phase);
a = meta->env->lexicalRead(meta, mn, phase);
float64 num = meta->toFloat64(a);
meta->env.lexicalWrite(meta, mn, allocNumber(num - 1.0), true, phase);
meta->env->lexicalWrite(meta, mn, allocNumber(num - 1.0), true, phase);
pushNumber(num);
}
break;
@ -870,20 +870,20 @@
{
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
a = meta->env.lexicalRead(meta, mn, phase);
a = meta->env->lexicalRead(meta, mn, phase);
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
meta->env.lexicalWrite(meta, mn, a, true, phase);
meta->env->lexicalWrite(meta, mn, a, true, phase);
}
break;
case eLexicalPreDec:
{
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
a = meta->env.lexicalRead(meta, mn, phase);
a = meta->env->lexicalRead(meta, mn, phase);
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
meta->env.lexicalWrite(meta, mn, a, true, phase);
meta->env->lexicalWrite(meta, mn, a, true, phase);
}
break;

View File

@ -72,17 +72,17 @@
}
ParameterFrame *runtimeFrame = new ParameterFrame(fWrap->compileFrame);
runtimeFrame->instantiate(&meta->env);
runtimeFrame->instantiate(meta->env);
PrototypeInstance *pInst = new PrototypeInstance(protoObj, meta->objectClass);
baseVal = OBJECT_TO_JS2VAL(pInst);
runtimeFrame->thisObject = baseVal;
// assignArguments(runtimeFrame, fWrap->compileFrame->signature);
if (!fWrap->code)
jsr(phase, fWrap->bCon, base(argCount + 1), baseVal); // seems out of order, but we need to catch the current top frame
meta->env.addFrame(runtimeFrame);
meta->env->addFrame(runtimeFrame);
if (fWrap->code) { // native code, pass pointer to argument base
a = fWrap->code(meta, a, base(argCount), argCount);
meta->env.removeTopFrame();
meta->env->removeTopFrame();
pop(argCount + 1);
push(a);
}
@ -114,23 +114,23 @@
a = JS2VAL_VOID;
else {
if (JS2VAL_IS_INACCESSIBLE(compileThis)) {
Frame *g = meta->env.getPackageOrGlobalFrame();
Frame *g = meta->env->getPackageOrGlobalFrame();
if (fWrap->compileFrame->prototype && (JS2VAL_IS_NULL(a) || JS2VAL_IS_VOID(a)) && (g->kind == GlobalObjectKind))
a = OBJECT_TO_JS2VAL(g);
}
}
ParameterFrame *runtimeFrame = new ParameterFrame(fWrap->compileFrame);
runtimeFrame->instantiate(&meta->env);
runtimeFrame->instantiate(meta->env);
runtimeFrame->thisObject = a;
// assignArguments(runtimeFrame, fWrap->compileFrame->signature);
// XXX
runtimeFrame->assignArguments(base(argCount), argCount);
if (!fWrap->code)
jsr(phase, fWrap->bCon, base(argCount + 2), JS2VAL_VOID); // seems out of order, but we need to catch the current top frame
meta->env.addFrame(runtimeFrame);
meta->env->addFrame(runtimeFrame);
if (fWrap->code) { // native code, pass pointer to argument base
a = fWrap->code(meta, a, base(argCount), argCount);
meta->env.removeTopFrame();
meta->env->removeTopFrame();
pop(argCount + 2);
push(a);
}
@ -141,17 +141,17 @@
CallableInstance *fInst = mc->method->fInst;
FunctionWrapper *fWrap = fInst->fWrap;
ParameterFrame *runtimeFrame = new ParameterFrame(fWrap->compileFrame);
runtimeFrame->instantiate(&meta->env);
runtimeFrame->instantiate(meta->env);
runtimeFrame->thisObject = mc->thisObject;
// assignArguments(runtimeFrame, fWrap->compileFrame->signature);
if (!fWrap->code)
jsr(phase, fWrap->bCon, base(argCount + 2), JS2VAL_VOID); // seems out of order, but we need to catch the current top frame
meta->env.addFrame(meta->objectType(mc->thisObject));
meta->env.addFrame(runtimeFrame);
meta->env->addFrame(meta->objectType(mc->thisObject));
meta->env->addFrame(runtimeFrame);
if (fWrap->code) {
a = fWrap->code(meta, mc->thisObject, base(argCount), argCount);
meta->env.removeTopFrame();
meta->env.removeTopFrame();
meta->env->removeTopFrame();
meta->env->removeTopFrame();
pop(argCount + 2);
push(a);
}
@ -190,14 +190,14 @@
{
Frame *f = bCon->mFrameList[BytecodeContainer::getShort(pc)];
pc += sizeof(short);
meta->env.addFrame(f);
f->instantiate(&meta->env);
meta->env->addFrame(f);
f->instantiate(meta->env);
}
break;
case ePopFrame:
{
meta->env.removeTopFrame();
meta->env->removeTopFrame();
}
break;

View File

@ -90,7 +90,7 @@
case eThis: // XXX literal?
{
a = meta->env.findThis(true);
a = meta->env->findThis(true);
if (JS2VAL_IS_INACCESSIBLE(a))
meta->reportError(Exception::compileExpressionError, "'this' not available", errorPos());
push(a);

View File

@ -67,7 +67,6 @@
/* Type tag bitfield length and derived macros. */
#define JS2VAL_TAGBITS 4
#define JS2VAL_UNNUMBER_MASK JS2_BIT(3)
#define JS2VAL_TAGMASK JS2_BITMASK(JS2VAL_TAGBITS)
#define JS2VAL_TAG(v) ((v) & JS2VAL_TAGMASK)
#define JS2VAL_SETTAG(v,t) ((v) | (t))
@ -89,7 +88,8 @@
/* Predicates for type testing. */
#define JS2VAL_IS_OBJECT(v) ((JS2VAL_TAG(v) == JS2VAL_OBJECT) && !JS2VAL_IS_SPECIALREF(v))
#define JS2VAL_IS_NUMBER(v) ((JS2VAL_TAG(v) != JS2VAL_OBJECT) && !(JS2VAL_TAG(v) & JS2VAL_UNNUMBER_MASK))
// XXX think about some way of making this faster...
#define JS2VAL_IS_NUMBER(v) (JS2VAL_IS_INT(v) || JS2VAL_IS_DOUBLE(v) || JS2VAL_IS_LONG(v) || JS2VAL_IS_ULONG(v) || JS2VAL_IS_FLOAT(v))
#define JS2VAL_IS_INT(v) (((v) & JS2VAL_INT) && (v) != JS2VAL_VOID)
#define JS2VAL_IS_DOUBLE(v) (JS2VAL_TAG(v) == JS2VAL_DOUBLE)
#define JS2VAL_IS_STRING(v) (JS2VAL_TAG(v) == JS2VAL_STRING)