зеркало из https://github.com/mozilla/pjs.git
Added notion of binding a 'this' to a method to construct a mini-closure
for call semantics. Fixed MSVC warnings from lexutils. Added BindThis instructionand removed 'this' from Call instruction (is now extracted from target argument).
This commit is contained in:
Родитель
2633790a83
Коммит
8ccb885553
|
@ -5,12 +5,13 @@
|
|||
enum {
|
||||
ADD, /* dest, source1, source2 */
|
||||
AND, /* dest, source1, source2 */
|
||||
BIND_THIS, /* result, this, target */
|
||||
BITNOT, /* dest, source */
|
||||
BRANCH, /* target label */
|
||||
BRANCH_FALSE, /* target label, condition */
|
||||
BRANCH_INITIALIZED, /* target label, condition */
|
||||
BRANCH_TRUE, /* target label, condition */
|
||||
CALL, /* result, target, this, args */
|
||||
CALL, /* result, target, args */
|
||||
CAST, /* dest, rvalue, toType */
|
||||
COMPARE_EQ, /* dest, source1, source2 */
|
||||
COMPARE_GE, /* dest, source1, source2 */
|
||||
|
@ -95,6 +96,22 @@
|
|||
/* print() and printOperands() inherited from Arithmetic */
|
||||
};
|
||||
|
||||
class BindThis : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* result, this, target */
|
||||
BindThis (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
||||
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
||||
(BIND_THIS, aOp1, aOp2, aOp3) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[BIND_THIS] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3;
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first);
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
class Bitnot : public Instruction_2<TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* dest, source */
|
||||
|
@ -153,18 +170,18 @@
|
|||
/* print() and printOperands() inherited from GenericBranch */
|
||||
};
|
||||
|
||||
class Call : public Instruction_4<TypedRegister, TypedRegister, TypedRegister, ArgumentList*> {
|
||||
class Call : public Instruction_3<TypedRegister, TypedRegister, ArgumentList*> {
|
||||
public:
|
||||
/* result, target, this, args */
|
||||
Call (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3, ArgumentList* aOp4) :
|
||||
Instruction_4<TypedRegister, TypedRegister, TypedRegister, ArgumentList*>
|
||||
(CALL, aOp1, aOp2, aOp3, aOp4) {};
|
||||
/* result, target, args */
|
||||
Call (TypedRegister aOp1, TypedRegister aOp2, ArgumentList* aOp3) :
|
||||
Instruction_3<TypedRegister, TypedRegister, ArgumentList*>
|
||||
(CALL, aOp1, aOp2, aOp3) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[CALL] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3 << ", " << mOp4;
|
||||
f << opcodeNames[CALL] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3;
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first);
|
||||
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first);
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
@ -1127,6 +1144,7 @@
|
|||
char *opcodeNames[] = {
|
||||
"ADD ",
|
||||
"AND ",
|
||||
"BIND_THIS ",
|
||||
"BITNOT ",
|
||||
"BRANCH ",
|
||||
"BRANCH_FALSE ",
|
||||
|
|
|
@ -475,10 +475,10 @@ TypedRegister ICodeGenerator::binaryOp(ICodeOp op, TypedRegister source1,
|
|||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::call(TypedRegister target, TypedRegister thisArg, ArgumentList *args)
|
||||
TypedRegister ICodeGenerator::call(TypedRegister target, ArgumentList *args)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Any_Type);
|
||||
Call *instr = new Call(dest, target, thisArg, args);
|
||||
Call *instr = new Call(dest, target, args);
|
||||
iCode->push_back(instr);
|
||||
return dest;
|
||||
}
|
||||
|
@ -491,6 +491,13 @@ TypedRegister ICodeGenerator::directCall(JSFunction *target, ArgumentList *args)
|
|||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::bindThis(TypedRegister thisArg, TypedRegister target)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Function_Type);
|
||||
iCode->push_back(new BindThis(dest, thisArg, target));
|
||||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::getMethod(TypedRegister thisArg, uint32 slotIndex)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Any_Type);
|
||||
|
@ -888,20 +895,20 @@ TypedRegister ICodeGenerator::handleIdentifier(IdentifierExprNode *p, ExprNode::
|
|||
{
|
||||
switch (lValueKind) {
|
||||
case Var:
|
||||
ret = call(v, TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(v, args);
|
||||
break;
|
||||
case Name:
|
||||
ret = call(loadName(name), TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(loadName(name), args);
|
||||
break;
|
||||
case Method:
|
||||
ret = call(getMethod(thisBase, slotIndex), thisBase, args);
|
||||
ret = call(getMethod(thisBase, slotIndex), args);
|
||||
break;
|
||||
case Static:
|
||||
ret = call(getStatic(mClass, name), TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(getStatic(mClass, name), args);
|
||||
break;
|
||||
case Constructor:
|
||||
ret = newClass(mClass);
|
||||
call(getStatic(mClass, name), ret, args);
|
||||
call(bindThis(ret, getStatic(mClass, name)), args);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad lvalue kind");
|
||||
|
@ -981,17 +988,17 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
|
|||
case ExprNode::call:
|
||||
switch (lValueKind) {
|
||||
case Static:
|
||||
ret = call(getStatic(clazz, fieldName), TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(getStatic(clazz, fieldName), args);
|
||||
break;
|
||||
case Constructor:
|
||||
ret = newClass(clazz);
|
||||
call(getStatic(clazz, fieldName), ret, args);
|
||||
call(bindThis(ret, getStatic(clazz, fieldName)), args);
|
||||
break;
|
||||
case Property:
|
||||
ret = call(getProperty(base, fieldName), base, args);
|
||||
ret = call(bindThis(base, getProperty(base, fieldName)), args);
|
||||
break;
|
||||
case Method:
|
||||
ret = call(getMethod(base, slotIndex), base, args);
|
||||
ret = call(getMethod(base, slotIndex), args);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad lvalue kind");
|
||||
|
@ -1020,6 +1027,9 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
|
|||
case Slot:
|
||||
v = getSlot(base, slotIndex);
|
||||
break;
|
||||
case Method:
|
||||
v = getMethod(base, slotIndex);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad lvalue kind");
|
||||
}
|
||||
|
@ -1170,7 +1180,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
JSClass* clazz = dynamic_cast<JSClass*>(value.type);
|
||||
if (clazz) {
|
||||
ret = newClass(clazz);
|
||||
ret = call(getStatic(clazz, className), ret, args);
|
||||
ret = call(bindThis(ret, getStatic(clazz, className)), args);
|
||||
}
|
||||
else {
|
||||
//
|
||||
|
@ -1187,7 +1197,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
if (value.isFunction()) {
|
||||
TypedRegister f = loadName(className, value.type);
|
||||
ret = newObject(f);
|
||||
ret = call(f, ret, args);
|
||||
ret = call(bindThis(ret, f), args);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("new <name>, where <name> is not a function"); // XXX Runtime error.
|
||||
|
@ -1238,7 +1248,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
if (i->op->getKind() == ExprNode::index) {
|
||||
InvokeExprNode *ii = static_cast<InvokeExprNode *>(i->op);
|
||||
TypedRegister base = genExpr(ii->op);
|
||||
ret = call(getElement(base, genExpr(ii->pairs->value)), base, args); // FIXME, only taking first index
|
||||
ret = call(bindThis(base, getElement(base, genExpr(ii->pairs->value))), args); // FIXME, only taking first index
|
||||
}
|
||||
else
|
||||
ASSERT("WAH!");
|
||||
|
@ -1762,11 +1772,11 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f, bool isConstructor
|
|||
}
|
||||
}
|
||||
if (!foundSuperCall) { // invoke the default superclass constructor
|
||||
icg.call(icg.getStatic(superclass, superclass->getName()), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
}
|
||||
}
|
||||
if (mClass->hasStatic(mInitName))
|
||||
icg.call(icg.getStatic(mClass, mInitName), thisValue, args); // ok, so it's mis-named
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(mClass, mInitName)), args); // ok, so it's mis-named
|
||||
|
||||
}
|
||||
if (f->function.body)
|
||||
|
@ -1981,9 +1991,9 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
|
|||
ICodeGenerator icg(classContext, thisClass, kIsStaticMethod);
|
||||
icg.allocateParameter(mContext->getWorld().identifiers["this"], false, thisClass); // always parameter #0
|
||||
if (superclass)
|
||||
icg.call(icg.getStatic(superclass, superclass->getName()), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
if (thisClass->hasStatic(mInitName))
|
||||
icg.call(icg.getStatic(thisClass, mInitName), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(thisClass, mInitName)), args);
|
||||
icg.returnStmt(thisValue);
|
||||
thisClass->defineConstructor(nameExpr->name);
|
||||
scg.setStatic(thisClass, nameExpr->name, scg.newFunction(icg.complete(&Void_Type)));
|
||||
|
@ -2534,9 +2544,9 @@ void ICodeGenerator::readICode(const char *fileName)
|
|||
ICodeGenerator icg(mContext, thisClass, kIsStaticMethod);
|
||||
icg.allocateParameter(mContext->getWorld().identifiers["this"], false, thisClass); // always parameter #0
|
||||
if (superclass)
|
||||
icg.call(icg.getStatic(superclass, superclass->getName()), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
if (thisClass->hasStatic(mInitName))
|
||||
icg.call(icg.getStatic(thisClass, mInitName), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(thisClass, mInitName)), args);
|
||||
icg.returnStmt(thisValue);
|
||||
thisClass->defineConstructor(className);
|
||||
scg.setStatic(thisClass, mContext->getWorld().identifiers[className], scg.newFunction(icg.complete(&Void_Type)));
|
||||
|
|
|
@ -348,8 +348,9 @@ namespace ICG {
|
|||
TypedRegister op(ICodeOp op, TypedRegister source);
|
||||
TypedRegister op(ICodeOp op, TypedRegister source1, TypedRegister source2);
|
||||
TypedRegister binaryOp(ICodeOp op, TypedRegister source1, TypedRegister source2);
|
||||
TypedRegister call(TypedRegister base, TypedRegister target, ArgumentList *args);
|
||||
TypedRegister call(TypedRegister target, ArgumentList *args);
|
||||
TypedRegister directCall(JSFunction *target, ArgumentList *args);
|
||||
TypedRegister bindThis(TypedRegister thisArg, TypedRegister target);
|
||||
TypedRegister getMethod(TypedRegister thisArg, uint32 slotIndex);
|
||||
|
||||
void move(TypedRegister destination, TypedRegister source);
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
namespace JavaScript {
|
||||
namespace ICodeASM {
|
||||
|
||||
static uint icodemap_size = 72;
|
||||
static uint icodemap_size = 73;
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
|
@ -53,12 +53,13 @@ namespace ICodeASM {
|
|||
} icodemap [] = {
|
||||
{"ADD", {otRegister, otRegister, otRegister}},
|
||||
{"AND", {otRegister, otRegister, otRegister}},
|
||||
{"BIND_THIS", {otRegister, otRegister, otRegister}},
|
||||
{"BITNOT", {otRegister, otRegister}},
|
||||
{"BRANCH", {otLabel}},
|
||||
{"BRANCH_FALSE", {otLabel, otRegister}},
|
||||
{"BRANCH_INITIALIZED", {otLabel, otRegister}},
|
||||
{"BRANCH_TRUE", {otLabel, otRegister}},
|
||||
{"CALL", {otRegister, otRegister, otRegister, otArgumentList}},
|
||||
{"CALL", {otRegister, otRegister, otArgumentList}},
|
||||
{"CAST", {otRegister, otRegister, otJSType}},
|
||||
{"COMPARE_EQ", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_GE", {otRegister, otRegister, otRegister}},
|
||||
|
@ -140,213 +141,216 @@ namespace ICodeASM {
|
|||
i = new And (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 2:
|
||||
i = new Bitnot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new BindThis (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 3:
|
||||
i = new Branch (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
i = new Bitnot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 4:
|
||||
i = new BranchFalse (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Branch (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
break;
|
||||
case 5:
|
||||
i = new BranchInitialized (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new BranchFalse (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 6:
|
||||
i = new BranchTrue (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new BranchInitialized (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 7:
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), reinterpret_cast<ArgumentList*>(node->operand[3].data));
|
||||
i = new BranchTrue (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 8:
|
||||
i = new Cast (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<JSType*>(node->operand[2].data));
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<ArgumentList*>(node->operand[2].data));
|
||||
break;
|
||||
case 9:
|
||||
i = new CompareEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Cast (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<JSType*>(node->operand[2].data));
|
||||
break;
|
||||
case 10:
|
||||
i = new CompareGE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 11:
|
||||
i = new CompareGT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareGE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 12:
|
||||
i = new CompareIN (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareGT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 13:
|
||||
i = new CompareLE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareIN (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 14:
|
||||
i = new CompareLT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareLE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 15:
|
||||
i = new CompareNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareLT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 16:
|
||||
i = new Debugger ();
|
||||
i = new CompareNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 17:
|
||||
i = new DeleteProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
i = new Debugger ();
|
||||
break;
|
||||
case 18:
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), reinterpret_cast<ArgumentList*>(node->operand[2].data));
|
||||
i = new DeleteProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
break;
|
||||
case 19:
|
||||
i = new Divide (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), reinterpret_cast<ArgumentList*>(node->operand[2].data));
|
||||
break;
|
||||
case 20:
|
||||
i = new ElemXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), static_cast<double>(node->operand[3].data));
|
||||
i = new Divide (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 21:
|
||||
i = new GenericBinaryOP (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<BinaryOperator::BinaryOp>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0), TypedRegister(static_cast<Register>(node->operand[3].data), 0));
|
||||
i = new ElemXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 22:
|
||||
i = new GetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new GenericBinaryOP (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<BinaryOperator::BinaryOp>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0), TypedRegister(static_cast<Register>(node->operand[3].data), 0));
|
||||
break;
|
||||
case 23:
|
||||
i = new GetMethod (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
i = new GetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 24:
|
||||
i = new GetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
i = new GetMethod (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
break;
|
||||
case 25:
|
||||
i = new GetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
i = new GetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
break;
|
||||
case 26:
|
||||
i = new GetStatic (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data));
|
||||
i = new GetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
break;
|
||||
case 27:
|
||||
i = new Instanceof (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new GetStatic (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data));
|
||||
break;
|
||||
case 28:
|
||||
i = new Jsr (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
i = new Instanceof (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 29:
|
||||
i = new LoadBoolean (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<bool>(node->operand[1].data));
|
||||
i = new Jsr (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
break;
|
||||
case 30:
|
||||
i = new LoadImmediate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<double>(node->operand[1].data));
|
||||
i = new LoadBoolean (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<bool>(node->operand[1].data));
|
||||
break;
|
||||
case 31:
|
||||
i = new LoadName (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data));
|
||||
i = new LoadImmediate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<double>(node->operand[1].data));
|
||||
break;
|
||||
case 32:
|
||||
i = new LoadString (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSString*>(node->operand[1].data));
|
||||
i = new LoadName (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data));
|
||||
break;
|
||||
case 33:
|
||||
i = new Move (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new LoadString (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSString*>(node->operand[1].data));
|
||||
break;
|
||||
case 34:
|
||||
i = new Multiply (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Move (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 35:
|
||||
i = new NameXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), static_cast<double>(node->operand[2].data));
|
||||
i = new Multiply (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 36:
|
||||
i = new Negate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new NameXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), static_cast<double>(node->operand[2].data));
|
||||
break;
|
||||
case 37:
|
||||
i = new NewArray (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Negate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 38:
|
||||
i = new NewClass (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data));
|
||||
i = new NewArray (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 39:
|
||||
i = new NewFunction (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<ICodeModule*>(node->operand[1].data));
|
||||
i = new NewClass (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data));
|
||||
break;
|
||||
case 40:
|
||||
i = new NewObject (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new NewFunction (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<ICodeModule*>(node->operand[1].data));
|
||||
break;
|
||||
case 41:
|
||||
i = new Nop ();
|
||||
i = new NewObject (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 42:
|
||||
i = new Not (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Nop ();
|
||||
break;
|
||||
case 43:
|
||||
i = new Or (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Not (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 44:
|
||||
i = new Posate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Or (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 45:
|
||||
i = new PropXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
i = new Posate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 46:
|
||||
i = new Remainder (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new PropXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 47:
|
||||
i = new Return (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Remainder (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 48:
|
||||
i = new ReturnVoid ();
|
||||
i = new Return (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 49:
|
||||
i = new Rts ();
|
||||
i = new ReturnVoid ();
|
||||
break;
|
||||
case 50:
|
||||
i = new SaveName (reinterpret_cast<const StringAtom*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Rts ();
|
||||
break;
|
||||
case 51:
|
||||
i = new SetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SaveName (reinterpret_cast<const StringAtom*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 52:
|
||||
i = new SetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 53:
|
||||
i = new SetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 54:
|
||||
i = new SetStatic (reinterpret_cast<JSClass*>(node->operand[0].data), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 55:
|
||||
i = new Shiftleft (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetStatic (reinterpret_cast<JSClass*>(node->operand[0].data), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 56:
|
||||
i = new Shiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Shiftleft (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 57:
|
||||
i = new SlotXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
i = new Shiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 58:
|
||||
i = new StaticXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
i = new SlotXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 59:
|
||||
i = new StrictEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new StaticXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 60:
|
||||
i = new StrictNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new StrictEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 61:
|
||||
i = new Subtract (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new StrictNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 62:
|
||||
i = new Super (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Subtract (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 63:
|
||||
i = new Test (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Super (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 64:
|
||||
i = new Throw (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Test (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 65:
|
||||
i = new Tryin (reinterpret_cast<Label*>(node->operand[0].data), reinterpret_cast<Label*>(node->operand[1].data));
|
||||
i = new Throw (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 66:
|
||||
i = new Tryout ();
|
||||
i = new Tryin (reinterpret_cast<Label*>(node->operand[0].data), reinterpret_cast<Label*>(node->operand[1].data));
|
||||
break;
|
||||
case 67:
|
||||
i = new Ushiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Tryout ();
|
||||
break;
|
||||
case 68:
|
||||
i = new VarXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<double>(node->operand[2].data));
|
||||
i = new Ushiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 69:
|
||||
i = new Within (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new VarXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<double>(node->operand[2].data));
|
||||
break;
|
||||
case 70:
|
||||
i = new Without ();
|
||||
i = new Within (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 71:
|
||||
i = new Without ();
|
||||
break;
|
||||
case 72:
|
||||
i = new Xor (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
|
||||
|
|
|
@ -695,7 +695,17 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
ASSERT(base.isObject()); // XXX runtime error
|
||||
JSClass *theClass = dynamic_cast<JSClass*>(base.object->getType());
|
||||
ASSERT(theClass);
|
||||
(*registers)[dst(gm).first] = theClass->getMethod(src2(gm));
|
||||
(*registers)[dst(gm).first] = new JSBoundThis(base, theClass->getMethod(src2(gm)));
|
||||
}
|
||||
break;
|
||||
|
||||
case BIND_THIS:
|
||||
{
|
||||
BindThis* bt = static_cast<BindThis*>(instruction);
|
||||
JSValue base = (*registers)[src1(bt).first];
|
||||
JSValue target = (*registers)[src2(bt).first];
|
||||
ASSERT(target.isFunction());
|
||||
(*registers)[dst(bt).first] = new JSBoundThis(base, target.function);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -715,9 +725,9 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
if (!target)
|
||||
throw new JSException("Call to non callable object");
|
||||
if (target->isNative()) {
|
||||
ArgumentList *params = op4(call);
|
||||
ArgumentList *params = op3(call);
|
||||
JSValues argv(params->size() + 1);
|
||||
argv[0] = (*registers)[op3(call).first];
|
||||
argv[0] = target->getThis(); //(*registers)[op3(call).first];
|
||||
JSValues::size_type i = 1;
|
||||
for (ArgumentList::const_iterator src = params->begin(), end = params->end();
|
||||
src != end; ++src, ++i) {
|
||||
|
@ -730,7 +740,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
}
|
||||
else {
|
||||
ICodeModule *icm = target->getICode();
|
||||
ArgumentList *args = op4(call);
|
||||
ArgumentList *args = op3(call);
|
||||
|
||||
// if all the parameters are positional
|
||||
// if (icm->itsParameters->mPositionalCount == icm->itsParameters->size())
|
||||
|
@ -824,7 +834,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
}
|
||||
|
||||
mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, op1(call));
|
||||
mActivation = new Activation(icm, mActivation, (*registers)[op3(call).first], callArgs);
|
||||
mActivation = new Activation(icm, mActivation, target->getThis()/*(*registers)[op3(call).first]*/, callArgs);
|
||||
registers = &mActivation->mRegisters;
|
||||
mPC = mActivation->mICode->its_iCode->begin();
|
||||
endPC = mActivation->mICode->its_iCode->end();
|
||||
|
|
|
@ -348,6 +348,7 @@ namespace JSClasses {
|
|||
}
|
||||
|
||||
#if !defined(XP_MAC)
|
||||
void operator delete(void* /*ptr*/) {}
|
||||
void operator delete(void* /*ptr*/, JSClass* /*thisClass*/) {}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -834,6 +834,13 @@ JSValue JSValue::convert(JSType *toType)
|
|||
return valueToInteger(*this);
|
||||
else if (toType == &String_Type)
|
||||
return valueToString(*this);
|
||||
else if (toType == &Function_Type)
|
||||
{
|
||||
if (tag == function_tag)
|
||||
return *this;
|
||||
else
|
||||
throw new JSException("Can't cast to function");
|
||||
}
|
||||
else {
|
||||
JSClass *toClass = dynamic_cast<JSClass *>(toType);
|
||||
if (toClass) {
|
||||
|
@ -860,7 +867,7 @@ JSValue JSValue::convert(JSType *toType)
|
|||
|
||||
JSFunction::~JSFunction()
|
||||
{
|
||||
delete mICode;
|
||||
if (mICode) delete mICode;
|
||||
}
|
||||
|
||||
JSString::JSString(const String& str)
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace JSTypes {
|
|||
|
||||
typedef uint32 Register;
|
||||
|
||||
|
||||
/**
|
||||
* All JavaScript data types.
|
||||
*/
|
||||
|
@ -270,16 +271,13 @@ namespace JSTypes {
|
|||
JSObject() { init(ObjectPrototypeObject); }
|
||||
JSObject(JSValue &constructor) { init(constructor.object->getProperty(widenCString("prototype")).object); }
|
||||
JSObject(JSObject *prototype) { init(prototype); }
|
||||
/*
|
||||
|
||||
I wanted to have this, but VCC complains about JSInstance instances not being deletable...
|
||||
|
||||
virtual ~JSObject()
|
||||
{
|
||||
if (mGetter) delete mGetter;
|
||||
if (mSetter) delete mSetter;
|
||||
}
|
||||
*/
|
||||
|
||||
static void initObjectObject(JSScope *g);
|
||||
|
||||
bool hasProperty(const String& name)
|
||||
|
@ -501,11 +499,11 @@ namespace JSTypes {
|
|||
* compiled code of the function.
|
||||
*/
|
||||
class JSFunction : public JSObject {
|
||||
protected:
|
||||
static JSString* FunctionString;
|
||||
static JSObject* FunctionPrototypeObject;
|
||||
ICodeModule* mICode;
|
||||
|
||||
protected:
|
||||
|
||||
typedef JavaScript::gc_traits_finalizable<JSFunction> traits;
|
||||
typedef gc_allocator<JSFunction, traits> allocator;
|
||||
|
@ -522,7 +520,9 @@ namespace JSTypes {
|
|||
setClass(FunctionString);
|
||||
}
|
||||
|
||||
~JSFunction();
|
||||
virtual ~JSFunction();
|
||||
|
||||
virtual JSValue getThis() { return kNullValue; }
|
||||
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
|
||||
|
@ -530,20 +530,37 @@ namespace JSTypes {
|
|||
virtual bool isNative() { return false; }
|
||||
};
|
||||
|
||||
class JSBoundThis : public JSFunction {
|
||||
typedef JavaScript::gc_traits_finalizable<JSBoundThis> traits;
|
||||
typedef gc_allocator<JSBoundThis, traits> allocator;
|
||||
public:
|
||||
JSBoundThis(JSValue aThis, JSFunction *aFunc) : JSFunction(*aFunc) { mBoundThis = aThis; }
|
||||
JSValue mBoundThis;
|
||||
virtual ~JSBoundThis() { mICode = NULL; }
|
||||
virtual JSValue getThis() { return mBoundThis; }
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
};
|
||||
|
||||
class JSNativeFunction : public JSFunction {
|
||||
typedef JavaScript::gc_traits_finalizable<JSNativeFunction> traits;
|
||||
typedef gc_allocator<JSNativeFunction, traits> allocator;
|
||||
public:
|
||||
typedef JSValue (*JSCode)(Context *cx, const JSValues& argv);
|
||||
JSCode mCode;
|
||||
JSNativeFunction(JSCode code) : mCode(code) {}
|
||||
virtual bool isNative() { return true; }
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
};
|
||||
|
||||
class JSBinaryOperator : public JSFunction {
|
||||
typedef JavaScript::gc_traits_finalizable<JSBinaryOperator> traits;
|
||||
typedef gc_allocator<JSBinaryOperator, traits> allocator;
|
||||
public:
|
||||
typedef JSValue (*JSBinaryCode)(const JSValue& arg1, const JSValue& arg2);
|
||||
JSBinaryCode mCode;
|
||||
JSBinaryOperator(JSBinaryCode code) : mCode(code) {}
|
||||
virtual bool isNative() { return true; }
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
// Turn off warnings about identifiers too long in browser information
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
|
||||
#include "lexutils.h"
|
||||
|
||||
namespace JavaScript {
|
||||
|
|
|
@ -5,12 +5,13 @@
|
|||
enum {
|
||||
ADD, /* dest, source1, source2 */
|
||||
AND, /* dest, source1, source2 */
|
||||
BIND_THIS, /* result, this, target */
|
||||
BITNOT, /* dest, source */
|
||||
BRANCH, /* target label */
|
||||
BRANCH_FALSE, /* target label, condition */
|
||||
BRANCH_INITIALIZED, /* target label, condition */
|
||||
BRANCH_TRUE, /* target label, condition */
|
||||
CALL, /* result, target, this, args */
|
||||
CALL, /* result, target, args */
|
||||
CAST, /* dest, rvalue, toType */
|
||||
COMPARE_EQ, /* dest, source1, source2 */
|
||||
COMPARE_GE, /* dest, source1, source2 */
|
||||
|
@ -95,6 +96,22 @@
|
|||
/* print() and printOperands() inherited from Arithmetic */
|
||||
};
|
||||
|
||||
class BindThis : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* result, this, target */
|
||||
BindThis (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
|
||||
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
|
||||
(BIND_THIS, aOp1, aOp2, aOp3) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[BIND_THIS] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3;
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first);
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
||||
class Bitnot : public Instruction_2<TypedRegister, TypedRegister> {
|
||||
public:
|
||||
/* dest, source */
|
||||
|
@ -153,18 +170,18 @@
|
|||
/* print() and printOperands() inherited from GenericBranch */
|
||||
};
|
||||
|
||||
class Call : public Instruction_4<TypedRegister, TypedRegister, TypedRegister, ArgumentList*> {
|
||||
class Call : public Instruction_3<TypedRegister, TypedRegister, ArgumentList*> {
|
||||
public:
|
||||
/* result, target, this, args */
|
||||
Call (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3, ArgumentList* aOp4) :
|
||||
Instruction_4<TypedRegister, TypedRegister, TypedRegister, ArgumentList*>
|
||||
(CALL, aOp1, aOp2, aOp3, aOp4) {};
|
||||
/* result, target, args */
|
||||
Call (TypedRegister aOp1, TypedRegister aOp2, ArgumentList* aOp3) :
|
||||
Instruction_3<TypedRegister, TypedRegister, ArgumentList*>
|
||||
(CALL, aOp1, aOp2, aOp3) {};
|
||||
virtual Formatter& print(Formatter& f) {
|
||||
f << opcodeNames[CALL] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3 << ", " << mOp4;
|
||||
f << opcodeNames[CALL] << "\t" << mOp1 << ", " << mOp2 << ", " << mOp3;
|
||||
return f;
|
||||
}
|
||||
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
|
||||
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first) << ", " << getRegisterValue(registers, mOp3.first);
|
||||
f << getRegisterValue(registers, mOp1.first) << ", " << getRegisterValue(registers, mOp2.first);
|
||||
return f;
|
||||
}
|
||||
};
|
||||
|
@ -1127,6 +1144,7 @@
|
|||
char *opcodeNames[] = {
|
||||
"ADD ",
|
||||
"AND ",
|
||||
"BIND_THIS ",
|
||||
"BITNOT ",
|
||||
"BRANCH ",
|
||||
"BRANCH_FALSE ",
|
||||
|
|
|
@ -475,10 +475,10 @@ TypedRegister ICodeGenerator::binaryOp(ICodeOp op, TypedRegister source1,
|
|||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::call(TypedRegister target, TypedRegister thisArg, ArgumentList *args)
|
||||
TypedRegister ICodeGenerator::call(TypedRegister target, ArgumentList *args)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Any_Type);
|
||||
Call *instr = new Call(dest, target, thisArg, args);
|
||||
Call *instr = new Call(dest, target, args);
|
||||
iCode->push_back(instr);
|
||||
return dest;
|
||||
}
|
||||
|
@ -491,6 +491,13 @@ TypedRegister ICodeGenerator::directCall(JSFunction *target, ArgumentList *args)
|
|||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::bindThis(TypedRegister thisArg, TypedRegister target)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Function_Type);
|
||||
iCode->push_back(new BindThis(dest, thisArg, target));
|
||||
return dest;
|
||||
}
|
||||
|
||||
TypedRegister ICodeGenerator::getMethod(TypedRegister thisArg, uint32 slotIndex)
|
||||
{
|
||||
TypedRegister dest(getTempRegister(), &Any_Type);
|
||||
|
@ -888,20 +895,20 @@ TypedRegister ICodeGenerator::handleIdentifier(IdentifierExprNode *p, ExprNode::
|
|||
{
|
||||
switch (lValueKind) {
|
||||
case Var:
|
||||
ret = call(v, TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(v, args);
|
||||
break;
|
||||
case Name:
|
||||
ret = call(loadName(name), TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(loadName(name), args);
|
||||
break;
|
||||
case Method:
|
||||
ret = call(getMethod(thisBase, slotIndex), thisBase, args);
|
||||
ret = call(getMethod(thisBase, slotIndex), args);
|
||||
break;
|
||||
case Static:
|
||||
ret = call(getStatic(mClass, name), TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(getStatic(mClass, name), args);
|
||||
break;
|
||||
case Constructor:
|
||||
ret = newClass(mClass);
|
||||
call(getStatic(mClass, name), ret, args);
|
||||
call(bindThis(ret, getStatic(mClass, name)), args);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad lvalue kind");
|
||||
|
@ -981,17 +988,17 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
|
|||
case ExprNode::call:
|
||||
switch (lValueKind) {
|
||||
case Static:
|
||||
ret = call(getStatic(clazz, fieldName), TypedRegister(NotARegister, &Null_Type), args);
|
||||
ret = call(getStatic(clazz, fieldName), args);
|
||||
break;
|
||||
case Constructor:
|
||||
ret = newClass(clazz);
|
||||
call(getStatic(clazz, fieldName), ret, args);
|
||||
call(bindThis(ret, getStatic(clazz, fieldName)), args);
|
||||
break;
|
||||
case Property:
|
||||
ret = call(getProperty(base, fieldName), base, args);
|
||||
ret = call(bindThis(base, getProperty(base, fieldName)), args);
|
||||
break;
|
||||
case Method:
|
||||
ret = call(getMethod(base, slotIndex), base, args);
|
||||
ret = call(getMethod(base, slotIndex), args);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad lvalue kind");
|
||||
|
@ -1020,6 +1027,9 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
|
|||
case Slot:
|
||||
v = getSlot(base, slotIndex);
|
||||
break;
|
||||
case Method:
|
||||
v = getMethod(base, slotIndex);
|
||||
break;
|
||||
default:
|
||||
NOT_REACHED("Bad lvalue kind");
|
||||
}
|
||||
|
@ -1170,7 +1180,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
JSClass* clazz = dynamic_cast<JSClass*>(value.type);
|
||||
if (clazz) {
|
||||
ret = newClass(clazz);
|
||||
ret = call(getStatic(clazz, className), ret, args);
|
||||
ret = call(bindThis(ret, getStatic(clazz, className)), args);
|
||||
}
|
||||
else {
|
||||
//
|
||||
|
@ -1187,7 +1197,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
if (value.isFunction()) {
|
||||
TypedRegister f = loadName(className, value.type);
|
||||
ret = newObject(f);
|
||||
ret = call(f, ret, args);
|
||||
ret = call(bindThis(ret, f), args);
|
||||
}
|
||||
else
|
||||
NOT_REACHED("new <name>, where <name> is not a function"); // XXX Runtime error.
|
||||
|
@ -1238,7 +1248,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
|
|||
if (i->op->getKind() == ExprNode::index) {
|
||||
InvokeExprNode *ii = static_cast<InvokeExprNode *>(i->op);
|
||||
TypedRegister base = genExpr(ii->op);
|
||||
ret = call(getElement(base, genExpr(ii->pairs->value)), base, args); // FIXME, only taking first index
|
||||
ret = call(bindThis(base, getElement(base, genExpr(ii->pairs->value))), args); // FIXME, only taking first index
|
||||
}
|
||||
else
|
||||
ASSERT("WAH!");
|
||||
|
@ -1762,11 +1772,11 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f, bool isConstructor
|
|||
}
|
||||
}
|
||||
if (!foundSuperCall) { // invoke the default superclass constructor
|
||||
icg.call(icg.getStatic(superclass, superclass->getName()), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
}
|
||||
}
|
||||
if (mClass->hasStatic(mInitName))
|
||||
icg.call(icg.getStatic(mClass, mInitName), thisValue, args); // ok, so it's mis-named
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(mClass, mInitName)), args); // ok, so it's mis-named
|
||||
|
||||
}
|
||||
if (f->function.body)
|
||||
|
@ -1981,9 +1991,9 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
|
|||
ICodeGenerator icg(classContext, thisClass, kIsStaticMethod);
|
||||
icg.allocateParameter(mContext->getWorld().identifiers["this"], false, thisClass); // always parameter #0
|
||||
if (superclass)
|
||||
icg.call(icg.getStatic(superclass, superclass->getName()), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
if (thisClass->hasStatic(mInitName))
|
||||
icg.call(icg.getStatic(thisClass, mInitName), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(thisClass, mInitName)), args);
|
||||
icg.returnStmt(thisValue);
|
||||
thisClass->defineConstructor(nameExpr->name);
|
||||
scg.setStatic(thisClass, nameExpr->name, scg.newFunction(icg.complete(&Void_Type)));
|
||||
|
@ -2534,9 +2544,9 @@ void ICodeGenerator::readICode(const char *fileName)
|
|||
ICodeGenerator icg(mContext, thisClass, kIsStaticMethod);
|
||||
icg.allocateParameter(mContext->getWorld().identifiers["this"], false, thisClass); // always parameter #0
|
||||
if (superclass)
|
||||
icg.call(icg.getStatic(superclass, superclass->getName()), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(superclass, superclass->getName())), args);
|
||||
if (thisClass->hasStatic(mInitName))
|
||||
icg.call(icg.getStatic(thisClass, mInitName), thisValue, args);
|
||||
icg.call(icg.bindThis(thisValue, icg.getStatic(thisClass, mInitName)), args);
|
||||
icg.returnStmt(thisValue);
|
||||
thisClass->defineConstructor(className);
|
||||
scg.setStatic(thisClass, mContext->getWorld().identifiers[className], scg.newFunction(icg.complete(&Void_Type)));
|
||||
|
|
|
@ -348,8 +348,9 @@ namespace ICG {
|
|||
TypedRegister op(ICodeOp op, TypedRegister source);
|
||||
TypedRegister op(ICodeOp op, TypedRegister source1, TypedRegister source2);
|
||||
TypedRegister binaryOp(ICodeOp op, TypedRegister source1, TypedRegister source2);
|
||||
TypedRegister call(TypedRegister base, TypedRegister target, ArgumentList *args);
|
||||
TypedRegister call(TypedRegister target, ArgumentList *args);
|
||||
TypedRegister directCall(JSFunction *target, ArgumentList *args);
|
||||
TypedRegister bindThis(TypedRegister thisArg, TypedRegister target);
|
||||
TypedRegister getMethod(TypedRegister thisArg, uint32 slotIndex);
|
||||
|
||||
void move(TypedRegister destination, TypedRegister source);
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
namespace JavaScript {
|
||||
namespace ICodeASM {
|
||||
|
||||
static uint icodemap_size = 72;
|
||||
static uint icodemap_size = 73;
|
||||
|
||||
static struct {
|
||||
char *name;
|
||||
|
@ -53,12 +53,13 @@ namespace ICodeASM {
|
|||
} icodemap [] = {
|
||||
{"ADD", {otRegister, otRegister, otRegister}},
|
||||
{"AND", {otRegister, otRegister, otRegister}},
|
||||
{"BIND_THIS", {otRegister, otRegister, otRegister}},
|
||||
{"BITNOT", {otRegister, otRegister}},
|
||||
{"BRANCH", {otLabel}},
|
||||
{"BRANCH_FALSE", {otLabel, otRegister}},
|
||||
{"BRANCH_INITIALIZED", {otLabel, otRegister}},
|
||||
{"BRANCH_TRUE", {otLabel, otRegister}},
|
||||
{"CALL", {otRegister, otRegister, otRegister, otArgumentList}},
|
||||
{"CALL", {otRegister, otRegister, otArgumentList}},
|
||||
{"CAST", {otRegister, otRegister, otJSType}},
|
||||
{"COMPARE_EQ", {otRegister, otRegister, otRegister}},
|
||||
{"COMPARE_GE", {otRegister, otRegister, otRegister}},
|
||||
|
@ -140,213 +141,216 @@ namespace ICodeASM {
|
|||
i = new And (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 2:
|
||||
i = new Bitnot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new BindThis (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 3:
|
||||
i = new Branch (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
i = new Bitnot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 4:
|
||||
i = new BranchFalse (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Branch (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
break;
|
||||
case 5:
|
||||
i = new BranchInitialized (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new BranchFalse (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 6:
|
||||
i = new BranchTrue (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new BranchInitialized (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 7:
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), reinterpret_cast<ArgumentList*>(node->operand[3].data));
|
||||
i = new BranchTrue (reinterpret_cast<Label*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 8:
|
||||
i = new Cast (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<JSType*>(node->operand[2].data));
|
||||
i = new Call (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<ArgumentList*>(node->operand[2].data));
|
||||
break;
|
||||
case 9:
|
||||
i = new CompareEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Cast (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<JSType*>(node->operand[2].data));
|
||||
break;
|
||||
case 10:
|
||||
i = new CompareGE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 11:
|
||||
i = new CompareGT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareGE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 12:
|
||||
i = new CompareIN (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareGT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 13:
|
||||
i = new CompareLE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareIN (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 14:
|
||||
i = new CompareLT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareLE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 15:
|
||||
i = new CompareNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new CompareLT (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 16:
|
||||
i = new Debugger ();
|
||||
i = new CompareNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 17:
|
||||
i = new DeleteProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
i = new Debugger ();
|
||||
break;
|
||||
case 18:
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), reinterpret_cast<ArgumentList*>(node->operand[2].data));
|
||||
i = new DeleteProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
break;
|
||||
case 19:
|
||||
i = new Divide (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new DirectCall (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSFunction*>(node->operand[1].data), reinterpret_cast<ArgumentList*>(node->operand[2].data));
|
||||
break;
|
||||
case 20:
|
||||
i = new ElemXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), static_cast<double>(node->operand[3].data));
|
||||
i = new Divide (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 21:
|
||||
i = new GenericBinaryOP (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<BinaryOperator::BinaryOp>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0), TypedRegister(static_cast<Register>(node->operand[3].data), 0));
|
||||
i = new ElemXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 22:
|
||||
i = new GetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new GenericBinaryOP (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<BinaryOperator::BinaryOp>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0), TypedRegister(static_cast<Register>(node->operand[3].data), 0));
|
||||
break;
|
||||
case 23:
|
||||
i = new GetMethod (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
i = new GetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 24:
|
||||
i = new GetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
i = new GetMethod (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
break;
|
||||
case 25:
|
||||
i = new GetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
i = new GetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data));
|
||||
break;
|
||||
case 26:
|
||||
i = new GetStatic (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data));
|
||||
i = new GetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data));
|
||||
break;
|
||||
case 27:
|
||||
i = new Instanceof (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new GetStatic (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data));
|
||||
break;
|
||||
case 28:
|
||||
i = new Jsr (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
i = new Instanceof (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 29:
|
||||
i = new LoadBoolean (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<bool>(node->operand[1].data));
|
||||
i = new Jsr (reinterpret_cast<Label*>(node->operand[0].data));
|
||||
break;
|
||||
case 30:
|
||||
i = new LoadImmediate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<double>(node->operand[1].data));
|
||||
i = new LoadBoolean (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<bool>(node->operand[1].data));
|
||||
break;
|
||||
case 31:
|
||||
i = new LoadName (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data));
|
||||
i = new LoadImmediate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<double>(node->operand[1].data));
|
||||
break;
|
||||
case 32:
|
||||
i = new LoadString (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSString*>(node->operand[1].data));
|
||||
i = new LoadName (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data));
|
||||
break;
|
||||
case 33:
|
||||
i = new Move (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new LoadString (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSString*>(node->operand[1].data));
|
||||
break;
|
||||
case 34:
|
||||
i = new Multiply (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Move (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 35:
|
||||
i = new NameXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), static_cast<double>(node->operand[2].data));
|
||||
i = new Multiply (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 36:
|
||||
i = new Negate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new NameXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), static_cast<double>(node->operand[2].data));
|
||||
break;
|
||||
case 37:
|
||||
i = new NewArray (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Negate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 38:
|
||||
i = new NewClass (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data));
|
||||
i = new NewArray (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 39:
|
||||
i = new NewFunction (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<ICodeModule*>(node->operand[1].data));
|
||||
i = new NewClass (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data));
|
||||
break;
|
||||
case 40:
|
||||
i = new NewObject (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new NewFunction (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<ICodeModule*>(node->operand[1].data));
|
||||
break;
|
||||
case 41:
|
||||
i = new Nop ();
|
||||
i = new NewObject (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 42:
|
||||
i = new Not (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Nop ();
|
||||
break;
|
||||
case 43:
|
||||
i = new Or (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Not (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 44:
|
||||
i = new Posate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Or (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 45:
|
||||
i = new PropXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
i = new Posate (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 46:
|
||||
i = new Remainder (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new PropXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), reinterpret_cast<const StringAtom*>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 47:
|
||||
i = new Return (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Remainder (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 48:
|
||||
i = new ReturnVoid ();
|
||||
i = new Return (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 49:
|
||||
i = new Rts ();
|
||||
i = new ReturnVoid ();
|
||||
break;
|
||||
case 50:
|
||||
i = new SaveName (reinterpret_cast<const StringAtom*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Rts ();
|
||||
break;
|
||||
case 51:
|
||||
i = new SetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SaveName (reinterpret_cast<const StringAtom*>(node->operand[0].data), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 52:
|
||||
i = new SetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetElement (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 53:
|
||||
i = new SetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetProp (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<const StringAtom*>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 54:
|
||||
i = new SetStatic (reinterpret_cast<JSClass*>(node->operand[0].data), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetSlot (TypedRegister(static_cast<Register>(node->operand[0].data), 0), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 55:
|
||||
i = new Shiftleft (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new SetStatic (reinterpret_cast<JSClass*>(node->operand[0].data), static_cast<uint32>(node->operand[1].data), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 56:
|
||||
i = new Shiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Shiftleft (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 57:
|
||||
i = new SlotXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
i = new Shiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 58:
|
||||
i = new StaticXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
i = new SlotXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 59:
|
||||
i = new StrictEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new StaticXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), reinterpret_cast<JSClass*>(node->operand[1].data), static_cast<uint32>(node->operand[2].data), static_cast<double>(node->operand[3].data));
|
||||
break;
|
||||
case 60:
|
||||
i = new StrictNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new StrictEQ (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 61:
|
||||
i = new Subtract (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new StrictNE (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 62:
|
||||
i = new Super (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Subtract (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 63:
|
||||
i = new Test (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
i = new Super (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 64:
|
||||
i = new Throw (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new Test (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0));
|
||||
break;
|
||||
case 65:
|
||||
i = new Tryin (reinterpret_cast<Label*>(node->operand[0].data), reinterpret_cast<Label*>(node->operand[1].data));
|
||||
i = new Throw (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 66:
|
||||
i = new Tryout ();
|
||||
i = new Tryin (reinterpret_cast<Label*>(node->operand[0].data), reinterpret_cast<Label*>(node->operand[1].data));
|
||||
break;
|
||||
case 67:
|
||||
i = new Ushiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
i = new Tryout ();
|
||||
break;
|
||||
case 68:
|
||||
i = new VarXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<double>(node->operand[2].data));
|
||||
i = new Ushiftright (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
case 69:
|
||||
i = new Within (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
i = new VarXcr (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), static_cast<double>(node->operand[2].data));
|
||||
break;
|
||||
case 70:
|
||||
i = new Without ();
|
||||
i = new Within (TypedRegister(static_cast<Register>(node->operand[0].data), 0));
|
||||
break;
|
||||
case 71:
|
||||
i = new Without ();
|
||||
break;
|
||||
case 72:
|
||||
i = new Xor (TypedRegister(static_cast<Register>(node->operand[0].data), 0), TypedRegister(static_cast<Register>(node->operand[1].data), 0), TypedRegister(static_cast<Register>(node->operand[2].data), 0));
|
||||
break;
|
||||
|
||||
|
|
|
@ -695,7 +695,17 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
ASSERT(base.isObject()); // XXX runtime error
|
||||
JSClass *theClass = dynamic_cast<JSClass*>(base.object->getType());
|
||||
ASSERT(theClass);
|
||||
(*registers)[dst(gm).first] = theClass->getMethod(src2(gm));
|
||||
(*registers)[dst(gm).first] = new JSBoundThis(base, theClass->getMethod(src2(gm)));
|
||||
}
|
||||
break;
|
||||
|
||||
case BIND_THIS:
|
||||
{
|
||||
BindThis* bt = static_cast<BindThis*>(instruction);
|
||||
JSValue base = (*registers)[src1(bt).first];
|
||||
JSValue target = (*registers)[src2(bt).first];
|
||||
ASSERT(target.isFunction());
|
||||
(*registers)[dst(bt).first] = new JSBoundThis(base, target.function);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -715,9 +725,9 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
if (!target)
|
||||
throw new JSException("Call to non callable object");
|
||||
if (target->isNative()) {
|
||||
ArgumentList *params = op4(call);
|
||||
ArgumentList *params = op3(call);
|
||||
JSValues argv(params->size() + 1);
|
||||
argv[0] = (*registers)[op3(call).first];
|
||||
argv[0] = target->getThis(); //(*registers)[op3(call).first];
|
||||
JSValues::size_type i = 1;
|
||||
for (ArgumentList::const_iterator src = params->begin(), end = params->end();
|
||||
src != end; ++src, ++i) {
|
||||
|
@ -730,7 +740,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
}
|
||||
else {
|
||||
ICodeModule *icm = target->getICode();
|
||||
ArgumentList *args = op4(call);
|
||||
ArgumentList *args = op3(call);
|
||||
|
||||
// if all the parameters are positional
|
||||
// if (icm->itsParameters->mPositionalCount == icm->itsParameters->size())
|
||||
|
@ -824,7 +834,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
|
|||
}
|
||||
|
||||
mLinkage = new Linkage(mLinkage, ++mPC, mActivation, mGlobal, op1(call));
|
||||
mActivation = new Activation(icm, mActivation, (*registers)[op3(call).first], callArgs);
|
||||
mActivation = new Activation(icm, mActivation, target->getThis()/*(*registers)[op3(call).first]*/, callArgs);
|
||||
registers = &mActivation->mRegisters;
|
||||
mPC = mActivation->mICode->its_iCode->begin();
|
||||
endPC = mActivation->mICode->its_iCode->end();
|
||||
|
|
|
@ -348,6 +348,7 @@ namespace JSClasses {
|
|||
}
|
||||
|
||||
#if !defined(XP_MAC)
|
||||
void operator delete(void* /*ptr*/) {}
|
||||
void operator delete(void* /*ptr*/, JSClass* /*thisClass*/) {}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -834,6 +834,13 @@ JSValue JSValue::convert(JSType *toType)
|
|||
return valueToInteger(*this);
|
||||
else if (toType == &String_Type)
|
||||
return valueToString(*this);
|
||||
else if (toType == &Function_Type)
|
||||
{
|
||||
if (tag == function_tag)
|
||||
return *this;
|
||||
else
|
||||
throw new JSException("Can't cast to function");
|
||||
}
|
||||
else {
|
||||
JSClass *toClass = dynamic_cast<JSClass *>(toType);
|
||||
if (toClass) {
|
||||
|
@ -860,7 +867,7 @@ JSValue JSValue::convert(JSType *toType)
|
|||
|
||||
JSFunction::~JSFunction()
|
||||
{
|
||||
delete mICode;
|
||||
if (mICode) delete mICode;
|
||||
}
|
||||
|
||||
JSString::JSString(const String& str)
|
||||
|
|
|
@ -68,6 +68,7 @@ namespace JSTypes {
|
|||
|
||||
typedef uint32 Register;
|
||||
|
||||
|
||||
/**
|
||||
* All JavaScript data types.
|
||||
*/
|
||||
|
@ -270,16 +271,13 @@ namespace JSTypes {
|
|||
JSObject() { init(ObjectPrototypeObject); }
|
||||
JSObject(JSValue &constructor) { init(constructor.object->getProperty(widenCString("prototype")).object); }
|
||||
JSObject(JSObject *prototype) { init(prototype); }
|
||||
/*
|
||||
|
||||
I wanted to have this, but VCC complains about JSInstance instances not being deletable...
|
||||
|
||||
virtual ~JSObject()
|
||||
{
|
||||
if (mGetter) delete mGetter;
|
||||
if (mSetter) delete mSetter;
|
||||
}
|
||||
*/
|
||||
|
||||
static void initObjectObject(JSScope *g);
|
||||
|
||||
bool hasProperty(const String& name)
|
||||
|
@ -501,11 +499,11 @@ namespace JSTypes {
|
|||
* compiled code of the function.
|
||||
*/
|
||||
class JSFunction : public JSObject {
|
||||
protected:
|
||||
static JSString* FunctionString;
|
||||
static JSObject* FunctionPrototypeObject;
|
||||
ICodeModule* mICode;
|
||||
|
||||
protected:
|
||||
|
||||
typedef JavaScript::gc_traits_finalizable<JSFunction> traits;
|
||||
typedef gc_allocator<JSFunction, traits> allocator;
|
||||
|
@ -522,7 +520,9 @@ namespace JSTypes {
|
|||
setClass(FunctionString);
|
||||
}
|
||||
|
||||
~JSFunction();
|
||||
virtual ~JSFunction();
|
||||
|
||||
virtual JSValue getThis() { return kNullValue; }
|
||||
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
|
||||
|
@ -530,20 +530,37 @@ namespace JSTypes {
|
|||
virtual bool isNative() { return false; }
|
||||
};
|
||||
|
||||
class JSBoundThis : public JSFunction {
|
||||
typedef JavaScript::gc_traits_finalizable<JSBoundThis> traits;
|
||||
typedef gc_allocator<JSBoundThis, traits> allocator;
|
||||
public:
|
||||
JSBoundThis(JSValue aThis, JSFunction *aFunc) : JSFunction(*aFunc) { mBoundThis = aThis; }
|
||||
JSValue mBoundThis;
|
||||
virtual ~JSBoundThis() { mICode = NULL; }
|
||||
virtual JSValue getThis() { return mBoundThis; }
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
};
|
||||
|
||||
class JSNativeFunction : public JSFunction {
|
||||
typedef JavaScript::gc_traits_finalizable<JSNativeFunction> traits;
|
||||
typedef gc_allocator<JSNativeFunction, traits> allocator;
|
||||
public:
|
||||
typedef JSValue (*JSCode)(Context *cx, const JSValues& argv);
|
||||
JSCode mCode;
|
||||
JSNativeFunction(JSCode code) : mCode(code) {}
|
||||
virtual bool isNative() { return true; }
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
};
|
||||
|
||||
class JSBinaryOperator : public JSFunction {
|
||||
typedef JavaScript::gc_traits_finalizable<JSBinaryOperator> traits;
|
||||
typedef gc_allocator<JSBinaryOperator, traits> allocator;
|
||||
public:
|
||||
typedef JSValue (*JSBinaryCode)(const JSValue& arg1, const JSValue& arg2);
|
||||
JSBinaryCode mCode;
|
||||
JSBinaryOperator(JSBinaryCode code) : mCode(code) {}
|
||||
virtual bool isNative() { return true; }
|
||||
void* operator new(size_t) { return allocator::allocate(1); }
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -31,6 +31,12 @@
|
|||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
// Turn off warnings about identifiers too long in browser information
|
||||
#pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
|
||||
#include "lexutils.h"
|
||||
|
||||
namespace JavaScript {
|
||||
|
|
Загрузка…
Ссылка в новой задаче