Switching to frame & package slot mechanism.

This commit is contained in:
rogerl%netscape.com 2003-04-14 21:01:51 +00:00
Родитель 4dba4eaf22
Коммит 1b01f15f8e
6 изменённых файлов: 318 добавлений и 88 удалений

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

@ -66,6 +66,7 @@ namespace MetaData {
// Begin execution of a bytecodeContainer
js2val JS2Engine::interpret(Phase execPhase, BytecodeContainer *targetbCon, Environment *env)
{
packageFrame = env->getPackageFrame();
jsr(execPhase, targetbCon, sp - execStack, JS2VAL_VOID, env);
ActivationFrame *f = activationStackTop;
js2val result;
@ -509,7 +510,22 @@ namespace MetaData {
{ eForValue, "ForValue", 0 },
{ eFrameSlotRead, "FrameSlotRead", U16 }, // <slot index:u16>
{ eFrameSlotRef, "FrameSlotRef", U16 }, // <slot index:u16>
{ eFrameSlotWrite, "FrameSlotWrite", U16 }, // <slot index:u16>
{ eFrameSlotDelete, "FrameSlotDelete", U16 }, // <slot index:u16>
{ eFrameSlotPostInc, "FrameSlotPostInc", U16 }, // <slot index:u16>
{ eFrameSlotPostDec, "FrameSlotPostDec", U16 }, // <slot index:u16>
{ eFrameSlotPreInc, "FrameSlotPreInc", U16 }, // <slot index:u16>
{ eFrameSlotPreDec, "FrameSlotPreDec", U16 }, // <slot index:u16>
{ ePackageSlotRead, "PackageSlotRead", U16 }, // <slot index:u16>
{ ePackageSlotRef, "PackageSlotRef", U16 }, // <slot index:u16>
{ ePackageSlotWrite, "PackageSlotWrite", U16 }, // <slot index:u16>
{ ePackageSlotDelete, "PackageSlotDelete", U16 }, // <slot index:u16>
{ ePackageSlotPostInc, "PackageSlotPostInc", U16 }, // <slot index:u16>
{ ePackageSlotPostDec, "PackageSlotPostDec", U16 }, // <slot index:u16>
{ ePackageSlotPreInc, "PackageSlotPreInc", U16 }, // <slot index:u16>
{ ePackageSlotPreDec, "PackageSlotPreDec", U16 }, // <slot index:u16>
{ eLexicalRead, "LexicalRead", NAME_INDEX }, // <multiname index:u16>
{ eLexicalWrite, "LexicalWrite", NAME_INDEX }, // <multiname index:u16>
@ -760,6 +776,19 @@ namespace MetaData {
case eLexicalDelete:
return 1; // push boolean result
case eFrameSlotRead:
case ePackageSlotRead:
return 1; // push value
case eFrameSlotWrite:
case ePackageSlotWrite:
return 0; // leaves value on stack
case eFrameSlotRef:
case ePackageSlotRef:
return 2; // push base and value
case eFrameSlotDelete:
case ePackageSlotDelete:
return 1; // push boolean result;
case eDotRead:
return 0; // pop a base, push the value
case eDotWrite:
@ -822,10 +851,15 @@ namespace MetaData {
case eForValue: // leave the iterator helper
return 1; // and push iteration value
case eFrameSlotRead:
return 1; // push value
case eFrameSlotWrite:
return -1; // doesn't leave value on stack
case eFrameSlotPostInc:
case eFrameSlotPostDec:
case eFrameSlotPreInc:
case eFrameSlotPreDec:
case ePackageSlotPostInc:
case ePackageSlotPostDec:
case ePackageSlotPreInc:
case ePackageSlotPreDec:
return 1; // push the new/old value
case eLexicalPostInc:
case eLexicalPostDec:
@ -887,6 +921,7 @@ namespace MetaData {
activationStackTop->env = meta->env; // save current environment, to be restored on rts
activationStackTop->newEnv = env; // and save the new environment, if an exception occurs, we can't depend on meta->env
activationStackTop->topFrame = env->getTopFrame(); // remember how big the new env. is supposed to be so that local frames don't accumulate
localFrame = checked_cast<NonWithFrame *>(activationStackTop->topFrame);
activationStackTop++;
if (new_bCon) {
bCon = new_bCon;

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

@ -106,6 +106,15 @@ enum JS2Op {
eFrameSlotPreInc, // <slot index:u16>
eFrameSlotPreDec, // <slot index:u16>
ePackageSlotRead, // <slot index:u16>
ePackageSlotRef, // <slot index:u16>
ePackageSlotWrite, // <slot index:u16>
ePackageSlotDelete, // <slot index:u16>
ePackageSlotPostInc, // <slot index:u16>
ePackageSlotPostDec, // <slot index:u16>
ePackageSlotPreInc, // <slot index:u16>
ePackageSlotPreDec, // <slot index:u16>
eLexicalRead, // <multiname index:u16>
eLexicalWrite, // <multiname index:u16>
eLexicalInit, // <multiname index:u16>
@ -170,6 +179,7 @@ enum JS2Op {
class Frame;
class NonWithFrame;
class ParameterFrame;
class Environment;
@ -332,6 +342,10 @@ public:
std::stack<HandlerData *> mTryStack;
std::stack<uint8 *> finallyStack;
// For frame slot references:
NonWithFrame *packageFrame;
NonWithFrame *localFrame;
void pushHandler(uint8 *pc);
void popHandler();

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

@ -439,8 +439,7 @@ namespace MetaData {
&& ((topFrame->kind == PackageKind)
|| (topFrame->kind == BlockFrameKind)
|| (topFrame->kind == ParameterKind)) ) {
DynamicVariable *v = defineHoistedVar(env, f->function.name, p, false);
v->value = OBJECT_TO_JS2VAL(fObj);
LocalMember *v = defineHoistedVar(env, f->function.name, p, false, OBJECT_TO_JS2VAL(fObj));
}
else {
Variable *v = new Variable(functionClass, OBJECT_TO_JS2VAL(fObj), true);
@ -500,7 +499,7 @@ namespace MetaData {
&& !immutable
&& (vs->attributes == NULL)
&& (vb->type == NULL)) {
defineHoistedVar(env, name, p, true);
defineHoistedVar(env, name, p, true, JS2VAL_UNDEFINED);
}
else {
a = Attribute::toCompoundAttribute(attr);
@ -517,7 +516,7 @@ namespace MetaData {
// Set type to FUTURE_TYPE - it will be resolved during 'Setup'. The value is either FUTURE_VALUE
// for 'const' - in which case the expression is compile time evaluated (or attempted) or set
// to INACCESSIBLE until run time initialization occurs.
Variable *v = new Variable(FUTURE_TYPE, immutable ? JS2VAL_FUTUREVALUE : JS2VAL_INACCESSIBLE, immutable);
Variable *v = new Variable(FUTURE_TYPE, immutable ? JS2VAL_FUTUREVALUE : JS2VAL_FUTUREVALUE, immutable);
vb->member = v;
v->vb = vb;
vb->mn = defineLocalMember(env, name, a->namespaces, a->overrideMod, a->xplicit, ReadWriteAccess, v, p->pos, true);
@ -2058,54 +2057,97 @@ doUnary:
returnRef = new (*referenceArena) LexicalReference(&i->name, cxt.strict);
referenceArena->registerDestructor(returnRef);
((LexicalReference *)returnRef)->variableMultiname.addNamespace(cxt);
#if 0
// Try to find this identifier at compile time, we have to stop if we reach
// a frame that supports dynamic properties - the identifier could be
// created at runtime without us finding it here.
// We're looking to find both the type of the reference (to store into exprType)
// and to see if we can change the reference to a FrameSlot or Slot (for member
// functions)
Multiname *multiname = &((LexicalReference *)returnRef)->variableMultiname;
FrameListIterator fi = env->getBegin();
while (fi != env->getEnd()) {
bool keepLooking = true;
while (fi != env->getEnd() && keepLooking) {
Frame *fr = *fi;
if (fr->kind == WithFrameKind)
// XXX unless it's provably not a dynamic object that been with'd??
break;
NonWithFrame *pf = checked_cast<NonWithFrame *>(*fi);
if (pf->kind != ClassKind) {
LocalMember *m = findFlatMember(pf, multiname, ReadAccess, CompilePhase);
if (m && m->kind == Member::Variable) {
NonWithFrame *pf = checked_cast<NonWithFrame *>(fr);
switch (pf->kind) {
default:
keepLooking = false;
break;
case BlockFrameKind:
{
LocalMember *m = findLocalMember(pf, multiname, ReadAccess);
if (m) {
switch (checked_cast<LocalMember *>(m)->memberKind) {
case LocalMember::VariableMember:
*exprType = checked_cast<Variable *>(m)->type;
break;
}
if (pf->kind == PackageKind)
case LocalMember::FrameVariableMember:
ASSERT(!checked_cast<FrameVariable *>(m)->packageSlot);
returnRef = new (*referenceArena) FrameSlotReference(checked_cast<FrameVariable *>(m)->frameSlot);
break;
}
break;
keepLooking = false;
}
}
break;
case ClassKind:
{
// look for this identifier in the static members
// (do we have a this?)
// If the class allows dynamic members, have to stop the search here
keepLooking = false;
}
break;
case PackageKind:
{
JS2Class *limit = objectType(pf);
InstanceMember *mBase = findBaseInstanceMember(limit, multiname, ReadAccess);
if (mBase)
// XXX *exprType = mBase->...
keepLooking = false;
else {
JS2Class *c = checked_cast<JS2Class *>(pf);
MemberDescriptor m2;
if (findLocalMember(c, multiname, ReadAccess, CompilePhase, &m2)
&& m2.localMember) {
if (m2.localMember->kind == LocalMember::Variable)
*exprType = checked_cast<Variable *>(m2.localMember)->type;
break;
}
if (m2.ns) { // an instance member
QualifiedName qname(m2.ns, multiname->name);
InstanceMember *m = findInstanceMember(c, &qname, ReadAccess);
js2val base = OBJECT_TO_JS2VAL(pf);
Member *m = findCommonMember(&base, multiname, ReadAccess, false);
if (m) {
if (m->kind == InstanceMember::InstanceVariableKind)
*exprType = checked_cast<InstanceVariable *>(m)->type;
switch (m->memberKind) {
case Member::ForbiddenMember:
case Member::DynamicVariableMember:
case Member::FrameVariableMember:
case Member::VariableMember:
case Member::ConstructorMethodMember:
case Member::SetterMember:
case Member::GetterMember:
switch (checked_cast<LocalMember *>(m)->memberKind) {
case LocalMember::VariableMember:
*exprType = checked_cast<Variable *>(m)->type;
break;
case LocalMember::FrameVariableMember:
ASSERT(checked_cast<FrameVariable *>(m)->packageSlot);
returnRef = new (*referenceArena) PackageSlotReference(checked_cast<FrameVariable *>(m)->frameSlot);
break;
}
else
break; // XXX Shouldn't findLocalMember guarantee this not possible?
}
else
break;
// XXX ok to keep going? Suppose the class allows dynamic properties?
case Member::InstanceVariableMember:
case Member::InstanceMethodMember:
case Member::InstanceGetterMember:
case Member::InstanceSetterMember:
// XXX checked_cast<InstanceMember *>(m)
break;
}
keepLooking = false;
}
}
// XXX if package allows dynamic members, stop looking
keepLooking = false;
}
break;
}
fi++;
}
#endif
}
break;
case ExprNode::Delete:
@ -2630,7 +2672,12 @@ doUnary:
LocalBindingEntry *lbe = *bi2;
singularFrame->localBindings.insert(lbe->name, lbe->clone());
}
if (pluralFrame->slots) {
size_t count = pluralFrame->slots->size();
singularFrame->slots = new std::vector<js2val>(count);
for (size_t i = 0; i < count; i++)
(*singularFrame->slots)[i] = (*pluralFrame->slots)[i];
}
}
// need to mark all the frames in the environment - otherwise a marked frame that
@ -2978,13 +3025,12 @@ doUnary:
// will shadow a parameter with the same name for compatibility with ECMAScript Edition 3.
// If there are multiple function definitions, the initial value is the last function definition.
LocalMember *JS2Metadata::defineHoistedVar(Environment *env, const String *id, StmtNode *p, bool isVar)
LocalMember *JS2Metadata::defineHoistedVar(Environment *env, const String *id, StmtNode *p, bool isVar, js2val initVal)
{
LocalMember *result;
LocalMember *result = NULL;
FrameListIterator regionalFrameEnd = env->getRegionalEnvironment();
NonWithFrame *regionalFrame = checked_cast<NonWithFrame *>(*regionalFrameEnd);
ASSERT((regionalFrame->kind == PackageKind) || (regionalFrame->kind == ParameterKind));
rescan:
// run through all the existing bindings, to see if this variable already exists.
LocalBinding *bindingResult = NULL;
@ -3019,7 +3065,8 @@ rescan:
}
else
lbe = *lbeP;
result = new FrameVariable(regionalFrame->allocateSlot());
result = new FrameVariable(regionalFrame->allocateSlot(), (regionalFrame->kind == PackageKind));
(*regionalFrame->slots)[checked_cast<FrameVariable *>(result)->frameSlot] = initVal;
LocalBinding *sb = new LocalBinding(ReadWriteAccess, result, true);
lbe->bindingList.push_back(LocalBindingEntry::NamespaceBinding(publicNamespace, sb));
}
@ -3029,14 +3076,15 @@ rescan:
else {
if ((bindingResult->accesses != ReadWriteAccess)
|| ((bindingResult->content->memberKind != LocalMember::DynamicVariableMember)
&& (bindingResult->content->memberKind != LocalMember::FrameVariableMember))
&& (bindingResult->content->memberKind != LocalMember::FrameVariableMember)))
reportError(Exception::definitionError, "Illegal redefinition of {0}", p->pos, id);
else {
result = bindingResult->content;
writeLocalMember(result, initVal, true);
}
}
// At this point a hoisted binding of the same var already exists, so there is no need to create another one
}
return result;
}
@ -3551,14 +3599,15 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
return result;
}
InstanceMember *JS2Metadata::findBaseInstanceMember(JS2Class *limit, Multiname *multiname, Access access)
// Start from the root class (Object) and proceed through more specific classes that are ancestors of c
InstanceMember *JS2Metadata::findBaseInstanceMember(JS2Class *c, Multiname *multiname, Access access)
{
InstanceMember *result = NULL;
if (limit->super) {
result = findBaseInstanceMember(limit->super, multiname, access);
if (c->super) {
result = findBaseInstanceMember(c->super, multiname, access);
if (result) return result;
}
return findLocalInstanceMember(limit, multiname, access);
return findLocalInstanceMember(c, multiname, access);
}
// getDerivedInstanceMember returns the most derived instance member whose name includes that of mBase and
@ -3709,6 +3758,20 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
*rval = v->value;
return true;
}
case LocalMember::FrameVariableMember:
{
if (phase == CompilePhase)
reportError(Exception::compileExpressionError, "Inappropriate compile time expression", engine->errorPos());
FrameVariable *f = checked_cast<FrameVariable *>(m);
if (f->packageSlot)
*rval = (*env->getPackageFrame()->slots)[f->frameSlot];
else {
FrameListIterator fi = env->getRegionalFrame();
ASSERT((*fi)->kind == ParameterKind);
*rval = (*checked_cast<NonWithFrame *>(*(fi - 1))->slots)[f->frameSlot];
}
}
return true;
case LocalMember::DynamicVariableMember:
if (phase == CompilePhase)
reportError(Exception::compileExpressionError, "Inappropriate compile time expression", engine->errorPos());
@ -3741,13 +3804,25 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
if (!initFlag
&& (JS2VAL_IS_INACCESSIBLE(v->value)
|| (v->immutable && !JS2VAL_IS_UNINITIALIZED(v->value))))
if (flags == JS2)
if (!cxt.E3compatibility)
reportError(Exception::propertyAccessError, "Forbidden access", engine->errorPos());
else // quietly ignore the write for JS1 compatibility
return true;
v->value = v->type->implicitCoerce(this, newValue);
}
return true;
case LocalMember::FrameVariableMember:
{
FrameVariable *f = checked_cast<FrameVariable *>(m);
if (f->packageSlot)
(*env->getPackageFrame()->slots)[f->frameSlot] = newValue;
else {
FrameListIterator fi = env->getRegionalFrame();
ASSERT((*fi)->kind == ParameterKind);
(*checked_cast<NonWithFrame *>(*(fi - 1))->slots)[f->frameSlot] = newValue;
}
}
return true;
case LocalMember::DynamicVariableMember:
(checked_cast<DynamicVariable *>(m))->value = newValue;
return true;

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

@ -455,12 +455,13 @@ public:
class FrameVariable : public LocalMember {
public:
FrameVariable(uint16 frameSlot) : LocalMember(Member::FrameVariableMember), frameSlot(frameSlot), sealed(false) { }
FrameVariable(uint16 frameSlot, bool packageSlot) : LocalMember(Member::FrameVariableMember), frameSlot(frameSlot), packageSlot(packageSlot), sealed(false) { }
uint16 frameSlot;
bool packageSlot; // true if the variable is in a package frame
bool sealed; // true if this variable cannot be deleted using the delete operator
virtual LocalMember *clone() { return new FrameVariable(frameSlot); }
virtual LocalMember *clone() { return new FrameVariable(frameSlot, packageSlot); }
};
class ConstructorMethod : public LocalMember {
@ -651,7 +652,7 @@ public:
LocalBindingMap localBindings; // Map of qualified names to members defined in this frame
std::vector<js2val> *slots; // temporaries allocted in this frame
std::vector<js2val> *slots; // temporaries or frame variables allocted in this frame
uint16 allocateSlot();
virtual void instantiate(Environment * /*env*/) { ASSERT(false); }
@ -1067,6 +1068,52 @@ public:
virtual int hasStackEffect() { return 1; }
};
class FrameSlotReference : public Reference {
// A special case of a DotReference with an FrameSl instead of a D
public:
FrameSlotReference(uint32 slotIndex) : slotIndex(slotIndex) { }
virtual ~FrameSlotReference() { }
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFrameSlotRead, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFrameSlotWrite, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFrameSlotRef, pos); bCon->addShort((uint16)slotIndex); }
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(eFrameSlotPostInc, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFrameSlotPostDec, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFrameSlotPreInc, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFrameSlotPreDec, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFalse, pos); /* bCon->emitOp(eFrameSlotDelete, pos); bCon->addShort((uint16)slotIndex); */ }
uint32 slotIndex;
virtual int hasStackEffect() { return 0; }
};
class PackageSlotReference : public Reference {
// A special case of a DotReference with an PackageSl instead of a D
public:
PackageSlotReference(uint32 slotIndex) : slotIndex(slotIndex) { }
virtual ~PackageSlotReference() { }
virtual void emitReadBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(ePackageSlotRead, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitWriteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(ePackageSlotWrite, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitReadForInvokeBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(ePackageSlotRef, pos); bCon->addShort((uint16)slotIndex); }
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(ePackageSlotPostInc, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitPostDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(ePackageSlotPostDec, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitPreIncBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(ePackageSlotPreInc, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(ePackageSlotPreDec, pos); bCon->addShort((uint16)slotIndex); }
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFalse, pos); /* bCon->emitOp(ePackageSlotDelete, pos); bCon->addShort((uint16)slotIndex); */ }
uint32 slotIndex;
virtual int hasStackEffect() { return 0; }
};
class NamedArgument {
public:
@ -1260,7 +1307,7 @@ public:
LocalMember *findFlatMember(NonWithFrame *container, Multiname *multiname, Access access, Phase phase);
InstanceBinding *resolveInstanceMemberName(JS2Class *js2class, Multiname *multiname, Access access, Phase phase, QualifiedName *qname);
DynamicVariable *defineHoistedVar(Environment *env, const String *id, StmtNode *p, bool isVar);
LocalMember *defineHoistedVar(Environment *env, const String *id, StmtNode *p, bool isVar, js2val initVal);
Multiname *defineLocalMember(Environment *env, const String *id, NamespaceList &namespaces, Attribute::OverrideModifier overrideMod, bool xplicit, Access access, LocalMember *m, size_t pos, bool enumerable);
InstanceMember *defineInstanceMember(JS2Class *c, Context *cxt, const String *id, NamespaceList &namespaces,
Attribute::OverrideModifier overrideMod, bool xplicit,

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

@ -261,9 +261,8 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
NonWithFrame *f = checked_cast<NonWithFrame *>(meta->env->getTopFrame());
a = pop();
(*f->slots)[slotIndex] = a;
a = top();
(*localFrame->slots)[slotIndex] = a;
}
break;
@ -271,7 +270,6 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
NonWithFrame *f = checked_cast<NonWithFrame *>(meta->env->getTopFrame());
// XXX some kind of code here?
}
break;
@ -280,8 +278,32 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
NonWithFrame *f = checked_cast<NonWithFrame *>(meta->env->getTopFrame());
push((*f->slots)[slotIndex]);
push((*localFrame->slots)[slotIndex]);
}
break;
case ePackageSlotWrite:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
a = top();
(*packageFrame->slots)[slotIndex] = a;
}
break;
case ePackageSlotDelete:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
// XXX some kind of code here?
}
break;
case ePackageSlotRead:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
push((*packageFrame->slots)[slotIndex]);
}
break;

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

