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:
rogerl%netscape.com 2000-11-16 23:48:42 +00:00
Родитель 2633790a83
Коммит 8ccb885553
18 изменённых файлов: 372 добавлений и 224 удалений

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

@ -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 {