From ceb54a7f92a4929722f38d11b145e7979adf8408 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Thu, 6 Jul 2000 18:26:26 +0000 Subject: [PATCH] Removed preprocess step, consolidated identifier handling. git-svn-id: svn://10.0.0.236/trunk@73767 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/js2/icodegenerator.cpp | 509 +++++++++++++--------------- mozilla/js/js2/icodegenerator.h | 122 +++---- mozilla/js/js2/interpreter.cpp | 10 +- mozilla/js/js2/js2.cpp | 12 +- mozilla/js/js2/jsclasses.h | 12 +- mozilla/js/js2/winbuild/js2.dsp | 4 + mozilla/js2/src/icodegenerator.cpp | 509 +++++++++++++--------------- mozilla/js2/src/icodegenerator.h | 122 +++---- mozilla/js2/src/interpreter.cpp | 10 +- mozilla/js2/src/jsclasses.h | 12 +- mozilla/js2/src/winbuild/js2.dsp | 4 + mozilla/js2/tests/cpp/js2_shell.cpp | 12 +- 12 files changed, 624 insertions(+), 714 deletions(-) diff --git a/mozilla/js/js2/icodegenerator.cpp b/mozilla/js/js2/icodegenerator.cpp index 9631ce579ba..8619e95eb94 100644 --- a/mozilla/js/js2/icodegenerator.cpp +++ b/mozilla/js/js2/icodegenerator.cpp @@ -66,11 +66,9 @@ Formatter& operator<<(Formatter &f, ICodeModule &i) ICodeGenerator::ICodeGenerator(World *world, JSScope *global, JSClass *aClass, ICodeGeneratorFlags flags) - : topRegister(0), - registerBase(0), - maxRegister(0), - parameterCount(0), - exceptionRegister(TypedRegister(NotARegister, &None_Type)), + : mTopRegister(0), + mParameterCount(0), + mExceptionRegister(TypedRegister(NotARegister, &None_Type)), variableList(new VariableList()), mWorld(world), mGlobal(global), @@ -90,20 +88,39 @@ JSType *ICodeGenerator::findType(const StringAtom& typeName) return &Any_Type; } +TypedRegister ICodeGenerator::allocateRegister(const StringAtom& name, JSType *type) +{ + Register r = mTopRegister; + while (r < mPermanentRegister.size()) + if (!mPermanentRegister[r]) + break; + else + ++r; + if (r == mPermanentRegister.size()) + mPermanentRegister.resize(r + 1); + mPermanentRegister[r] = true; + + TypedRegister result(r, type); + (*variableList)[name] = result; + mTopRegister = ++r; + return result; +} + + TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name, const StringAtom& typeName) { - if (exceptionRegister.first == NotARegister) { - exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); + if (mExceptionRegister.first == NotARegister) { + mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); } - return grabRegister(name, findType(typeName)); + return allocateRegister(name, findType(typeName)); } TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name) { - if (exceptionRegister.first == NotARegister) { - exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); + if (mExceptionRegister.first == NotARegister) { + mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); } - return grabRegister(name, &Any_Type); + return allocateRegister(name, &Any_Type); } ICodeModule *ICodeGenerator::complete() @@ -149,8 +166,7 @@ ICodeModule *ICodeGenerator::complete() } } */ - markMaxRegister(); - ICodeModule* module = new ICodeModule(iCode, variableList, maxRegister, 0, mInstructionMap); + ICodeModule* module = new ICodeModule(iCode, variableList, mPermanentRegister.size(), 0, mInstructionMap); iCodeOwner = false; // give ownership to the module. return module; } @@ -160,7 +176,7 @@ ICodeModule *ICodeGenerator::complete() TypedRegister ICodeGenerator::loadImmediate(double value) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); LoadImmediate *instr = new LoadImmediate(dest, value); iCode->push_back(instr); return dest; @@ -168,7 +184,7 @@ TypedRegister ICodeGenerator::loadImmediate(double value) TypedRegister ICodeGenerator::loadString(String &value) { - TypedRegister dest(getRegister(), &String_Type); + TypedRegister dest(getTempRegister(), &String_Type); LoadString *instr = new LoadString(dest, new JSString(value)); iCode->push_back(instr); return dest; @@ -176,7 +192,7 @@ TypedRegister ICodeGenerator::loadString(String &value) TypedRegister ICodeGenerator::loadString(const StringAtom &value) { - TypedRegister dest(getRegister(), &String_Type); + TypedRegister dest(getTempRegister(), &String_Type); LoadString *instr = new LoadString(dest, new JSString(value)); iCode->push_back(instr); return dest; @@ -184,7 +200,7 @@ TypedRegister ICodeGenerator::loadString(const StringAtom &value) TypedRegister ICodeGenerator::loadBoolean(bool value) { - TypedRegister dest(getRegister(), &Boolean_Type); + TypedRegister dest(getTempRegister(), &Boolean_Type); LoadBoolean *instr = new LoadBoolean(dest, value); iCode->push_back(instr); return dest; @@ -192,7 +208,7 @@ TypedRegister ICodeGenerator::loadBoolean(bool value) TypedRegister ICodeGenerator::newObject() { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); NewObject *instr = new NewObject(dest); iCode->push_back(instr); return dest; @@ -200,7 +216,7 @@ TypedRegister ICodeGenerator::newObject() TypedRegister ICodeGenerator::newClass(const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); NewClass *instr = new NewClass(dest, &name); iCode->push_back(instr); return dest; @@ -208,7 +224,7 @@ TypedRegister ICodeGenerator::newClass(const StringAtom &name) TypedRegister ICodeGenerator::newFunction(ICodeModule *icm) { - TypedRegister dest(getRegister(), &Function_Type); + TypedRegister dest(getTempRegister(), &Function_Type); NewFunction *instr = new NewFunction(dest, icm); iCode->push_back(instr); return dest; @@ -216,7 +232,7 @@ TypedRegister ICodeGenerator::newFunction(ICodeModule *icm) TypedRegister ICodeGenerator::newArray() { - TypedRegister dest(getRegister(), &Array_Type); + TypedRegister dest(getTempRegister(), &Array_Type); NewArray *instr = new NewArray(dest); iCode->push_back(instr); return dest; @@ -226,7 +242,7 @@ TypedRegister ICodeGenerator::newArray() TypedRegister ICodeGenerator::loadName(const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); LoadName *instr = new LoadName(dest, &name); iCode->push_back(instr); return dest; @@ -240,7 +256,7 @@ void ICodeGenerator::saveName(const StringAtom &name, TypedRegister value) TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); NameXcr *instr = new NameXcr(dest, &name, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -250,7 +266,7 @@ TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op) TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); VarXcr *instr = new VarXcr(dest, var, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -261,7 +277,7 @@ TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op) TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); DeleteProp *instr = new DeleteProp(dest, base, &name); iCode->push_back(instr); return dest; @@ -269,7 +285,7 @@ TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAto TypedRegister ICodeGenerator::getProperty(TypedRegister base, const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); GetProp *instr = new GetProp(dest, base, &name); iCode->push_back(instr); return dest; @@ -284,7 +300,7 @@ void ICodeGenerator::setProperty(TypedRegister base, const StringAtom &name, TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom &name, ICodeOp op) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); PropXcr *instr = new PropXcr(dest, base, &name, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -296,7 +312,7 @@ TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom & TypedRegister ICodeGenerator::getStatic(JSClass *base, const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); const JSSlot& slot = base->getStatic(name); GetStatic *instr = new GetStatic(dest, base, slot.mIndex); iCode->push_back(instr); @@ -313,7 +329,7 @@ void ICodeGenerator::setStatic(JSClass *base, const StringAtom &name, TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, ICodeOp op) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); const JSSlot& slot = base->getStatic(name); StaticXcr *instr = new StaticXcr(dest, base, slot.mIndex, 1.0); iCode->push_back(instr); @@ -325,7 +341,7 @@ TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, I TypedRegister ICodeGenerator::getSlot(TypedRegister base, uint32 slot) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); GetSlot *instr = new GetSlot(dest, base, slot); iCode->push_back(instr); return dest; @@ -340,7 +356,7 @@ void ICodeGenerator::setSlot(TypedRegister base, uint32 slot, TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp op) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); SlotXcr *instr = new SlotXcr(dest, base, slot, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -351,7 +367,7 @@ TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp o TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); GetElement *instr = new GetElement(dest, base, index); iCode->push_back(instr); return dest; @@ -366,7 +382,7 @@ void ICodeGenerator::setElement(TypedRegister base, TypedRegister index, TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index, ICodeOp op) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); ElemXcr *instr = new ElemXcr(dest, base, index, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -376,7 +392,7 @@ TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); ASSERT(source.first != NotARegister); Unary *instr = new Unary (op, dest, source); iCode->push_back(instr); @@ -394,7 +410,7 @@ void ICodeGenerator::move(TypedRegister destination, TypedRegister source) TypedRegister ICodeGenerator::logicalNot(TypedRegister source) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Not *instr = new Not(dest, source); iCode->push_back(instr); return dest; @@ -402,7 +418,7 @@ TypedRegister ICodeGenerator::logicalNot(TypedRegister source) TypedRegister ICodeGenerator::test(TypedRegister source) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Test *instr = new Test(dest, source); iCode->push_back(instr); return dest; @@ -413,7 +429,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1, { ASSERT(source1.first != NotARegister); ASSERT(source2.first != NotARegister); - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Arithmetic *instr = new Arithmetic(op, dest, source1, source2); iCode->push_back(instr); return dest; @@ -421,7 +437,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1, TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name, RegisterList args) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Call *instr = new Call(dest, target, &name, args); iCode->push_back(instr); return dest; @@ -429,7 +445,7 @@ TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name, TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister targetValue, RegisterList args) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); MethodCall *instr = new MethodCall(dest, targetBase, targetValue, args); iCode->push_back(instr); return dest; @@ -437,7 +453,7 @@ TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister TypedRegister ICodeGenerator::staticCall(JSClass *c, const StringAtom &name, RegisterList args) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); const JSSlot& slot = c->getStatic(name); StaticCall *instr = new StaticCall(dest, c, slot.mIndex, args); iCode->push_back(instr); @@ -618,46 +634,161 @@ static bool isSlotName(JSType *t, const StringAtom &name, uint32 &slotIndex, JST return false; } -TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args) + +ICodeGenerator::LValueKind ICodeGenerator::resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex) { - enum {Property, Slot, Static} lValueKind; - + if (!isWithinWith()) { + v = findVariable(name); + if (v.first != NotARegister) + return Var; + else { + if (mClass) { // we're compiling a method of a class + if (!isStaticMethod()) { + if (isSlotName(mClass, name, slotIndex, v.second)) + return Slot; + } + if (mClass->hasStatic(name, v.second)) { + return Static; + } + } + v.second = mGlobal->getType(name); + return Name; + } + } + v.second = &Any_Type; + return Name; +} + +TypedRegister ICodeGenerator::handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args) +{ + ASSERT(p->getKind() == ExprNode::identifier); + + JSType *vType = &Any_Type; + uint32 slotIndex; + TypedRegister ret; + TypedRegister v; + + const StringAtom &name = (static_cast(p))->name; + LValueKind lValueKind = resolveIdentifier(name, ret, slotIndex); + + TypedRegister thisBase = TypedRegister(0, mClass ? mClass : &Any_Type); + + switch (use) { + case ExprNode::identifier: + switch (lValueKind) { + case Var: + break; + case Name: + ret = loadName(name); + break; + case Slot: + ret = getSlot(thisBase, slotIndex); + break; + case Static: + ret = getStatic(mClass, name); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + case ExprNode::preDecrement: + case ExprNode::preIncrement: + switch (lValueKind) { + case Var: + ret = op(xcrementOp, ret, loadImmediate(1.0)); + break; + case Name: + ret = loadName(name); + ret = op(xcrementOp, ret, loadImmediate(1.0)); + saveName(name, ret); + break; + case Slot: + ret = op(xcrementOp, getSlot(thisBase, slotIndex), loadImmediate(1.0)); + setSlot(thisBase, slotIndex, ret); + break; + case Static: + ret = op(xcrementOp, getStatic(mClass, name), loadImmediate(1.0)); + setStatic(mClass, name, ret); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + case ExprNode::postDecrement: + case ExprNode::postIncrement: + switch (lValueKind) { + case Var: + ret = varXcr(ret, xcrementOp); + break; + case Name: + ret = nameXcr(name, xcrementOp); + break; + case Slot: + ret = slotXcr(thisBase, slotIndex, xcrementOp); + break; + case Static: + ret = staticXcr(mClass, name, xcrementOp); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + case ExprNode::call: + switch (lValueKind) { + case Var: + ret = call(ret, name, *args); + break; + case Name: + ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(name), *args); + break; + case Static: + ret = staticCall(mClass, name, *args); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + } + return ret; + +} + +TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args) +{ ASSERT(b->getKind() == ExprNode::dot); + LValueKind lValueKind; + if (b->op2->getKind() != ExprNode::identifier) { NOT_REACHED("Implement me"); // turns into a getProperty (but not via any overloaded [] ) } else { - const StringAtom &name = static_cast(b->op2)->name; + const StringAtom &fieldName = static_cast(b->op2)->name; TypedRegister base; - JSClass *c = NULL; + JSClass *clazz = NULL; JSType *fieldType = &Any_Type; uint32 slotIndex; if ((b->op1->getKind() == ExprNode::identifier) && !isWithinWith()) { const StringAtom &baseName = (static_cast(b->op1))->name; - JSType *baseType = &Any_Type; - base = findVariable(baseName); - - if (base.first != NotARegister) - baseType = base.second; - else { - // implicit 'this' has a big impact here - baseType = mGlobal->getType(baseName); - } + resolveIdentifier(baseName, base, slotIndex); + lValueKind = Property; - if (baseType == &Type_Type) { + // + // handle . + // + if (base.second == &Type_Type) { const JSValue &v = mGlobal->getVariable(baseName); - c = dynamic_cast(v.type); - if (c && c->hasStatic(name, fieldType)) { + clazz = dynamic_cast(v.type); + if (clazz && clazz->hasStatic(fieldName, fieldType)) { lValueKind = Static; } } if (lValueKind == Property) { - if (isSlotName(baseType, name, slotIndex, fieldType)) + if (isSlotName(base.second, fieldName, slotIndex, fieldType)) lValueKind = Slot; else { - c = dynamic_cast(baseType); - if (c && c->hasStatic(name, fieldType)) + clazz = dynamic_cast(base.second); + if (clazz && clazz->hasStatic(fieldName, fieldType)) lValueKind = Static; else lValueKind = Property; @@ -668,11 +799,11 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I } else { base = genExpr(b->op1); - if (isSlotName(base.second, name, slotIndex, fieldType)) + if (isSlotName(base.second, fieldName, slotIndex, fieldType)) lValueKind = Slot; else { - c = dynamic_cast(base.second); - if (c && c->hasStatic(name, fieldType)) + clazz = dynamic_cast(base.second); + if (clazz && clazz->hasStatic(fieldName, fieldType)) lValueKind = Static; else lValueKind = Property; @@ -683,10 +814,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::call: switch (lValueKind) { case Static: - ret = staticCall(c, name, *args); + ret = staticCall(clazz, fieldName, *args); break; case Property: - ret = methodCall(base, loadString(name), *args); + ret = methodCall(base, loadString(fieldName), *args); break; default: NOT_REACHED("Bad lvalue kind"); @@ -706,10 +837,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::bitwiseOrEquals: switch (lValueKind) { case Static: - v = getStatic(c, name); + v = getStatic(clazz, fieldName); break; case Property: - v = getProperty(base, name); + v = getProperty(base, fieldName); break; case Slot: v = getSlot(base, slotIndex); @@ -726,10 +857,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::assignment: switch (lValueKind) { case Static: - setStatic(c, name, ret); + setStatic(clazz, fieldName, ret); break; case Property: - setProperty(base, name, ret); + setProperty(base, fieldName, ret); break; case Slot: setSlot(base, slotIndex, ret); @@ -742,10 +873,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::postIncrement: switch (lValueKind) { case Static: - ret = staticXcr(c, name, xcrementOp); + ret = staticXcr(clazz, fieldName, xcrementOp); break; case Property: - ret = propertyXcr(base, name, xcrementOp); + ret = propertyXcr(base, fieldName, xcrementOp); break; case Slot: ret = slotXcr(base, slotIndex, xcrementOp); @@ -757,12 +888,12 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::preIncrement: switch (lValueKind) { case Static: - ret = op(xcrementOp, getStatic(c, name), loadImmediate(1.0)); - setStatic(c, name, ret); + ret = op(xcrementOp, getStatic(clazz, fieldName), loadImmediate(1.0)); + setStatic(clazz, fieldName, ret); break; case Property: - ret = op(xcrementOp, getProperty(base, name), loadImmediate(1.0)); - setProperty(base, name, ret); + ret = op(xcrementOp, getProperty(base, fieldName), loadImmediate(1.0)); + setProperty(base, fieldName, ret); break; case Slot: ret = op(xcrementOp, getSlot(base, slotIndex), loadImmediate(1.0)); @@ -774,7 +905,7 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I break; case ExprNode::Delete: if (lValueKind == Property) { - ret = deleteProperty(base, name); + ret = deleteProperty(base, fieldName); } break; default: @@ -857,34 +988,10 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, if (i->op->getKind() == ExprNode::dot) { BinaryExprNode *b = static_cast(i->op); ret = handleDot(b, ExprNode::call, xcrementOp, ret, &args); -/* - TypedRegister base = genExpr(b->op1); - // might be Class.() - const StringAtom &name = static_cast(b->op2)->name; - if ((base.second == &Type_Type) - && (b->op1->getKind() == ExprNode::identifier)) { - const StringAtom &className = (static_cast(b->op1))->name; - const JSValue &v = mGlobal->getVariable(className); - JSClass* c = dynamic_cast(v.type); - if (c && c->hasStatic(name)) { - ret = staticCall(c, name, args); - break; - } - } - ret = methodCall(base, loadString(name), args); -*/ } else if (i->op->getKind() == ExprNode::identifier) { - if (!isWithinWith()) { - TypedRegister v = findVariable((static_cast(i->op))->name); - if (v.first != NotARegister) - ret = call(v, static_cast(i->op)->name, args); - else - ret = call(TypedRegister(NotARegister, &Null_Type), static_cast(i->op)->name, args); - } - else - ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(static_cast(i->op)->name), args); + ret = handleIdentifier(static_cast(i->op), ExprNode::call, xcrementOp, &args); } else if (i->op->getKind() == ExprNode::index) { @@ -916,34 +1023,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, break; case ExprNode::identifier : { - const StringAtom &name = (static_cast(p))->name; - if (!isWithinWith()) { - TypedRegister v = findVariable(name); - if (v.first != NotARegister) - ret = v; - else { - if (mClass) { // we're compiling a method of a class - JSType *fieldType; - if (!isStaticMethod()) { - uint32 slotIndex; - if (isSlotName(mClass, name, slotIndex, fieldType)) { - ret = getSlot(TypedRegister(0, mClass), slotIndex); - ret.second = fieldType; - break; - } - } - if (mClass->hasStatic(name, fieldType)) { - ret = getStatic(mClass, name); - ret.second = fieldType; - break; - } - } - ret = loadName(name); - ret.second = mGlobal->getType(name); - } - } - else - ret = loadName(name); + ret = handleIdentifier(static_cast(p), ExprNode::identifier, xcrementOp, NULL); } break; case ExprNode::number : @@ -958,26 +1038,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, { UnaryExprNode *u = static_cast(p); if (u->op->getKind() == ExprNode::dot) { - BinaryExprNode *b = static_cast(u->op); - ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL); + ret = handleDot(static_cast(u->op), p->getKind(), xcrementOp, ret, NULL); } else if (u->op->getKind() == ExprNode::identifier) { - if (!isWithinWith()) { - TypedRegister v = findVariable((static_cast(u->op))->name); - if (v.first != NotARegister) - ret = op(xcrementOp, ret, loadImmediate(1.0)); - else { - ret = loadName((static_cast(u->op))->name); - ret = op(xcrementOp, ret, loadImmediate(1.0)); - saveName((static_cast(u->op))->name, ret); - } - } - else { - ret = loadName((static_cast(u->op))->name); - ret = op(xcrementOp, ret, loadImmediate(1.0)); - saveName((static_cast(u->op))->name, ret); - } + ret = handleIdentifier(static_cast(u->op), p->getKind(), xcrementOp, NULL); } else if (u->op->getKind() == ExprNode::index) { @@ -998,20 +1063,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, { UnaryExprNode *u = static_cast(p); if (u->op->getKind() == ExprNode::dot) { - BinaryExprNode *b = static_cast(u->op); - ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL); + ret = handleDot(static_cast(u->op), p->getKind(), xcrementOp, ret, NULL); } else if (u->op->getKind() == ExprNode::identifier) { - if (!isWithinWith()) { - TypedRegister v = findVariable((static_cast(u->op))->name); - if (v.first != NotARegister) - ret = varXcr(v, xcrementOp); - else - ret = nameXcr((static_cast(u->op))->name, xcrementOp); - } - else - ret = nameXcr((static_cast(u->op))->name, xcrementOp); + ret = handleIdentifier(static_cast(u->op), p->getKind(), xcrementOp, NULL); } else if (u->op->getKind() == ExprNode::index) { @@ -1291,7 +1347,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, icg.allocateParameter((static_cast(v->name))->name); v = v->next; } - icg.preprocess(f->function.body); icg.genStmt(f->function.body); //stdOut << icg; ICodeModule *icm = icg.complete(); @@ -1325,116 +1380,6 @@ bool LabelEntry::containsLabel(const StringAtom *label) return false; } -void ICodeGenerator::preprocess(StmtNode *p) -{ - switch (p->getKind()) { - case StmtNode::block: - { - BlockStmtNode *b = static_cast(p); - StmtNode *s = b->statements; - while (s) { - preprocess(s); - s = s->next; - } - } - break; - case StmtNode::Var: - { - VariableStmtNode *vs = static_cast(p); - VariableBinding *v = vs->bindings; - while (v) { - if (v->name && (v->name->getKind() == ExprNode::identifier)) - if (v->type && (v->type->getKind() == ExprNode::identifier)) - if (isTopLevel()) - mGlobal->defineVariable((static_cast(v->name))->name, - findType((static_cast(v->type))->name)); - else - allocateVariable((static_cast(v->name))->name, - (static_cast(v->type))->name); - else - allocateVariable((static_cast(v->name))->name); - v = v->next; - } - } - break; - case StmtNode::DoWhile: - { - UnaryStmtNode *d = static_cast(p); - preprocess(d->stmt); - } - break; - case StmtNode::While: - { - UnaryStmtNode *w = static_cast(p); - preprocess(w->stmt); - } - break; - case StmtNode::For: - { - ForStmtNode *f = static_cast(p); - if (f->initializer) - preprocess(f->initializer); - preprocess(f->stmt); - } - break; - case StmtNode::If: - { - UnaryStmtNode *i = static_cast(p); - preprocess(i->stmt); - } - break; - case StmtNode::IfElse: - { - BinaryStmtNode *i = static_cast(p); - preprocess(i->stmt); - preprocess(i->stmt2); - } - break; - case StmtNode::With: - { - UnaryStmtNode *w = static_cast(p); - preprocess(w->stmt); - } - break; - case StmtNode::Switch: - { - SwitchStmtNode *sw = static_cast(p); - StmtNode *s = sw->statements; - while (s) { - if (s->getKind() != StmtNode::Case) - preprocess(s); - s = s->next; - } - } - break; - case StmtNode::label: - { - LabelStmtNode *l = static_cast(p); - preprocess(l->stmt); - } - break; - case StmtNode::Try: - { - TryStmtNode *t = static_cast(p); - genStmt(t->stmt); - if (t->catches) { - CatchClause *c = t->catches; - while (c) { - preprocess(c->stmt); - c = c->next; - } - } - if (t->finally) - genStmt(t->finally); - } - break; - - default: - break; - - } -} - static bool hasAttribute(const IdentifierList* identifiers, Token::Kind tokenKind) { while (identifiers) { @@ -1458,7 +1403,6 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f) icg.allocateParameter((static_cast(v->name))->name); v = v->next; } - icg.preprocess(f->function.body); icg.genStmt(f->function.body); return icg.complete(); @@ -1469,8 +1413,8 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) TypedRegister ret(NotARegister, &None_Type); startStatement(p->pos); - if (exceptionRegister.first == NotARegister) { - exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); + if (mExceptionRegister.first == NotARegister) { + mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); } switch (p->getKind()) { @@ -1565,7 +1509,7 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) // freeze the class. thisClass->complete(); if (ccg.getICode()->size()) - thisClass->setConstructor(ccg.complete()); + thisClass->setInitializer(ccg.complete()); // REVISIT: using the scope of the class to store both methods and statics. if (scg.getICode()->size()) { Interpreter::Context cx(*mWorld, thisScope); @@ -1591,8 +1535,18 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) VariableStmtNode *vs = static_cast(p); VariableBinding *v = vs->bindings; while (v) { - if (v->name && v->initializer) { - if (v->name->getKind() == ExprNode::identifier) { + if (v->name && (v->name->getKind() == ExprNode::identifier)) { + if (v->type && (v->type->getKind() == ExprNode::identifier)) { + if (isTopLevel()) + mGlobal->defineVariable((static_cast(v->name))->name, + findType((static_cast(v->type))->name)); + else + allocateVariable((static_cast(v->name))->name, + (static_cast(v->type))->name); + } + else + allocateVariable((static_cast(v->name))->name); + if (v->initializer) { if (!isTopLevel() && !isWithinWith()) { TypedRegister r = genExpr(v->name); TypedRegister val = genExpr(v->initializer); @@ -1603,7 +1557,6 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) saveName((static_cast(v->name))->name, val); } } - // XXX what's the else case here, when does a VariableBinding NOT have an identifier child? } v = v->next; } @@ -1889,19 +1842,19 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) CatchClause *c = t->catches; while (c) { // Bind the incoming exception ... - setRegisterForVariable(c->name, exceptionRegister); + setRegisterForVariable(c->name, mExceptionRegister); genStmt(c->stmt); if (finallyLabel) jsr(finallyLabel); - throwStmt(exceptionRegister); + throwStmt(mExceptionRegister); c = c->next; } } if (finallyLabel) { setLabel(finallyInvoker); jsr(finallyLabel); - throwStmt(exceptionRegister); + throwStmt(mExceptionRegister); setLabel(finallyLabel); genStmt(t->finally); diff --git a/mozilla/js/js2/icodegenerator.h b/mozilla/js/js2/icodegenerator.h index 37aa42d3631..7d2ee1e4bce 100644 --- a/mozilla/js/js2/icodegenerator.h +++ b/mozilla/js/js2/icodegenerator.h @@ -118,69 +118,70 @@ namespace ICG { bool iCodeOwner; LabelList labels; - Register topRegister; // highest (currently) alloacated register - Register registerBase; // start of registers available for expression temps - uint32 maxRegister; // highest (ever) allocated register - uint32 parameterCount; // number of parameters declared for the function - // these must come before any variables declared. - TypedRegister exceptionRegister;// reserved to carry the exception object. - VariableList *variableList; // name|register pair for each variable + Register mTopRegister; // highest (currently) alloacated register + uint32 mParameterCount; // number of parameters declared for the function + // these must come before any variables declared. + TypedRegister mExceptionRegister; // reserved to carry the exception object. + VariableList *variableList; // name|register pair for each variable - World *mWorld; // used to register strings - JSScope *mGlobal; // the scope for compiling within - LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct - // maps source position to instruction index + World *mWorld; // used to register strings + JSScope *mGlobal; // the scope for compiling within + LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct + // maps source position to instruction index InstructionMap *mInstructionMap; - JSClass *mClass; // enclosing class when generating code for methods - ICodeGeneratorFlags mFlags; // assorted flags + JSClass *mClass; // enclosing class when generating code for methods + ICodeGeneratorFlags mFlags; // assorted flags + + std::vector mPermanentRegister; + + Register getTempRegister() + { + while (mTopRegister < mPermanentRegister.size()) + if (!mPermanentRegister[mTopRegister]) + return mTopRegister++; + else + ++mTopRegister; + mPermanentRegister.resize(mTopRegister + 1); + mPermanentRegister[mTopRegister] = false; + return mTopRegister++; + } + + void resetTopRegister() { mTopRegister = mParameterCount; } + void resetStatement() { resetTopRegister(); } + + TypedRegister allocateRegister(const StringAtom& name, JSType *type); + + void setRegisterForVariable(const StringAtom& name, TypedRegister r) { (*variableList)[name] = r; } + + JSType *findType(const StringAtom& typeName); + + + - void markMaxRegister() - { if (topRegister > maxRegister) maxRegister = topRegister; } - - Register getRegister() - { return topRegister++; } - void resetTopRegister() - { markMaxRegister(); topRegister = registerBase; } - void setLabel(Label *label); - void jsr(Label *label) { iCode->push_back(new Jsr(label)); } - void rts() { iCode->push_back(new Rts()); } + void jsr(Label *label) { iCode->push_back(new Jsr(label)); } + void rts() { iCode->push_back(new Rts()); } void branch(Label *label); GenericBranch *branchTrue(Label *label, TypedRegister condition); GenericBranch *branchFalse(Label *label, TypedRegister condition); void beginTry(Label *catchLabel, Label *finallyLabel) - { iCode->push_back(new Tryin(catchLabel, finallyLabel)); } - void endTry() - { iCode->push_back(new Tryout()); } + { iCode->push_back(new Tryin(catchLabel, finallyLabel)); } + void endTry() { iCode->push_back(new Tryout()); } - void beginWith(TypedRegister obj) - { iCode->push_back(new Within(obj)); } - void endWith() - { iCode->push_back(new Without()); } + void beginWith(TypedRegister obj) { iCode->push_back(new Within(obj)); } + void endWith() { iCode->push_back(new Without()); } - void resetStatement() { resetTopRegister(); } - void setRegisterForVariable(const StringAtom& name, TypedRegister r) - { (*variableList)[name] = r; } - void startStatement(uint32 pos) - { (*mInstructionMap)[iCode->size()] = pos; } + void startStatement(uint32 pos) { (*mInstructionMap)[iCode->size()] = pos; } ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind); - TypedRegister grabRegister(const StringAtom& name, JSType *type) - { - TypedRegister result(getRegister(), type); - (*variableList)[name] = result; - registerBase = topRegister; - return result; - } - bool isTopLevel() { return (mFlags & kIsTopLevel) != 0; } bool isWithinWith() { return (mFlags & kIsWithinWith) != 0; } @@ -188,7 +189,11 @@ namespace ICG { void setFlag(uint32 flag, bool v) { mFlags = (ICodeGeneratorFlags)((v) ? mFlags | flag : mFlags & ~flag); } - JSType *findType(const StringAtom& typeName); + + typedef enum {Var, Property, Slot, Static, Name} LValueKind; + + LValueKind resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex); + TypedRegister handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args); TypedRegister handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args); ICodeModule *genFunction(FunctionStmtNode *f); @@ -207,32 +212,30 @@ namespace ICG { ICodeModule *complete(); TypedRegister genExpr(ExprNode *p, - bool needBoolValueInBranch = false, - Label *trueBranch = NULL, - Label *falseBranch = NULL); - void preprocess(StmtNode *p); + bool needBoolValueInBranch = false, + Label *trueBranch = NULL, + Label *falseBranch = NULL); TypedRegister genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL); void returnStmt(TypedRegister r); void returnStmt(); - void throwStmt(TypedRegister r) - { iCode->push_back(new Throw(r)); } - void debuggerStmt() - { iCode->push_back(new Debugger()); } + void throwStmt(TypedRegister r) { iCode->push_back(new Throw(r)); } + void debuggerStmt() { iCode->push_back(new Debugger()); } TypedRegister allocateVariable(const StringAtom& name); TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName); TypedRegister findVariable(const StringAtom& name) - { VariableList::iterator i = variableList->find(name); - return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; } + { + VariableList::iterator i = variableList->find(name); + return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; + } - TypedRegister allocateParameter(const StringAtom& name) - { parameterCount++; return grabRegister(name, &Any_Type); } + TypedRegister allocateParameter(const StringAtom& name) { mParameterCount++; return allocateRegister(name, &Any_Type); } TypedRegister allocateParameter(const StringAtom& name, const StringAtom& typeName) - { parameterCount++; return grabRegister(name, findType(typeName)); } + { mParameterCount++; return allocateRegister(name, findType(typeName)); } TypedRegister allocateParameter(const StringAtom& name, JSType *type) - { parameterCount++; return grabRegister(name, type); } + { mParameterCount++; return allocateRegister(name, type); } Formatter& print(Formatter& f); @@ -279,8 +282,7 @@ namespace ICG { TypedRegister varXcr(TypedRegister var, ICodeOp op); - Register getRegisterBase() { return topRegister; } - InstructionStream *getICode() { return iCode; } + InstructionStream *getICode() { return iCode; } Label *getLabel(); diff --git a/mozilla/js/js2/interpreter.cpp b/mozilla/js/js2/interpreter.cpp index 2deb21774f4..6e68b2e2b94 100644 --- a/mozilla/js/js2/interpreter.cpp +++ b/mozilla/js/js2/interpreter.cpp @@ -679,14 +679,14 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) InstructionIterator nextPC = ++mPC; do { // call the constructor(s), if any. - ICodeModule* ctor = thisClass->getConstructor(); - if (ctor) { + ICodeModule* init = thisClass->getInitializer(); + if (init) { mLinkage = new Linkage(mLinkage, nextPC, mActivation, mGlobal, voidRegister); - mActivation = new Activation(ctor, args); + mActivation = new Activation(init, args); registers = &mActivation->mRegisters; - nextPC = ctor->its_iCode->begin(); - endPC = ctor->its_iCode->end(); + nextPC = init->its_iCode->begin(); + endPC = init->its_iCode->end(); } thisClass = thisClass->getSuperClass(); } while (thisClass); diff --git a/mozilla/js/js2/js2.cpp b/mozilla/js/js2/js2.cpp index f83a84e8fdb..b1c74c29098 100644 --- a/mozilla/js/js2/js2.cpp +++ b/mozilla/js/js2/js2.cpp @@ -147,7 +147,6 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName) TypedRegister ret(NotARegister, &None_Type); while (p) { - icg.preprocess(p); ret = icg.genStmt(p); p = p->next; } @@ -155,7 +154,7 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName) ICodeModule *icm = icg.complete(); -//stdOut << icg; +stdOut << icg; icm->setFileName (fileName); return icm; @@ -344,7 +343,8 @@ class Tracer : public Context::Listener { char * tests[] = { "function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" , - "a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" + "a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" , + "class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s()); print(A.b); return;" }; static void testCompile() @@ -361,15 +361,11 @@ static void testCompile() StmtNode *parsedStatements = p.parseProgram(); ICodeGenerator icg(&world, &glob); StmtNode *s = parsedStatements; - while (s) { - icg.preprocess(s); - s = s->next; - } - s = parsedStatements; while (s) { icg.genStmt(s); s = s->next; } +// stdOut << icg; cx.interpret(icg.complete(), JSValues()); } } diff --git a/mozilla/js/js2/jsclasses.h b/mozilla/js/js2/jsclasses.h index 0cda4d81290..c32bbe16977 100644 --- a/mozilla/js/js2/jsclasses.h +++ b/mozilla/js/js2/jsclasses.h @@ -79,7 +79,7 @@ namespace JSClasses { uint32 mStaticCount; JSSlots mStaticSlots; JSValue* mStaticData; - ICodeModule* mConstructor; + ICodeModule* mInitializer; // typedef std::vector > JSMethods; // JSMethods mMethods; public: @@ -89,7 +89,7 @@ namespace JSClasses { mSlotCount(superClass ? superClass->mSlotCount : 0), mStaticCount(0), mStaticData(0), - mConstructor(0) + mInitializer(0) { // to "inherit" superClass methods. if (superClass) @@ -106,14 +106,14 @@ namespace JSClasses { return mScope; } - void setConstructor(ICodeModule* ctor) + void setInitializer(ICodeModule* init) { - mConstructor = ctor; + mInitializer = init; } - ICodeModule* getConstructor() + ICodeModule* getInitializer() { - return mConstructor; + return mInitializer; } const JSSlot& defineSlot(const String& name, JSType* type) diff --git a/mozilla/js/js2/winbuild/js2.dsp b/mozilla/js/js2/winbuild/js2.dsp index ba72d60c459..da1371d3f10 100644 --- a/mozilla/js/js2/winbuild/js2.dsp +++ b/mozilla/js/js2/winbuild/js2.dsp @@ -175,6 +175,10 @@ SOURCE=..\hash.h # End Source File # Begin Source File +SOURCE=..\icode.h +# End Source File +# Begin Source File + SOURCE=..\icodegenerator.h # End Source File # Begin Source File diff --git a/mozilla/js2/src/icodegenerator.cpp b/mozilla/js2/src/icodegenerator.cpp index 9631ce579ba..8619e95eb94 100644 --- a/mozilla/js2/src/icodegenerator.cpp +++ b/mozilla/js2/src/icodegenerator.cpp @@ -66,11 +66,9 @@ Formatter& operator<<(Formatter &f, ICodeModule &i) ICodeGenerator::ICodeGenerator(World *world, JSScope *global, JSClass *aClass, ICodeGeneratorFlags flags) - : topRegister(0), - registerBase(0), - maxRegister(0), - parameterCount(0), - exceptionRegister(TypedRegister(NotARegister, &None_Type)), + : mTopRegister(0), + mParameterCount(0), + mExceptionRegister(TypedRegister(NotARegister, &None_Type)), variableList(new VariableList()), mWorld(world), mGlobal(global), @@ -90,20 +88,39 @@ JSType *ICodeGenerator::findType(const StringAtom& typeName) return &Any_Type; } +TypedRegister ICodeGenerator::allocateRegister(const StringAtom& name, JSType *type) +{ + Register r = mTopRegister; + while (r < mPermanentRegister.size()) + if (!mPermanentRegister[r]) + break; + else + ++r; + if (r == mPermanentRegister.size()) + mPermanentRegister.resize(r + 1); + mPermanentRegister[r] = true; + + TypedRegister result(r, type); + (*variableList)[name] = result; + mTopRegister = ++r; + return result; +} + + TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name, const StringAtom& typeName) { - if (exceptionRegister.first == NotARegister) { - exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); + if (mExceptionRegister.first == NotARegister) { + mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); } - return grabRegister(name, findType(typeName)); + return allocateRegister(name, findType(typeName)); } TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name) { - if (exceptionRegister.first == NotARegister) { - exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); + if (mExceptionRegister.first == NotARegister) { + mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); } - return grabRegister(name, &Any_Type); + return allocateRegister(name, &Any_Type); } ICodeModule *ICodeGenerator::complete() @@ -149,8 +166,7 @@ ICodeModule *ICodeGenerator::complete() } } */ - markMaxRegister(); - ICodeModule* module = new ICodeModule(iCode, variableList, maxRegister, 0, mInstructionMap); + ICodeModule* module = new ICodeModule(iCode, variableList, mPermanentRegister.size(), 0, mInstructionMap); iCodeOwner = false; // give ownership to the module. return module; } @@ -160,7 +176,7 @@ ICodeModule *ICodeGenerator::complete() TypedRegister ICodeGenerator::loadImmediate(double value) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); LoadImmediate *instr = new LoadImmediate(dest, value); iCode->push_back(instr); return dest; @@ -168,7 +184,7 @@ TypedRegister ICodeGenerator::loadImmediate(double value) TypedRegister ICodeGenerator::loadString(String &value) { - TypedRegister dest(getRegister(), &String_Type); + TypedRegister dest(getTempRegister(), &String_Type); LoadString *instr = new LoadString(dest, new JSString(value)); iCode->push_back(instr); return dest; @@ -176,7 +192,7 @@ TypedRegister ICodeGenerator::loadString(String &value) TypedRegister ICodeGenerator::loadString(const StringAtom &value) { - TypedRegister dest(getRegister(), &String_Type); + TypedRegister dest(getTempRegister(), &String_Type); LoadString *instr = new LoadString(dest, new JSString(value)); iCode->push_back(instr); return dest; @@ -184,7 +200,7 @@ TypedRegister ICodeGenerator::loadString(const StringAtom &value) TypedRegister ICodeGenerator::loadBoolean(bool value) { - TypedRegister dest(getRegister(), &Boolean_Type); + TypedRegister dest(getTempRegister(), &Boolean_Type); LoadBoolean *instr = new LoadBoolean(dest, value); iCode->push_back(instr); return dest; @@ -192,7 +208,7 @@ TypedRegister ICodeGenerator::loadBoolean(bool value) TypedRegister ICodeGenerator::newObject() { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); NewObject *instr = new NewObject(dest); iCode->push_back(instr); return dest; @@ -200,7 +216,7 @@ TypedRegister ICodeGenerator::newObject() TypedRegister ICodeGenerator::newClass(const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); NewClass *instr = new NewClass(dest, &name); iCode->push_back(instr); return dest; @@ -208,7 +224,7 @@ TypedRegister ICodeGenerator::newClass(const StringAtom &name) TypedRegister ICodeGenerator::newFunction(ICodeModule *icm) { - TypedRegister dest(getRegister(), &Function_Type); + TypedRegister dest(getTempRegister(), &Function_Type); NewFunction *instr = new NewFunction(dest, icm); iCode->push_back(instr); return dest; @@ -216,7 +232,7 @@ TypedRegister ICodeGenerator::newFunction(ICodeModule *icm) TypedRegister ICodeGenerator::newArray() { - TypedRegister dest(getRegister(), &Array_Type); + TypedRegister dest(getTempRegister(), &Array_Type); NewArray *instr = new NewArray(dest); iCode->push_back(instr); return dest; @@ -226,7 +242,7 @@ TypedRegister ICodeGenerator::newArray() TypedRegister ICodeGenerator::loadName(const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); LoadName *instr = new LoadName(dest, &name); iCode->push_back(instr); return dest; @@ -240,7 +256,7 @@ void ICodeGenerator::saveName(const StringAtom &name, TypedRegister value) TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); NameXcr *instr = new NameXcr(dest, &name, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -250,7 +266,7 @@ TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op) TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); VarXcr *instr = new VarXcr(dest, var, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -261,7 +277,7 @@ TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op) TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); DeleteProp *instr = new DeleteProp(dest, base, &name); iCode->push_back(instr); return dest; @@ -269,7 +285,7 @@ TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAto TypedRegister ICodeGenerator::getProperty(TypedRegister base, const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); GetProp *instr = new GetProp(dest, base, &name); iCode->push_back(instr); return dest; @@ -284,7 +300,7 @@ void ICodeGenerator::setProperty(TypedRegister base, const StringAtom &name, TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom &name, ICodeOp op) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); PropXcr *instr = new PropXcr(dest, base, &name, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -296,7 +312,7 @@ TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom & TypedRegister ICodeGenerator::getStatic(JSClass *base, const StringAtom &name) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); const JSSlot& slot = base->getStatic(name); GetStatic *instr = new GetStatic(dest, base, slot.mIndex); iCode->push_back(instr); @@ -313,7 +329,7 @@ void ICodeGenerator::setStatic(JSClass *base, const StringAtom &name, TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, ICodeOp op) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); const JSSlot& slot = base->getStatic(name); StaticXcr *instr = new StaticXcr(dest, base, slot.mIndex, 1.0); iCode->push_back(instr); @@ -325,7 +341,7 @@ TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, I TypedRegister ICodeGenerator::getSlot(TypedRegister base, uint32 slot) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); GetSlot *instr = new GetSlot(dest, base, slot); iCode->push_back(instr); return dest; @@ -340,7 +356,7 @@ void ICodeGenerator::setSlot(TypedRegister base, uint32 slot, TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp op) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); SlotXcr *instr = new SlotXcr(dest, base, slot, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -351,7 +367,7 @@ TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp o TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); GetElement *instr = new GetElement(dest, base, index); iCode->push_back(instr); return dest; @@ -366,7 +382,7 @@ void ICodeGenerator::setElement(TypedRegister base, TypedRegister index, TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index, ICodeOp op) { - TypedRegister dest(getRegister(), &Number_Type); + TypedRegister dest(getTempRegister(), &Number_Type); ElemXcr *instr = new ElemXcr(dest, base, index, (op == ADD) ? 1.0 : -1.0); iCode->push_back(instr); return dest; @@ -376,7 +392,7 @@ TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); ASSERT(source.first != NotARegister); Unary *instr = new Unary (op, dest, source); iCode->push_back(instr); @@ -394,7 +410,7 @@ void ICodeGenerator::move(TypedRegister destination, TypedRegister source) TypedRegister ICodeGenerator::logicalNot(TypedRegister source) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Not *instr = new Not(dest, source); iCode->push_back(instr); return dest; @@ -402,7 +418,7 @@ TypedRegister ICodeGenerator::logicalNot(TypedRegister source) TypedRegister ICodeGenerator::test(TypedRegister source) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Test *instr = new Test(dest, source); iCode->push_back(instr); return dest; @@ -413,7 +429,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1, { ASSERT(source1.first != NotARegister); ASSERT(source2.first != NotARegister); - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Arithmetic *instr = new Arithmetic(op, dest, source1, source2); iCode->push_back(instr); return dest; @@ -421,7 +437,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1, TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name, RegisterList args) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); Call *instr = new Call(dest, target, &name, args); iCode->push_back(instr); return dest; @@ -429,7 +445,7 @@ TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name, TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister targetValue, RegisterList args) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); MethodCall *instr = new MethodCall(dest, targetBase, targetValue, args); iCode->push_back(instr); return dest; @@ -437,7 +453,7 @@ TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister TypedRegister ICodeGenerator::staticCall(JSClass *c, const StringAtom &name, RegisterList args) { - TypedRegister dest(getRegister(), &Any_Type); + TypedRegister dest(getTempRegister(), &Any_Type); const JSSlot& slot = c->getStatic(name); StaticCall *instr = new StaticCall(dest, c, slot.mIndex, args); iCode->push_back(instr); @@ -618,46 +634,161 @@ static bool isSlotName(JSType *t, const StringAtom &name, uint32 &slotIndex, JST return false; } -TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args) + +ICodeGenerator::LValueKind ICodeGenerator::resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex) { - enum {Property, Slot, Static} lValueKind; - + if (!isWithinWith()) { + v = findVariable(name); + if (v.first != NotARegister) + return Var; + else { + if (mClass) { // we're compiling a method of a class + if (!isStaticMethod()) { + if (isSlotName(mClass, name, slotIndex, v.second)) + return Slot; + } + if (mClass->hasStatic(name, v.second)) { + return Static; + } + } + v.second = mGlobal->getType(name); + return Name; + } + } + v.second = &Any_Type; + return Name; +} + +TypedRegister ICodeGenerator::handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args) +{ + ASSERT(p->getKind() == ExprNode::identifier); + + JSType *vType = &Any_Type; + uint32 slotIndex; + TypedRegister ret; + TypedRegister v; + + const StringAtom &name = (static_cast(p))->name; + LValueKind lValueKind = resolveIdentifier(name, ret, slotIndex); + + TypedRegister thisBase = TypedRegister(0, mClass ? mClass : &Any_Type); + + switch (use) { + case ExprNode::identifier: + switch (lValueKind) { + case Var: + break; + case Name: + ret = loadName(name); + break; + case Slot: + ret = getSlot(thisBase, slotIndex); + break; + case Static: + ret = getStatic(mClass, name); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + case ExprNode::preDecrement: + case ExprNode::preIncrement: + switch (lValueKind) { + case Var: + ret = op(xcrementOp, ret, loadImmediate(1.0)); + break; + case Name: + ret = loadName(name); + ret = op(xcrementOp, ret, loadImmediate(1.0)); + saveName(name, ret); + break; + case Slot: + ret = op(xcrementOp, getSlot(thisBase, slotIndex), loadImmediate(1.0)); + setSlot(thisBase, slotIndex, ret); + break; + case Static: + ret = op(xcrementOp, getStatic(mClass, name), loadImmediate(1.0)); + setStatic(mClass, name, ret); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + case ExprNode::postDecrement: + case ExprNode::postIncrement: + switch (lValueKind) { + case Var: + ret = varXcr(ret, xcrementOp); + break; + case Name: + ret = nameXcr(name, xcrementOp); + break; + case Slot: + ret = slotXcr(thisBase, slotIndex, xcrementOp); + break; + case Static: + ret = staticXcr(mClass, name, xcrementOp); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + case ExprNode::call: + switch (lValueKind) { + case Var: + ret = call(ret, name, *args); + break; + case Name: + ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(name), *args); + break; + case Static: + ret = staticCall(mClass, name, *args); + break; + default: + NOT_REACHED("Bad lvalue kind"); + } + break; + } + return ret; + +} + +TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args) +{ ASSERT(b->getKind() == ExprNode::dot); + LValueKind lValueKind; + if (b->op2->getKind() != ExprNode::identifier) { NOT_REACHED("Implement me"); // turns into a getProperty (but not via any overloaded [] ) } else { - const StringAtom &name = static_cast(b->op2)->name; + const StringAtom &fieldName = static_cast(b->op2)->name; TypedRegister base; - JSClass *c = NULL; + JSClass *clazz = NULL; JSType *fieldType = &Any_Type; uint32 slotIndex; if ((b->op1->getKind() == ExprNode::identifier) && !isWithinWith()) { const StringAtom &baseName = (static_cast(b->op1))->name; - JSType *baseType = &Any_Type; - base = findVariable(baseName); - - if (base.first != NotARegister) - baseType = base.second; - else { - // implicit 'this' has a big impact here - baseType = mGlobal->getType(baseName); - } + resolveIdentifier(baseName, base, slotIndex); + lValueKind = Property; - if (baseType == &Type_Type) { + // + // handle . + // + if (base.second == &Type_Type) { const JSValue &v = mGlobal->getVariable(baseName); - c = dynamic_cast(v.type); - if (c && c->hasStatic(name, fieldType)) { + clazz = dynamic_cast(v.type); + if (clazz && clazz->hasStatic(fieldName, fieldType)) { lValueKind = Static; } } if (lValueKind == Property) { - if (isSlotName(baseType, name, slotIndex, fieldType)) + if (isSlotName(base.second, fieldName, slotIndex, fieldType)) lValueKind = Slot; else { - c = dynamic_cast(baseType); - if (c && c->hasStatic(name, fieldType)) + clazz = dynamic_cast(base.second); + if (clazz && clazz->hasStatic(fieldName, fieldType)) lValueKind = Static; else lValueKind = Property; @@ -668,11 +799,11 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I } else { base = genExpr(b->op1); - if (isSlotName(base.second, name, slotIndex, fieldType)) + if (isSlotName(base.second, fieldName, slotIndex, fieldType)) lValueKind = Slot; else { - c = dynamic_cast(base.second); - if (c && c->hasStatic(name, fieldType)) + clazz = dynamic_cast(base.second); + if (clazz && clazz->hasStatic(fieldName, fieldType)) lValueKind = Static; else lValueKind = Property; @@ -683,10 +814,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::call: switch (lValueKind) { case Static: - ret = staticCall(c, name, *args); + ret = staticCall(clazz, fieldName, *args); break; case Property: - ret = methodCall(base, loadString(name), *args); + ret = methodCall(base, loadString(fieldName), *args); break; default: NOT_REACHED("Bad lvalue kind"); @@ -706,10 +837,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::bitwiseOrEquals: switch (lValueKind) { case Static: - v = getStatic(c, name); + v = getStatic(clazz, fieldName); break; case Property: - v = getProperty(base, name); + v = getProperty(base, fieldName); break; case Slot: v = getSlot(base, slotIndex); @@ -726,10 +857,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::assignment: switch (lValueKind) { case Static: - setStatic(c, name, ret); + setStatic(clazz, fieldName, ret); break; case Property: - setProperty(base, name, ret); + setProperty(base, fieldName, ret); break; case Slot: setSlot(base, slotIndex, ret); @@ -742,10 +873,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::postIncrement: switch (lValueKind) { case Static: - ret = staticXcr(c, name, xcrementOp); + ret = staticXcr(clazz, fieldName, xcrementOp); break; case Property: - ret = propertyXcr(base, name, xcrementOp); + ret = propertyXcr(base, fieldName, xcrementOp); break; case Slot: ret = slotXcr(base, slotIndex, xcrementOp); @@ -757,12 +888,12 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I case ExprNode::preIncrement: switch (lValueKind) { case Static: - ret = op(xcrementOp, getStatic(c, name), loadImmediate(1.0)); - setStatic(c, name, ret); + ret = op(xcrementOp, getStatic(clazz, fieldName), loadImmediate(1.0)); + setStatic(clazz, fieldName, ret); break; case Property: - ret = op(xcrementOp, getProperty(base, name), loadImmediate(1.0)); - setProperty(base, name, ret); + ret = op(xcrementOp, getProperty(base, fieldName), loadImmediate(1.0)); + setProperty(base, fieldName, ret); break; case Slot: ret = op(xcrementOp, getSlot(base, slotIndex), loadImmediate(1.0)); @@ -774,7 +905,7 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I break; case ExprNode::Delete: if (lValueKind == Property) { - ret = deleteProperty(base, name); + ret = deleteProperty(base, fieldName); } break; default: @@ -857,34 +988,10 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, if (i->op->getKind() == ExprNode::dot) { BinaryExprNode *b = static_cast(i->op); ret = handleDot(b, ExprNode::call, xcrementOp, ret, &args); -/* - TypedRegister base = genExpr(b->op1); - // might be Class.() - const StringAtom &name = static_cast(b->op2)->name; - if ((base.second == &Type_Type) - && (b->op1->getKind() == ExprNode::identifier)) { - const StringAtom &className = (static_cast(b->op1))->name; - const JSValue &v = mGlobal->getVariable(className); - JSClass* c = dynamic_cast(v.type); - if (c && c->hasStatic(name)) { - ret = staticCall(c, name, args); - break; - } - } - ret = methodCall(base, loadString(name), args); -*/ } else if (i->op->getKind() == ExprNode::identifier) { - if (!isWithinWith()) { - TypedRegister v = findVariable((static_cast(i->op))->name); - if (v.first != NotARegister) - ret = call(v, static_cast(i->op)->name, args); - else - ret = call(TypedRegister(NotARegister, &Null_Type), static_cast(i->op)->name, args); - } - else - ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(static_cast(i->op)->name), args); + ret = handleIdentifier(static_cast(i->op), ExprNode::call, xcrementOp, &args); } else if (i->op->getKind() == ExprNode::index) { @@ -916,34 +1023,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, break; case ExprNode::identifier : { - const StringAtom &name = (static_cast(p))->name; - if (!isWithinWith()) { - TypedRegister v = findVariable(name); - if (v.first != NotARegister) - ret = v; - else { - if (mClass) { // we're compiling a method of a class - JSType *fieldType; - if (!isStaticMethod()) { - uint32 slotIndex; - if (isSlotName(mClass, name, slotIndex, fieldType)) { - ret = getSlot(TypedRegister(0, mClass), slotIndex); - ret.second = fieldType; - break; - } - } - if (mClass->hasStatic(name, fieldType)) { - ret = getStatic(mClass, name); - ret.second = fieldType; - break; - } - } - ret = loadName(name); - ret.second = mGlobal->getType(name); - } - } - else - ret = loadName(name); + ret = handleIdentifier(static_cast(p), ExprNode::identifier, xcrementOp, NULL); } break; case ExprNode::number : @@ -958,26 +1038,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, { UnaryExprNode *u = static_cast(p); if (u->op->getKind() == ExprNode::dot) { - BinaryExprNode *b = static_cast(u->op); - ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL); + ret = handleDot(static_cast(u->op), p->getKind(), xcrementOp, ret, NULL); } else if (u->op->getKind() == ExprNode::identifier) { - if (!isWithinWith()) { - TypedRegister v = findVariable((static_cast(u->op))->name); - if (v.first != NotARegister) - ret = op(xcrementOp, ret, loadImmediate(1.0)); - else { - ret = loadName((static_cast(u->op))->name); - ret = op(xcrementOp, ret, loadImmediate(1.0)); - saveName((static_cast(u->op))->name, ret); - } - } - else { - ret = loadName((static_cast(u->op))->name); - ret = op(xcrementOp, ret, loadImmediate(1.0)); - saveName((static_cast(u->op))->name, ret); - } + ret = handleIdentifier(static_cast(u->op), p->getKind(), xcrementOp, NULL); } else if (u->op->getKind() == ExprNode::index) { @@ -998,20 +1063,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, { UnaryExprNode *u = static_cast(p); if (u->op->getKind() == ExprNode::dot) { - BinaryExprNode *b = static_cast(u->op); - ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL); + ret = handleDot(static_cast(u->op), p->getKind(), xcrementOp, ret, NULL); } else if (u->op->getKind() == ExprNode::identifier) { - if (!isWithinWith()) { - TypedRegister v = findVariable((static_cast(u->op))->name); - if (v.first != NotARegister) - ret = varXcr(v, xcrementOp); - else - ret = nameXcr((static_cast(u->op))->name, xcrementOp); - } - else - ret = nameXcr((static_cast(u->op))->name, xcrementOp); + ret = handleIdentifier(static_cast(u->op), p->getKind(), xcrementOp, NULL); } else if (u->op->getKind() == ExprNode::index) { @@ -1291,7 +1347,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, icg.allocateParameter((static_cast(v->name))->name); v = v->next; } - icg.preprocess(f->function.body); icg.genStmt(f->function.body); //stdOut << icg; ICodeModule *icm = icg.complete(); @@ -1325,116 +1380,6 @@ bool LabelEntry::containsLabel(const StringAtom *label) return false; } -void ICodeGenerator::preprocess(StmtNode *p) -{ - switch (p->getKind()) { - case StmtNode::block: - { - BlockStmtNode *b = static_cast(p); - StmtNode *s = b->statements; - while (s) { - preprocess(s); - s = s->next; - } - } - break; - case StmtNode::Var: - { - VariableStmtNode *vs = static_cast(p); - VariableBinding *v = vs->bindings; - while (v) { - if (v->name && (v->name->getKind() == ExprNode::identifier)) - if (v->type && (v->type->getKind() == ExprNode::identifier)) - if (isTopLevel()) - mGlobal->defineVariable((static_cast(v->name))->name, - findType((static_cast(v->type))->name)); - else - allocateVariable((static_cast(v->name))->name, - (static_cast(v->type))->name); - else - allocateVariable((static_cast(v->name))->name); - v = v->next; - } - } - break; - case StmtNode::DoWhile: - { - UnaryStmtNode *d = static_cast(p); - preprocess(d->stmt); - } - break; - case StmtNode::While: - { - UnaryStmtNode *w = static_cast(p); - preprocess(w->stmt); - } - break; - case StmtNode::For: - { - ForStmtNode *f = static_cast(p); - if (f->initializer) - preprocess(f->initializer); - preprocess(f->stmt); - } - break; - case StmtNode::If: - { - UnaryStmtNode *i = static_cast(p); - preprocess(i->stmt); - } - break; - case StmtNode::IfElse: - { - BinaryStmtNode *i = static_cast(p); - preprocess(i->stmt); - preprocess(i->stmt2); - } - break; - case StmtNode::With: - { - UnaryStmtNode *w = static_cast(p); - preprocess(w->stmt); - } - break; - case StmtNode::Switch: - { - SwitchStmtNode *sw = static_cast(p); - StmtNode *s = sw->statements; - while (s) { - if (s->getKind() != StmtNode::Case) - preprocess(s); - s = s->next; - } - } - break; - case StmtNode::label: - { - LabelStmtNode *l = static_cast(p); - preprocess(l->stmt); - } - break; - case StmtNode::Try: - { - TryStmtNode *t = static_cast(p); - genStmt(t->stmt); - if (t->catches) { - CatchClause *c = t->catches; - while (c) { - preprocess(c->stmt); - c = c->next; - } - } - if (t->finally) - genStmt(t->finally); - } - break; - - default: - break; - - } -} - static bool hasAttribute(const IdentifierList* identifiers, Token::Kind tokenKind) { while (identifiers) { @@ -1458,7 +1403,6 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f) icg.allocateParameter((static_cast(v->name))->name); v = v->next; } - icg.preprocess(f->function.body); icg.genStmt(f->function.body); return icg.complete(); @@ -1469,8 +1413,8 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) TypedRegister ret(NotARegister, &None_Type); startStatement(p->pos); - if (exceptionRegister.first == NotARegister) { - exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); + if (mExceptionRegister.first == NotARegister) { + mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type); } switch (p->getKind()) { @@ -1565,7 +1509,7 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) // freeze the class. thisClass->complete(); if (ccg.getICode()->size()) - thisClass->setConstructor(ccg.complete()); + thisClass->setInitializer(ccg.complete()); // REVISIT: using the scope of the class to store both methods and statics. if (scg.getICode()->size()) { Interpreter::Context cx(*mWorld, thisScope); @@ -1591,8 +1535,18 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) VariableStmtNode *vs = static_cast(p); VariableBinding *v = vs->bindings; while (v) { - if (v->name && v->initializer) { - if (v->name->getKind() == ExprNode::identifier) { + if (v->name && (v->name->getKind() == ExprNode::identifier)) { + if (v->type && (v->type->getKind() == ExprNode::identifier)) { + if (isTopLevel()) + mGlobal->defineVariable((static_cast(v->name))->name, + findType((static_cast(v->type))->name)); + else + allocateVariable((static_cast(v->name))->name, + (static_cast(v->type))->name); + } + else + allocateVariable((static_cast(v->name))->name); + if (v->initializer) { if (!isTopLevel() && !isWithinWith()) { TypedRegister r = genExpr(v->name); TypedRegister val = genExpr(v->initializer); @@ -1603,7 +1557,6 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) saveName((static_cast(v->name))->name, val); } } - // XXX what's the else case here, when does a VariableBinding NOT have an identifier child? } v = v->next; } @@ -1889,19 +1842,19 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet) CatchClause *c = t->catches; while (c) { // Bind the incoming exception ... - setRegisterForVariable(c->name, exceptionRegister); + setRegisterForVariable(c->name, mExceptionRegister); genStmt(c->stmt); if (finallyLabel) jsr(finallyLabel); - throwStmt(exceptionRegister); + throwStmt(mExceptionRegister); c = c->next; } } if (finallyLabel) { setLabel(finallyInvoker); jsr(finallyLabel); - throwStmt(exceptionRegister); + throwStmt(mExceptionRegister); setLabel(finallyLabel); genStmt(t->finally); diff --git a/mozilla/js2/src/icodegenerator.h b/mozilla/js2/src/icodegenerator.h index 37aa42d3631..7d2ee1e4bce 100644 --- a/mozilla/js2/src/icodegenerator.h +++ b/mozilla/js2/src/icodegenerator.h @@ -118,69 +118,70 @@ namespace ICG { bool iCodeOwner; LabelList labels; - Register topRegister; // highest (currently) alloacated register - Register registerBase; // start of registers available for expression temps - uint32 maxRegister; // highest (ever) allocated register - uint32 parameterCount; // number of parameters declared for the function - // these must come before any variables declared. - TypedRegister exceptionRegister;// reserved to carry the exception object. - VariableList *variableList; // name|register pair for each variable + Register mTopRegister; // highest (currently) alloacated register + uint32 mParameterCount; // number of parameters declared for the function + // these must come before any variables declared. + TypedRegister mExceptionRegister; // reserved to carry the exception object. + VariableList *variableList; // name|register pair for each variable - World *mWorld; // used to register strings - JSScope *mGlobal; // the scope for compiling within - LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct - // maps source position to instruction index + World *mWorld; // used to register strings + JSScope *mGlobal; // the scope for compiling within + LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct + // maps source position to instruction index InstructionMap *mInstructionMap; - JSClass *mClass; // enclosing class when generating code for methods - ICodeGeneratorFlags mFlags; // assorted flags + JSClass *mClass; // enclosing class when generating code for methods + ICodeGeneratorFlags mFlags; // assorted flags + + std::vector mPermanentRegister; + + Register getTempRegister() + { + while (mTopRegister < mPermanentRegister.size()) + if (!mPermanentRegister[mTopRegister]) + return mTopRegister++; + else + ++mTopRegister; + mPermanentRegister.resize(mTopRegister + 1); + mPermanentRegister[mTopRegister] = false; + return mTopRegister++; + } + + void resetTopRegister() { mTopRegister = mParameterCount; } + void resetStatement() { resetTopRegister(); } + + TypedRegister allocateRegister(const StringAtom& name, JSType *type); + + void setRegisterForVariable(const StringAtom& name, TypedRegister r) { (*variableList)[name] = r; } + + JSType *findType(const StringAtom& typeName); + + + - void markMaxRegister() - { if (topRegister > maxRegister) maxRegister = topRegister; } - - Register getRegister() - { return topRegister++; } - void resetTopRegister() - { markMaxRegister(); topRegister = registerBase; } - void setLabel(Label *label); - void jsr(Label *label) { iCode->push_back(new Jsr(label)); } - void rts() { iCode->push_back(new Rts()); } + void jsr(Label *label) { iCode->push_back(new Jsr(label)); } + void rts() { iCode->push_back(new Rts()); } void branch(Label *label); GenericBranch *branchTrue(Label *label, TypedRegister condition); GenericBranch *branchFalse(Label *label, TypedRegister condition); void beginTry(Label *catchLabel, Label *finallyLabel) - { iCode->push_back(new Tryin(catchLabel, finallyLabel)); } - void endTry() - { iCode->push_back(new Tryout()); } + { iCode->push_back(new Tryin(catchLabel, finallyLabel)); } + void endTry() { iCode->push_back(new Tryout()); } - void beginWith(TypedRegister obj) - { iCode->push_back(new Within(obj)); } - void endWith() - { iCode->push_back(new Without()); } + void beginWith(TypedRegister obj) { iCode->push_back(new Within(obj)); } + void endWith() { iCode->push_back(new Without()); } - void resetStatement() { resetTopRegister(); } - void setRegisterForVariable(const StringAtom& name, TypedRegister r) - { (*variableList)[name] = r; } - void startStatement(uint32 pos) - { (*mInstructionMap)[iCode->size()] = pos; } + void startStatement(uint32 pos) { (*mInstructionMap)[iCode->size()] = pos; } ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind); - TypedRegister grabRegister(const StringAtom& name, JSType *type) - { - TypedRegister result(getRegister(), type); - (*variableList)[name] = result; - registerBase = topRegister; - return result; - } - bool isTopLevel() { return (mFlags & kIsTopLevel) != 0; } bool isWithinWith() { return (mFlags & kIsWithinWith) != 0; } @@ -188,7 +189,11 @@ namespace ICG { void setFlag(uint32 flag, bool v) { mFlags = (ICodeGeneratorFlags)((v) ? mFlags | flag : mFlags & ~flag); } - JSType *findType(const StringAtom& typeName); + + typedef enum {Var, Property, Slot, Static, Name} LValueKind; + + LValueKind resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex); + TypedRegister handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args); TypedRegister handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args); ICodeModule *genFunction(FunctionStmtNode *f); @@ -207,32 +212,30 @@ namespace ICG { ICodeModule *complete(); TypedRegister genExpr(ExprNode *p, - bool needBoolValueInBranch = false, - Label *trueBranch = NULL, - Label *falseBranch = NULL); - void preprocess(StmtNode *p); + bool needBoolValueInBranch = false, + Label *trueBranch = NULL, + Label *falseBranch = NULL); TypedRegister genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL); void returnStmt(TypedRegister r); void returnStmt(); - void throwStmt(TypedRegister r) - { iCode->push_back(new Throw(r)); } - void debuggerStmt() - { iCode->push_back(new Debugger()); } + void throwStmt(TypedRegister r) { iCode->push_back(new Throw(r)); } + void debuggerStmt() { iCode->push_back(new Debugger()); } TypedRegister allocateVariable(const StringAtom& name); TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName); TypedRegister findVariable(const StringAtom& name) - { VariableList::iterator i = variableList->find(name); - return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; } + { + VariableList::iterator i = variableList->find(name); + return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; + } - TypedRegister allocateParameter(const StringAtom& name) - { parameterCount++; return grabRegister(name, &Any_Type); } + TypedRegister allocateParameter(const StringAtom& name) { mParameterCount++; return allocateRegister(name, &Any_Type); } TypedRegister allocateParameter(const StringAtom& name, const StringAtom& typeName) - { parameterCount++; return grabRegister(name, findType(typeName)); } + { mParameterCount++; return allocateRegister(name, findType(typeName)); } TypedRegister allocateParameter(const StringAtom& name, JSType *type) - { parameterCount++; return grabRegister(name, type); } + { mParameterCount++; return allocateRegister(name, type); } Formatter& print(Formatter& f); @@ -279,8 +282,7 @@ namespace ICG { TypedRegister varXcr(TypedRegister var, ICodeOp op); - Register getRegisterBase() { return topRegister; } - InstructionStream *getICode() { return iCode; } + InstructionStream *getICode() { return iCode; } Label *getLabel(); diff --git a/mozilla/js2/src/interpreter.cpp b/mozilla/js2/src/interpreter.cpp index 2deb21774f4..6e68b2e2b94 100644 --- a/mozilla/js2/src/interpreter.cpp +++ b/mozilla/js2/src/interpreter.cpp @@ -679,14 +679,14 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) InstructionIterator nextPC = ++mPC; do { // call the constructor(s), if any. - ICodeModule* ctor = thisClass->getConstructor(); - if (ctor) { + ICodeModule* init = thisClass->getInitializer(); + if (init) { mLinkage = new Linkage(mLinkage, nextPC, mActivation, mGlobal, voidRegister); - mActivation = new Activation(ctor, args); + mActivation = new Activation(init, args); registers = &mActivation->mRegisters; - nextPC = ctor->its_iCode->begin(); - endPC = ctor->its_iCode->end(); + nextPC = init->its_iCode->begin(); + endPC = init->its_iCode->end(); } thisClass = thisClass->getSuperClass(); } while (thisClass); diff --git a/mozilla/js2/src/jsclasses.h b/mozilla/js2/src/jsclasses.h index 0cda4d81290..c32bbe16977 100644 --- a/mozilla/js2/src/jsclasses.h +++ b/mozilla/js2/src/jsclasses.h @@ -79,7 +79,7 @@ namespace JSClasses { uint32 mStaticCount; JSSlots mStaticSlots; JSValue* mStaticData; - ICodeModule* mConstructor; + ICodeModule* mInitializer; // typedef std::vector > JSMethods; // JSMethods mMethods; public: @@ -89,7 +89,7 @@ namespace JSClasses { mSlotCount(superClass ? superClass->mSlotCount : 0), mStaticCount(0), mStaticData(0), - mConstructor(0) + mInitializer(0) { // to "inherit" superClass methods. if (superClass) @@ -106,14 +106,14 @@ namespace JSClasses { return mScope; } - void setConstructor(ICodeModule* ctor) + void setInitializer(ICodeModule* init) { - mConstructor = ctor; + mInitializer = init; } - ICodeModule* getConstructor() + ICodeModule* getInitializer() { - return mConstructor; + return mInitializer; } const JSSlot& defineSlot(const String& name, JSType* type) diff --git a/mozilla/js2/src/winbuild/js2.dsp b/mozilla/js2/src/winbuild/js2.dsp index ba72d60c459..da1371d3f10 100644 --- a/mozilla/js2/src/winbuild/js2.dsp +++ b/mozilla/js2/src/winbuild/js2.dsp @@ -175,6 +175,10 @@ SOURCE=..\hash.h # End Source File # Begin Source File +SOURCE=..\icode.h +# End Source File +# Begin Source File + SOURCE=..\icodegenerator.h # End Source File # Begin Source File diff --git a/mozilla/js2/tests/cpp/js2_shell.cpp b/mozilla/js2/tests/cpp/js2_shell.cpp index f83a84e8fdb..b1c74c29098 100644 --- a/mozilla/js2/tests/cpp/js2_shell.cpp +++ b/mozilla/js2/tests/cpp/js2_shell.cpp @@ -147,7 +147,6 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName) TypedRegister ret(NotARegister, &None_Type); while (p) { - icg.preprocess(p); ret = icg.genStmt(p); p = p->next; } @@ -155,7 +154,7 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName) ICodeModule *icm = icg.complete(); -//stdOut << icg; +stdOut << icg; icm->setFileName (fileName); return icm; @@ -344,7 +343,8 @@ class Tracer : public Context::Listener { char * tests[] = { "function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" , - "a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" + "a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" , + "class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s()); print(A.b); return;" }; static void testCompile() @@ -361,15 +361,11 @@ static void testCompile() StmtNode *parsedStatements = p.parseProgram(); ICodeGenerator icg(&world, &glob); StmtNode *s = parsedStatements; - while (s) { - icg.preprocess(s); - s = s->next; - } - s = parsedStatements; while (s) { icg.genStmt(s); s = s->next; } +// stdOut << icg; cx.interpret(icg.complete(), JSValues()); } }