@ -1154,10 +1154,9 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
NonWithFrame *f = checked_cast<NonWithFrame *>(meta->env->getTopFrame());
a = (*f->slots)[slotIndex];
a = (*localFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
(*f->slots)[slotIndex] = allocNumber(num + 1.0);
(*localFrame->slots)[slotIndex] = allocNumber(num + 1.0);
pushNumber(num);
}
break;
@ -1165,10 +1164,9 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
NonWithFrame *f = checked_cast<NonWithFrame *>(meta->env->getTopFrame());
a = (*f->slots)[slotIndex];
a = (*localFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
(*f->slots)[slotIndex] = allocNumber(num - 1.0);
(*localFrame->slots)[slotIndex] = allocNumber(num - 1.0);
pushNumber(num);
}
break;
@ -1176,21 +1174,60 @@
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
NonWithFrame *f = checked_cast<NonWithFrame *>(meta->env->getTopFrame());
a = (*f->slots)[slotIndex];
a = (*localFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
(*f->slots)[slotIndex] = a;
(*localFrame->slots)[slotIndex] = a;
}
break;
case eFrameSlotPreDec:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
NonWithFrame *f = checked_cast<NonWithFrame *>(meta->env->getTopFrame());
a = (*f->slots)[slotIndex];
a = (*localFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
(*f->slots)[slotIndex] = a;
(*localFrame->slots)[slotIndex] = a;
}
break;
case ePackageSlotPostInc:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
a = (*packageFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
(*packageFrame->slots)[slotIndex] = allocNumber(num + 1.0);
pushNumber(num);
}
break;
case ePackageSlotPostDec:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
a = (*packageFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
(*packageFrame->slots)[slotIndex] = allocNumber(num - 1.0);
pushNumber(num);
}
break;
case ePackageSlotPreInc:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
a = (*packageFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
a = pushNumber(num + 1.0);
(*packageFrame->slots)[slotIndex] = a;
}
break;
case ePackageSlotPreDec:
{
uint16 slotIndex = BytecodeContainer::getShort(pc);
pc += sizeof(short);
a = (*packageFrame->slots)[slotIndex];
float64 num = meta->toFloat64(a);
a = pushNumber(num - 1.0);
(*packageFrame->slots)[slotIndex] = a;
}
break;