From f13e0741a0b3af0f83f900be6500c244df9f1110 Mon Sep 17 00:00:00 2001 From: "rogerl%netscape.com" Date: Thu, 1 Feb 2001 00:59:21 +0000 Subject: [PATCH] Changed Cast to take a JSValue containing a type instead of type directly. Added LoadType to help support that. Also added LoadNull. --- js/js2/icode.h | 28 +++++++++--- js/js2/icodegenerator.cpp | 20 ++++++++- js/js2/icodegenerator.h | 2 + js/js2/icodemap.h | 88 ++++++++++++++++++++------------------ js/js2/interpreter.cpp | 22 +++++----- js/js2/tools/jsicodes.pm | 8 +++- js2/src/icode.h | 28 +++++++++--- js2/src/icodegenerator.cpp | 20 ++++++++- js2/src/icodegenerator.h | 2 + js2/src/icodemap.h | 88 ++++++++++++++++++++------------------ js2/src/interpreter.cpp | 22 +++++----- js2/tools/jsicodes.pm | 8 +++- 12 files changed, 218 insertions(+), 118 deletions(-) diff --git a/js/js2/icode.h b/js/js2/icode.h index 962bd0ee0d25..d399b7b81242 100644 --- a/js/js2/icode.h +++ b/js/js2/icode.h @@ -41,6 +41,7 @@ LOAD_NULL, /* dest */ LOAD_STRING, /* dest, immediate value (string) */ LOAD_TRUE, /* dest */ + LOAD_TYPE, /* dest, type */ MOVE, /* dest, source */ MULTIPLY, /* dest, source1, source2 */ NAME_XCR, /* dest, name, value */ @@ -191,18 +192,18 @@ } }; - class Cast : public Instruction_3 { + class Cast : public Instruction_3 { public: /* dest, rvalue, toType */ - Cast (TypedRegister aOp1, TypedRegister aOp2, JSType* aOp3) : - Instruction_3 + Cast (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) : + Instruction_3 (CAST, aOp1, aOp2, aOp3) {}; virtual Formatter& print(Formatter& f) { - f << opcodeNames[CAST] << "\t" << mOp1 << ", " << mOp2 << ", " << "'" << mOp3->getName() << "'"; + f << opcodeNames[CAST] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3; return f; } virtual Formatter& printOperands(Formatter& f, const JSValues& registers) { - f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first); + f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first); return f; } }; @@ -646,6 +647,22 @@ } }; + class LoadType : public Instruction_2 { + public: + /* dest, type */ + LoadType (TypedRegister aOp1, JSType* aOp2) : + Instruction_2 + (LOAD_TYPE, aOp1, aOp2) {}; + virtual Formatter& print(Formatter& f) { + f << opcodeNames[LOAD_TYPE] << "\t" << mOp1 << ", " << "'" << mOp2->getName() << "'"; + return f; + } + virtual Formatter& printOperands(Formatter& f, const JSValues& registers) { + f << getRegisterValue(registers, mOp1.first); + return f; + } + }; + class Move : public Instruction_2 { public: /* dest, source */ @@ -1265,6 +1282,7 @@ "LOAD_NULL ", "LOAD_STRING ", "LOAD_TRUE ", + "LOAD_TYPE ", "MOVE ", "MULTIPLY ", "NAME_XCR ", diff --git a/js/js2/icodegenerator.cpp b/js/js2/icodegenerator.cpp index 1deddc30e182..664ba95c9f7e 100644 --- a/js/js2/icodegenerator.cpp +++ b/js/js2/icodegenerator.cpp @@ -225,6 +225,21 @@ TypedRegister ICodeGenerator::loadBoolean(bool value) return dest; } +TypedRegister ICodeGenerator::loadNull() +{ + TypedRegister dest(getTempRegister(), &Any_Type); + iCode->push_back(new LoadNull(dest)); + return dest; +} + +TypedRegister ICodeGenerator::loadType(JSType *type) +{ + TypedRegister dest(getTempRegister(), type); + iCode->push_back(new LoadType(dest, type)); + return dest; +} + + TypedRegister ICodeGenerator::newObject(TypedRegister constructor) { TypedRegister dest(getTempRegister(), &Any_Type); @@ -535,7 +550,7 @@ TypedRegister ICodeGenerator::super() TypedRegister ICodeGenerator::cast(TypedRegister arg, JSType *toType) { TypedRegister dest(getTempRegister(), toType); - Cast *instr = new Cast(dest, arg, toType); + Cast *instr = new Cast(dest, arg, loadType(toType)); iCode->push_back(instr); return dest; } @@ -1249,6 +1264,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, else ret = loadBoolean(false); break; + case ExprNode::Null: + ret = loadNull(); + break; case ExprNode::parentheses: { UnaryExprNode *u = static_cast(p); diff --git a/js/js2/icodegenerator.h b/js/js2/icodegenerator.h index dea8d866f2e2..43f4cf538835 100644 --- a/js/js2/icodegenerator.h +++ b/js/js2/icodegenerator.h @@ -378,6 +378,8 @@ namespace ICG { TypedRegister loadImmediate(double value); TypedRegister loadString(const String &value); TypedRegister loadString(const StringAtom &name); + TypedRegister loadNull(); + TypedRegister loadType(JSType *toType); TypedRegister newObject(TypedRegister constructor); TypedRegister newArray(); diff --git a/js/js2/icodemap.h b/js/js2/icodemap.h index 9949741f559e..485ce905565a 100644 --- a/js/js2/icodemap.h +++ b/js/js2/icodemap.h @@ -45,7 +45,7 @@ namespace JavaScript { namespace ICodeASM { - static uint icodemap_size = 78; + static uint icodemap_size = 79; static struct { char *name; @@ -60,7 +60,7 @@ namespace ICodeASM { {"BRANCH_INITIALIZED", {otLabel, otRegister}}, {"BRANCH_TRUE", {otLabel, otRegister}}, {"CALL", {otRegister, otRegister, otArgumentList}}, - {"CAST", {otRegister, otRegister, otJSType}}, + {"CAST", {otRegister, otRegister, otRegister}}, {"CLASS", {otRegister, otRegister}}, {"COMPARE_EQ", {otRegister, otRegister, otRegister}}, {"COMPARE_GE", {otRegister, otRegister, otRegister}}, @@ -89,6 +89,7 @@ namespace ICodeASM { {"LOAD_NULL", {otRegister}}, {"LOAD_STRING", {otRegister, otJSString}}, {"LOAD_TRUE", {otRegister}}, + {"LOAD_TYPE", {otRegister, otJSType}}, {"MOVE", {otRegister, otRegister}}, {"MULTIPLY", {otRegister, otRegister, otRegister}}, {"NAME_XCR", {otRegister, otStringAtom, otDouble}}, @@ -167,7 +168,7 @@ namespace ICodeASM { i = new Call (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data)); break; case 9: - i = new Cast (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data)); + i = new Cast (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 10: i = new Class (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); @@ -254,123 +255,126 @@ namespace ICodeASM { i = new LoadTrue (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 38: - i = new Move (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new LoadType (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 39: - i = new Multiply (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Move (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 40: - i = new NameXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data)); + i = new Multiply (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 41: - i = new Negate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new NameXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data)); break; case 42: - i = new NewArray (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Negate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 43: - i = new NewClass (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); + i = new NewArray (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 44: - i = new NewClosure (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); + i = new NewClass (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 45: - i = new NewFunction (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); + i = new NewClosure (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 46: - i = new NewObject (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new NewFunction (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 47: - i = new Nop (); + i = new NewObject (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 48: - i = new Not (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Nop (); break; case 49: - i = new Or (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Not (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 50: - i = new Posate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Or (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 51: - i = new PropXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data), static_cast(node->operand[3].data)); + i = new Posate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 52: - i = new Remainder (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new PropXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data), static_cast(node->operand[3].data)); break; case 53: - i = new Return (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Remainder (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 54: - i = new ReturnVoid (); + i = new Return (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 55: - i = new Rts (); + i = new ReturnVoid (); break; case 56: - i = new SaveName (reinterpret_cast(node->operand[0].data), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Rts (); break; case 57: - i = new SetElement (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SaveName (reinterpret_cast(node->operand[0].data), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 58: - i = new SetProp (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetElement (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 59: - i = new SetSlot (TypedRegister(static_cast(node->operand[0].data), 0), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetProp (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 60: - i = new SetStatic (reinterpret_cast(node->operand[0].data), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetSlot (TypedRegister(static_cast(node->operand[0].data), 0), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 61: - i = new Shiftleft (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetStatic (reinterpret_cast(node->operand[0].data), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 62: - i = new Shiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Shiftleft (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 63: - i = new SlotXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); + i = new Shiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 64: - i = new StaticXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); + i = new SlotXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); break; case 65: - i = new StrictEQ (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new StaticXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); break; case 66: - i = new StrictNE (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new StrictEQ (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 67: - i = new Subtract (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new StrictNE (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 68: - i = new Super (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Subtract (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 69: - i = new Test (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Super (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 70: - i = new Throw (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Test (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 71: - i = new Tryin (reinterpret_cast(node->operand[0].data), reinterpret_cast(node->operand[1].data)); + i = new Throw (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 72: - i = new Tryout (); + i = new Tryin (reinterpret_cast(node->operand[0].data), reinterpret_cast(node->operand[1].data)); break; case 73: - i = new Ushiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Tryout (); break; case 74: - i = new VarXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data)); + i = new Ushiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 75: - i = new Within (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new VarXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data)); break; case 76: - i = new Without (); + i = new Within (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 77: + i = new Without (); + break; + case 78: i = new Xor (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; diff --git a/js/js2/interpreter.cpp b/js/js2/interpreter.cpp index 02e89123a87e..63886ef4f0f4 100644 --- a/js/js2/interpreter.cpp +++ b/js/js2/interpreter.cpp @@ -108,12 +108,6 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName) JSValues emptyArgs; JSValue result; - // save off important member variables, to enable recursive call to interpret. - // this is a little stinky, but should be exception-safe. - autosaver activation(mActivation, 0); - autosaver linkage(mLinkage, 0); - autosaver pc(mPC); - try { Arena a; Parser p(getWorld(), a, buffer, fileName); @@ -133,11 +127,12 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName) stdOut << '\n'; /*******/ - // Generate code for parsedStatements, which is a linked + // Generate code for parsedStatements, which is a linked // list of zero or more statements ICodeModule* icm = genCode(parsedStatements, fileName); if (icm) { - result = interpret(icm, emptyArgs); + Context cx(getWorld(), getGlobalObject()); + result = cx.interpret(icm, emptyArgs); delete icm; } } catch (Exception &e) { @@ -538,8 +533,15 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) case CAST: { Cast* c = static_cast(instruction); - JSType *toType = op3(c); - (*registers)[dst(c).first] = (*registers)[src1(c).first].convert(toType); + JSValue toTypeValue = (*registers)[op3(c).first]; + ASSERT(toTypeValue.isType()); + (*registers)[dst(c).first] = (*registers)[src1(c).first].convert(toTypeValue.type); + } + break; + case LOAD_TYPE: + { + LoadType *lt = static_cast(instruction); + (*registers)[dst(lt).first] = src1(lt); } break; case CLASS: diff --git a/js/js2/tools/jsicodes.pm b/js/js2/tools/jsicodes.pm index 12835e8b2072..c2764a269a3d 100644 --- a/js/js2/tools/jsicodes.pm +++ b/js/js2/tools/jsicodes.pm @@ -175,6 +175,12 @@ $ops{"LOAD_NAME"} = rem => "dest, name", params => [ ("TypedRegister", "const StringAtom*" ) ] }; +$ops{"LOAD_TYPE"} = + { + super => "Instruction_2", + rem => "dest, type", + params => [ ("TypedRegister", "JSType*" ) ] + }; $ops{"SUPER"} = { super => "Instruction_1", @@ -426,7 +432,7 @@ $ops{"CAST"} = { super => "Instruction_3", rem => "dest, rvalue, toType", - params => [ ("TypedRegister", "TypedRegister", "JSType*") ] + params => [ ("TypedRegister", "TypedRegister", "TypedRegister") ] }; $ops{"CLASS"} = { diff --git a/js2/src/icode.h b/js2/src/icode.h index 962bd0ee0d25..d399b7b81242 100644 --- a/js2/src/icode.h +++ b/js2/src/icode.h @@ -41,6 +41,7 @@ LOAD_NULL, /* dest */ LOAD_STRING, /* dest, immediate value (string) */ LOAD_TRUE, /* dest */ + LOAD_TYPE, /* dest, type */ MOVE, /* dest, source */ MULTIPLY, /* dest, source1, source2 */ NAME_XCR, /* dest, name, value */ @@ -191,18 +192,18 @@ } }; - class Cast : public Instruction_3 { + class Cast : public Instruction_3 { public: /* dest, rvalue, toType */ - Cast (TypedRegister aOp1, TypedRegister aOp2, JSType* aOp3) : - Instruction_3 + Cast (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) : + Instruction_3 (CAST, aOp1, aOp2, aOp3) {}; virtual Formatter& print(Formatter& f) { - f << opcodeNames[CAST] << "\t" << mOp1 << ", " << mOp2 << ", " << "'" << mOp3->getName() << "'"; + f << opcodeNames[CAST] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3; return f; } virtual Formatter& printOperands(Formatter& f, const JSValues& registers) { - f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first); + f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first); return f; } }; @@ -646,6 +647,22 @@ } }; + class LoadType : public Instruction_2 { + public: + /* dest, type */ + LoadType (TypedRegister aOp1, JSType* aOp2) : + Instruction_2 + (LOAD_TYPE, aOp1, aOp2) {}; + virtual Formatter& print(Formatter& f) { + f << opcodeNames[LOAD_TYPE] << "\t" << mOp1 << ", " << "'" << mOp2->getName() << "'"; + return f; + } + virtual Formatter& printOperands(Formatter& f, const JSValues& registers) { + f << getRegisterValue(registers, mOp1.first); + return f; + } + }; + class Move : public Instruction_2 { public: /* dest, source */ @@ -1265,6 +1282,7 @@ "LOAD_NULL ", "LOAD_STRING ", "LOAD_TRUE ", + "LOAD_TYPE ", "MOVE ", "MULTIPLY ", "NAME_XCR ", diff --git a/js2/src/icodegenerator.cpp b/js2/src/icodegenerator.cpp index 1deddc30e182..664ba95c9f7e 100644 --- a/js2/src/icodegenerator.cpp +++ b/js2/src/icodegenerator.cpp @@ -225,6 +225,21 @@ TypedRegister ICodeGenerator::loadBoolean(bool value) return dest; } +TypedRegister ICodeGenerator::loadNull() +{ + TypedRegister dest(getTempRegister(), &Any_Type); + iCode->push_back(new LoadNull(dest)); + return dest; +} + +TypedRegister ICodeGenerator::loadType(JSType *type) +{ + TypedRegister dest(getTempRegister(), type); + iCode->push_back(new LoadType(dest, type)); + return dest; +} + + TypedRegister ICodeGenerator::newObject(TypedRegister constructor) { TypedRegister dest(getTempRegister(), &Any_Type); @@ -535,7 +550,7 @@ TypedRegister ICodeGenerator::super() TypedRegister ICodeGenerator::cast(TypedRegister arg, JSType *toType) { TypedRegister dest(getTempRegister(), toType); - Cast *instr = new Cast(dest, arg, toType); + Cast *instr = new Cast(dest, arg, loadType(toType)); iCode->push_back(instr); return dest; } @@ -1249,6 +1264,9 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p, else ret = loadBoolean(false); break; + case ExprNode::Null: + ret = loadNull(); + break; case ExprNode::parentheses: { UnaryExprNode *u = static_cast(p); diff --git a/js2/src/icodegenerator.h b/js2/src/icodegenerator.h index dea8d866f2e2..43f4cf538835 100644 --- a/js2/src/icodegenerator.h +++ b/js2/src/icodegenerator.h @@ -378,6 +378,8 @@ namespace ICG { TypedRegister loadImmediate(double value); TypedRegister loadString(const String &value); TypedRegister loadString(const StringAtom &name); + TypedRegister loadNull(); + TypedRegister loadType(JSType *toType); TypedRegister newObject(TypedRegister constructor); TypedRegister newArray(); diff --git a/js2/src/icodemap.h b/js2/src/icodemap.h index 9949741f559e..485ce905565a 100644 --- a/js2/src/icodemap.h +++ b/js2/src/icodemap.h @@ -45,7 +45,7 @@ namespace JavaScript { namespace ICodeASM { - static uint icodemap_size = 78; + static uint icodemap_size = 79; static struct { char *name; @@ -60,7 +60,7 @@ namespace ICodeASM { {"BRANCH_INITIALIZED", {otLabel, otRegister}}, {"BRANCH_TRUE", {otLabel, otRegister}}, {"CALL", {otRegister, otRegister, otArgumentList}}, - {"CAST", {otRegister, otRegister, otJSType}}, + {"CAST", {otRegister, otRegister, otRegister}}, {"CLASS", {otRegister, otRegister}}, {"COMPARE_EQ", {otRegister, otRegister, otRegister}}, {"COMPARE_GE", {otRegister, otRegister, otRegister}}, @@ -89,6 +89,7 @@ namespace ICodeASM { {"LOAD_NULL", {otRegister}}, {"LOAD_STRING", {otRegister, otJSString}}, {"LOAD_TRUE", {otRegister}}, + {"LOAD_TYPE", {otRegister, otJSType}}, {"MOVE", {otRegister, otRegister}}, {"MULTIPLY", {otRegister, otRegister, otRegister}}, {"NAME_XCR", {otRegister, otStringAtom, otDouble}}, @@ -167,7 +168,7 @@ namespace ICodeASM { i = new Call (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data)); break; case 9: - i = new Cast (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data)); + i = new Cast (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 10: i = new Class (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); @@ -254,123 +255,126 @@ namespace ICodeASM { i = new LoadTrue (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 38: - i = new Move (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new LoadType (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 39: - i = new Multiply (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Move (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 40: - i = new NameXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data)); + i = new Multiply (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 41: - i = new Negate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new NameXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data)); break; case 42: - i = new NewArray (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Negate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 43: - i = new NewClass (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); + i = new NewArray (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 44: - i = new NewClosure (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); + i = new NewClass (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 45: - i = new NewFunction (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); + i = new NewClosure (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 46: - i = new NewObject (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new NewFunction (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data)); break; case 47: - i = new Nop (); + i = new NewObject (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 48: - i = new Not (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Nop (); break; case 49: - i = new Or (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Not (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 50: - i = new Posate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Or (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 51: - i = new PropXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data), static_cast(node->operand[3].data)); + i = new Posate (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 52: - i = new Remainder (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new PropXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), reinterpret_cast(node->operand[2].data), static_cast(node->operand[3].data)); break; case 53: - i = new Return (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Remainder (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 54: - i = new ReturnVoid (); + i = new Return (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 55: - i = new Rts (); + i = new ReturnVoid (); break; case 56: - i = new SaveName (reinterpret_cast(node->operand[0].data), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Rts (); break; case 57: - i = new SetElement (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SaveName (reinterpret_cast(node->operand[0].data), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 58: - i = new SetProp (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetElement (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 59: - i = new SetSlot (TypedRegister(static_cast(node->operand[0].data), 0), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetProp (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 60: - i = new SetStatic (reinterpret_cast(node->operand[0].data), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetSlot (TypedRegister(static_cast(node->operand[0].data), 0), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 61: - i = new Shiftleft (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new SetStatic (reinterpret_cast(node->operand[0].data), static_cast(node->operand[1].data), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 62: - i = new Shiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Shiftleft (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 63: - i = new SlotXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); + i = new Shiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 64: - i = new StaticXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); + i = new SlotXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); break; case 65: - i = new StrictEQ (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new StaticXcr (TypedRegister(static_cast(node->operand[0].data), 0), reinterpret_cast(node->operand[1].data), static_cast(node->operand[2].data), static_cast(node->operand[3].data)); break; case 66: - i = new StrictNE (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new StrictEQ (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 67: - i = new Subtract (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new StrictNE (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 68: - i = new Super (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Subtract (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 69: - i = new Test (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); + i = new Super (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 70: - i = new Throw (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new Test (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0)); break; case 71: - i = new Tryin (reinterpret_cast(node->operand[0].data), reinterpret_cast(node->operand[1].data)); + i = new Throw (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 72: - i = new Tryout (); + i = new Tryin (reinterpret_cast(node->operand[0].data), reinterpret_cast(node->operand[1].data)); break; case 73: - i = new Ushiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); + i = new Tryout (); break; case 74: - i = new VarXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data)); + i = new Ushiftright (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; case 75: - i = new Within (TypedRegister(static_cast(node->operand[0].data), 0)); + i = new VarXcr (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), static_cast(node->operand[2].data)); break; case 76: - i = new Without (); + i = new Within (TypedRegister(static_cast(node->operand[0].data), 0)); break; case 77: + i = new Without (); + break; + case 78: i = new Xor (TypedRegister(static_cast(node->operand[0].data), 0), TypedRegister(static_cast(node->operand[1].data), 0), TypedRegister(static_cast(node->operand[2].data), 0)); break; diff --git a/js2/src/interpreter.cpp b/js2/src/interpreter.cpp index 02e89123a87e..63886ef4f0f4 100644 --- a/js2/src/interpreter.cpp +++ b/js2/src/interpreter.cpp @@ -108,12 +108,6 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName) JSValues emptyArgs; JSValue result; - // save off important member variables, to enable recursive call to interpret. - // this is a little stinky, but should be exception-safe. - autosaver activation(mActivation, 0); - autosaver linkage(mLinkage, 0); - autosaver pc(mPC); - try { Arena a; Parser p(getWorld(), a, buffer, fileName); @@ -133,11 +127,12 @@ JSValue Context::readEvalFile(FILE* in, const String& fileName) stdOut << '\n'; /*******/ - // Generate code for parsedStatements, which is a linked + // Generate code for parsedStatements, which is a linked // list of zero or more statements ICodeModule* icm = genCode(parsedStatements, fileName); if (icm) { - result = interpret(icm, emptyArgs); + Context cx(getWorld(), getGlobalObject()); + result = cx.interpret(icm, emptyArgs); delete icm; } } catch (Exception &e) { @@ -538,8 +533,15 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args) case CAST: { Cast* c = static_cast(instruction); - JSType *toType = op3(c); - (*registers)[dst(c).first] = (*registers)[src1(c).first].convert(toType); + JSValue toTypeValue = (*registers)[op3(c).first]; + ASSERT(toTypeValue.isType()); + (*registers)[dst(c).first] = (*registers)[src1(c).first].convert(toTypeValue.type); + } + break; + case LOAD_TYPE: + { + LoadType *lt = static_cast(instruction); + (*registers)[dst(lt).first] = src1(lt); } break; case CLASS: diff --git a/js2/tools/jsicodes.pm b/js2/tools/jsicodes.pm index 12835e8b2072..c2764a269a3d 100644 --- a/js2/tools/jsicodes.pm +++ b/js2/tools/jsicodes.pm @@ -175,6 +175,12 @@ $ops{"LOAD_NAME"} = rem => "dest, name", params => [ ("TypedRegister", "const StringAtom*" ) ] }; +$ops{"LOAD_TYPE"} = + { + super => "Instruction_2", + rem => "dest, type", + params => [ ("TypedRegister", "JSType*" ) ] + }; $ops{"SUPER"} = { super => "Instruction_1", @@ -426,7 +432,7 @@ $ops{"CAST"} = { super => "Instruction_3", rem => "dest, rvalue, toType", - params => [ ("TypedRegister", "TypedRegister", "JSType*") ] + params => [ ("TypedRegister", "TypedRegister", "TypedRegister") ] }; $ops{"CLASS"} = {