Changed use of Register to TypedRegister throughout.

This commit is contained in:
rogerl%netscape.com 2000-06-20 22:45:45 +00:00
Родитель c23aa15cea
Коммит 0bb6f588ba
12 изменённых файлов: 1002 добавлений и 1188 удалений

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

@ -61,14 +61,15 @@ Formatter& operator<<(Formatter &f, ICodeModule &i)
// ICodeGenerator
//
ICodeGenerator::ICodeGenerator(World *world)
ICodeGenerator::ICodeGenerator(World *world, JSScope *global)
: topRegister(0),
registerBase(0),
maxRegister(0),
parameterCount(0),
exceptionRegister(NotARegister),
exceptionRegister(TypedRegister(NotARegister, &None_Type)),
variableList(new VariableList()),
mWorld(world),
mGlobal(global),
mInstructionMap(new InstructionMap()),
mWithinWith(false)
@ -77,12 +78,28 @@ ICodeGenerator::ICodeGenerator(World *world)
iCodeOwner = true;
}
Register ICodeGenerator::allocateVariable(const StringAtom& name)
const JSType *ICodeGenerator::findType(const StringAtom& typeName)
{
const JSValue& type = mGlobal->getVariable(typeName);
if (type.isType())
return type.type;
return &Any_Type;
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name, const StringAtom& typeName)
{
if (exceptionRegister == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")]);
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name);
return grabRegister(name, findType(typeName));
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name)
{
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name, &Any_Type);
}
ICodeModule *ICodeGenerator::complete()
@ -126,41 +143,41 @@ ICodeModule *ICodeGenerator::complete()
/********************************************************************/
Register ICodeGenerator::loadImmediate(double value)
TypedRegister ICodeGenerator::loadImmediate(double value)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
LoadImmediate *instr = new LoadImmediate(dest, value);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::loadString(String &value)
TypedRegister ICodeGenerator::loadString(String &value)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &String_Type);
LoadString *instr = new LoadString(dest, new JSString(value));
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::loadValue(JSValue value)
TypedRegister ICodeGenerator::loadBoolean(bool value)
{
Register dest = getRegister();
LoadValue *instr = new LoadValue(dest, value);
TypedRegister dest(getRegister(), &Boolean_Type);
LoadBoolean *instr = new LoadBoolean(dest, value);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::newObject()
TypedRegister ICodeGenerator::newObject()
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
NewObject *instr = new NewObject(dest);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::newArray()
TypedRegister ICodeGenerator::newArray()
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Array_Type);
NewArray *instr = new NewArray(dest);
iCode->push_back(instr);
return dest;
@ -168,47 +185,47 @@ Register ICodeGenerator::newArray()
Register ICodeGenerator::loadName(const StringAtom &name)
TypedRegister ICodeGenerator::loadName(const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
LoadName *instr = new LoadName(dest, &name);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::saveName(const StringAtom &name, Register value)
void ICodeGenerator::saveName(const StringAtom &name, TypedRegister value)
{
SaveName *instr = new SaveName(&name, value);
iCode->push_back(instr);
}
Register ICodeGenerator::nameInc(const StringAtom &name)
TypedRegister ICodeGenerator::nameInc(const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
NameXcr *instr = new NameXcr(dest, &name, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::nameDec(const StringAtom &name)
TypedRegister ICodeGenerator::nameDec(const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
NameXcr *instr = new NameXcr(dest, &name, -1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::varInc(Register var)
TypedRegister ICodeGenerator::varInc(TypedRegister var)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
VarXcr *instr = new VarXcr(dest, var, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::varDec(Register var)
TypedRegister ICodeGenerator::varDec(TypedRegister var)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
VarXcr *instr = new VarXcr(dest, var, -1.0);
iCode->push_back(instr);
return dest;
@ -216,32 +233,32 @@ Register ICodeGenerator::varDec(Register var)
Register ICodeGenerator::getProperty(Register base, const StringAtom &name)
TypedRegister ICodeGenerator::getProperty(TypedRegister base, const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
GetProp *instr = new GetProp(dest, base, &name);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::setProperty(Register base, const StringAtom &name,
Register value)
void ICodeGenerator::setProperty(TypedRegister base, const StringAtom &name,
TypedRegister value)
{
SetProp *instr = new SetProp(base, &name, value);
iCode->push_back(instr);
}
Register ICodeGenerator::propertyInc(Register base, const StringAtom &name)
TypedRegister ICodeGenerator::propertyInc(TypedRegister base, const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
PropXcr *instr = new PropXcr(dest, base, &name, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::propertyDec(Register base, const StringAtom &name)
TypedRegister ICodeGenerator::propertyDec(TypedRegister base, const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
PropXcr *instr = new PropXcr(dest, base, &name, -1.0);
iCode->push_back(instr);
return dest;
@ -249,94 +266,94 @@ Register ICodeGenerator::propertyDec(Register base, const StringAtom &name)
Register ICodeGenerator::getElement(Register base, Register index)
TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
GetElement *instr = new GetElement(dest, base, index);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::setElement(Register base, Register index,
Register value)
void ICodeGenerator::setElement(TypedRegister base, TypedRegister index,
TypedRegister value)
{
SetElement *instr = new SetElement(base, index, value);
iCode->push_back(instr);
}
Register ICodeGenerator::elementInc(Register base, Register index)
TypedRegister ICodeGenerator::elementInc(TypedRegister base, TypedRegister index)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
ElemXcr *instr = new ElemXcr(dest, base, index, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::elementDec(Register base, Register index)
TypedRegister ICodeGenerator::elementDec(TypedRegister base, TypedRegister index)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
ElemXcr *instr = new ElemXcr(dest, base, index, -1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::op(ICodeOp op, Register source)
TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source)
{
Register dest = getRegister();
ASSERT(source != NotARegister);
TypedRegister dest(getRegister(), &Any_Type);
ASSERT(source.first != NotARegister);
Unary *instr = new Unary (op, dest, source);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::move(Register destination, Register source)
void ICodeGenerator::move(TypedRegister destination, TypedRegister source)
{
ASSERT(destination != NotARegister);
ASSERT(source != NotARegister);
ASSERT(destination.first != NotARegister);
ASSERT(source.first != NotARegister);
Move *instr = new Move(destination, source);
iCode->push_back(instr);
}
Register ICodeGenerator::logicalNot(Register source)
TypedRegister ICodeGenerator::logicalNot(TypedRegister source)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
Not *instr = new Not(dest, source);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::test(Register source)
TypedRegister ICodeGenerator::test(TypedRegister source)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
Test *instr = new Test(dest, source);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::op(ICodeOp op, Register source1,
Register source2)
TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1,
TypedRegister source2)
{
ASSERT(source1 != NotARegister);
ASSERT(source2 != NotARegister);
Register dest = getRegister();
ASSERT(source1.first != NotARegister);
ASSERT(source2.first != NotARegister);
TypedRegister dest(getRegister(), &Any_Type);
Arithmetic *instr = new Arithmetic(op, dest, source1, source2);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::call(Register target, RegisterList args)
TypedRegister ICodeGenerator::call(TypedRegister target, RegisterList args)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
Call *instr = new Call(dest, target, args);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::callVoid(Register target, RegisterList args)
void ICodeGenerator::callVoid(TypedRegister target, RegisterList args)
{
Call *instr = new Call(NotARegister, target, args);
Call *instr = new Call(TypedRegister(NotARegister, &Void_Type), target, args);
iCode->push_back(instr);
}
@ -346,23 +363,23 @@ void ICodeGenerator::branch(Label *label)
iCode->push_back(instr);
}
GenericBranch *ICodeGenerator::branchTrue(Label *label, Register condition)
GenericBranch *ICodeGenerator::branchTrue(Label *label, TypedRegister condition)
{
GenericBranch *instr = new GenericBranch(BRANCH_TRUE, label, condition);
iCode->push_back(instr);
return instr;
}
GenericBranch *ICodeGenerator::branchFalse(Label *label, Register condition)
GenericBranch *ICodeGenerator::branchFalse(Label *label, TypedRegister condition)
{
GenericBranch *instr = new GenericBranch(BRANCH_FALSE, label, condition);
iCode->push_back(instr);
return instr;
}
void ICodeGenerator::returnStmt(Register r)
void ICodeGenerator::returnStmt(TypedRegister r)
{
if (r == NotARegister)
if (r.first == NotARegister)
iCode->push_back(new ReturnVoid());
else
iCode->push_back(new Return(r));
@ -504,37 +521,37 @@ static bool generatedBoolean(ExprNode *p)
a conditional branch to the appropriate target. If either branch is NULL, it
indicates that the label is immediately forthcoming.
*/
Result ICodeGenerator::genExpr(ExprNode *p,
TypedRegister ICodeGenerator::genExpr(ExprNode *p,
bool needBoolValueInBranch,
Label *trueBranch,
Label *falseBranch)
{
Register ret = NotARegister;
TypedRegister ret(NotARegister, &None_Type);
switch (p->getKind()) {
case ExprNode::True:
if (trueBranch || falseBranch) {
if (needBoolValueInBranch)
ret = loadValue(kTrue);
ret = loadBoolean(true);
if (trueBranch)
branch(trueBranch);
}
else
ret = loadValue(kTrue);
ret = loadBoolean(true);
break;
case ExprNode::False:
if (trueBranch || falseBranch) {
if (needBoolValueInBranch)
ret = loadValue(kFalse);
ret = loadBoolean(false);
if (falseBranch)
branch(falseBranch);
}
else
ret = loadValue(kFalse);
ret = loadBoolean(false);
break;
case ExprNode::parentheses:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch).reg;
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch);
}
break;
case ExprNode::New:
@ -546,11 +563,11 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::call :
{
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
Register fn = genExpr(i->op).reg;
TypedRegister fn = genExpr(i->op);
RegisterList args;
ExprPairList *p = i->pairs;
while (p) {
args.push_back(genExpr(p->value).reg);
args.push_back(genExpr(p->value));
p = p->next;
}
ret = call(fn, args);
@ -559,23 +576,23 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
}
break;
case ExprNode::dot :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
break;
case ExprNode::identifier :
{
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(p))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(p))->name);
if (v.first != NotARegister)
ret = v;
else
ret = loadName((static_cast<IdentifierExprNode *>(p))->name);
@ -595,7 +612,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
ret = op(ADD, ret, loadImmediate(1.0));
setProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name, ret);
@ -603,8 +620,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = op(ADD, ret, loadImmediate(1.0));
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
@ -621,8 +638,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
ret = op(ADD, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -634,14 +651,14 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = propertyInc(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = varInc(v);
else
ret = nameInc((static_cast<IdentifierExprNode *>(u->op))->name);
@ -652,8 +669,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = elementInc(base, index);
}
}
@ -663,7 +680,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name, ret);
@ -671,8 +688,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = op(SUBTRACT, ret, loadImmediate(1.0));
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
@ -689,8 +706,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -702,14 +719,14 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = propertyDec(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = varDec(v);
else
ret = nameDec((static_cast<IdentifierExprNode *>(u->op))->name);
@ -720,8 +737,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = elementInc(base, index);
}
}
@ -731,7 +748,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::complement:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
Register r = genExpr(u->op).reg;
TypedRegister r = genExpr(u->op);
ret = op(mapExprNodeToICodeOp(p->getKind()), r);
}
break;
@ -748,19 +765,19 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOr:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
}
break;
case ExprNode::assignment:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2).reg;
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v.first != NotARegister)
move(v, ret);
else
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
@ -771,14 +788,14 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
TypedRegister base = genExpr(lb->op1);
setProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name, ret);
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
setElement(base, index, ret);
}
}
@ -796,11 +813,11 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOrEquals:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2).reg;
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v != NotARegister) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v.first != NotARegister) {
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
move(v, ret);
}
@ -811,7 +828,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
}
}
else {
Register v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
TypedRegister v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
}
@ -819,17 +836,17 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
Register v = getProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name);
TypedRegister base = genExpr(lb->op1);
TypedRegister v = getProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name, ret);
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
Register v = getElement(base, index);
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
TypedRegister v = getElement(base, index);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setElement(base, index, ret);
}
@ -843,8 +860,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::Instanceof:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -861,8 +878,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::greaterThanOrEqual:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r2, r1); // will return reverse case
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -880,8 +897,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::notIdentical:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -907,12 +924,12 @@ Result ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *fBranch = getLabel();
Register r1 = genExpr(b->op1, true, NULL, fBranch).reg;
TypedRegister r1 = genExpr(b->op1, true, NULL, fBranch);
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchFalse(fBranch, r1);
}
Register r2 = genExpr(b->op2).reg;
TypedRegister r2 = genExpr(b->op2);
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -932,12 +949,12 @@ Result ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *tBranch = getLabel();
Register r1 = genExpr(b->op1, true, tBranch, NULL).reg;
TypedRegister r1 = genExpr(b->op1, true, tBranch, NULL);
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchTrue(tBranch, r1);
}
Register r2 = genExpr(b->op2).reg;
TypedRegister r2 = genExpr(b->op2);
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -954,13 +971,13 @@ Result ICodeGenerator::genExpr(ExprNode *p,
TernaryExprNode *t = static_cast<TernaryExprNode *>(p);
Label *fBranch = getLabel();
Label *beyondBranch = getLabel();
Register c = genExpr(t->op1, false, NULL, fBranch).reg;
TypedRegister c = genExpr(t->op1, false, NULL, fBranch);
if (!generatedBoolean(t->op1))
branchFalse(fBranch, test(c));
Register r1 = genExpr(t->op2).reg;
TypedRegister r1 = genExpr(t->op2);
branch(beyondBranch);
setLabel(fBranch);
Register r2 = genExpr(t->op3).reg;
TypedRegister r2 = genExpr(t->op3);
if (r1 != r2) // FIXME, need a way to specify a dest???
move(r1, r2);
setLabel(beyondBranch);
@ -976,7 +993,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
ExprPairList *e = plen->pairs;
while (e) {
if (e->field && e->value && (e->field->getKind() == ExprNode::identifier))
setProperty(ret, (static_cast<IdentifierExprNode *>(e->field))->name, genExpr(e->value).reg);
setProperty(ret, (static_cast<IdentifierExprNode *>(e->field))->name, genExpr(e->value));
e = e->next;
}
}
@ -987,7 +1004,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
NOT_REACHED("Unsupported ExprNode kind");
}
}
return Result(ret, Any_Type);
return ret;
}
/*
@ -1110,20 +1127,20 @@ void ICodeGenerator::preprocess(StmtNode *p)
}
}
Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
{
Register ret = NotARegister;
TypedRegister ret(NotARegister, &None_Type);
startStatement(p->pos);
if (exceptionRegister == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")]);
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
switch (p->getKind()) {
case StmtNode::Function:
{
FunctionStmtNode *f = static_cast<FunctionStmtNode *>(p);
ICodeGenerator icg(mWorld);
ICodeGenerator icg(mWorld, mGlobal);
VariableBinding *v = f->function.parameters;
while (v) {
if (v->name && (v->name->getKind() == ExprNode::identifier))
@ -1146,12 +1163,12 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
if (v->name && v->initializer) {
if (v->name->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register r = genExpr(v->name).reg;
Register val = genExpr(v->initializer).reg;
TypedRegister r = genExpr(v->name);
TypedRegister val = genExpr(v->initializer);
move(r, val);
}
else {
Register val = genExpr(v->initializer).reg;
TypedRegister val = genExpr(v->initializer);
saveName((static_cast<IdentifierExprNode *>(v->name))->name, val);
}
}
@ -1164,29 +1181,29 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::expression:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
ret = genExpr(e->expr).reg;
ret = genExpr(e->expr);
}
break;
case StmtNode::Throw:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
throwStmt(genExpr(e->expr).reg);
throwStmt(genExpr(e->expr));
}
break;
case StmtNode::Return:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
if (e->expr)
returnStmt(ret = genExpr(e->expr).reg);
returnStmt(ret = genExpr(e->expr));
else
returnStmt(NotARegister);
returnStmt(TypedRegister(NotARegister, &Void_Type));
}
break;
case StmtNode::If:
{
Label *falseLabel = getLabel();
UnaryStmtNode *i = static_cast<UnaryStmtNode *>(p);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
TypedRegister c = genExpr(i->expr, false, NULL, falseLabel);
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1198,7 +1215,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
Label *falseLabel = getLabel();
Label *beyondLabel = getLabel();
BinaryStmtNode *i = static_cast<BinaryStmtNode *>(p);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
TypedRegister c = genExpr(i->expr, false, NULL, falseLabel);
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1211,7 +1228,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::With:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
Register o = genExpr(w->expr).reg;
TypedRegister o = genExpr(w->expr);
bool withinWith = mWithinWith;
mWithinWith = true;
beginWith(o);
@ -1226,7 +1243,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
LabelEntry *e = new LabelEntry(currentLabelSet, getLabel());
mLabelStack.push_back(e);
SwitchStmtNode *sw = static_cast<SwitchStmtNode *>(p);
Register sc = genExpr(sw->expr).reg;
TypedRegister sc = genExpr(sw->expr);
StmtNode *s = sw->statements;
// ECMA requires case & default statements to be immediate children of switch
// unlike C where they can be arbitrarily deeply nested in other statements.
@ -1239,8 +1256,8 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
if (nextCaseLabel)
setLabel(nextCaseLabel);
nextCaseLabel = getLabel();
Register r = genExpr(c->expr).reg;
Register eq = op(COMPARE_EQ, r, sc);
TypedRegister r = genExpr(c->expr);
TypedRegister eq = op(COMPARE_EQ, r, sc);
lastBranch = branchFalse(nextCaseLabel, eq);
}
else {
@ -1270,7 +1287,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(doBodyTopLabel);
genStmt(d->stmt);
setLabel(e->continueLabel);
Register c = genExpr(d->expr, false, doBodyTopLabel, NULL).reg;
TypedRegister c = genExpr(d->expr, false, doBodyTopLabel, NULL);
if (!generatedBoolean(d->expr))
branchTrue(doBodyTopLabel, test(c));
setLabel(e->breakLabel);
@ -1290,7 +1307,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
genStmt(w->stmt);
setLabel(e->continueLabel);
Register c = genExpr(w->expr, false, whileBodyTopLabel, NULL).reg;
TypedRegister c = genExpr(w->expr, false, whileBodyTopLabel, NULL);
if (!generatedBoolean(w->expr))
branchTrue(whileBodyTopLabel, test(c));
@ -1315,11 +1332,11 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(e->continueLabel);
if (f->expr3)
genExpr(f->expr3).reg;
genExpr(f->expr3);
setLabel(forTestLabel);
if (f->expr2) {
Register c = genExpr(f->expr2, false, forBlockTop, NULL).reg;
TypedRegister c = genExpr(f->expr2, false, forBlockTop, NULL);
if (!generatedBoolean(f->expr2))
branchTrue(forBlockTop, test(c));
}

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

@ -46,9 +46,9 @@ namespace JavaScript {
namespace ICG {
using namespace VM;
using namespace JSTypes;
typedef std::map<String, Register, std::less<String> > VariableList;
typedef std::map<String, TypedRegister, std::less<String> > VariableList;
typedef std::pair<uint32, uint32> InstructionMapping;
typedef std::vector<InstructionMapping *> InstructionMap;
@ -105,12 +105,6 @@ namespace ICG {
// function/script, adds statements and expressions to it and then
// converts it into an ICodeModule, ready for execution.
struct Result {
Result(Register reg, JSTypes::JSType type) : reg(reg), type(type) {}
Register reg;
JSTypes::JSType type;
};
class ICodeGenerator {
private:
InstructionStream *iCode;
@ -122,10 +116,11 @@ namespace ICG {
uint32 maxRegister; // highest (ever) allocated register
uint32 parameterCount; // number of parameters declared for the function
// these must come before any variables declared.
Register exceptionRegister; // reserved to carry the exception object.
TypedRegister exceptionRegister;// reserved to carry the exception object.
VariableList *variableList; // name|register pair for each variable
World *mWorld; // used to register strings
World *mWorld; // used to register strings
JSScope *mGlobal; // the scope for compiling within
LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct
InstructionMap *mInstructionMap;// maps source position to instruction index
@ -146,15 +141,15 @@ namespace ICG {
void jsr(Label *label) { iCode->push_back(new Jsr(label)); }
void rts() { iCode->push_back(new Rts()); }
void branch(Label *label);
GenericBranch *branchTrue(Label *label, Register condition);
GenericBranch *branchFalse(Label *label, Register condition);
GenericBranch *branchTrue(Label *label, TypedRegister condition);
GenericBranch *branchFalse(Label *label, TypedRegister condition);
void beginTry(Label *catchLabel, Label *finallyLabel)
{ iCode->push_back(new Tryin(catchLabel, finallyLabel)); }
void endTry()
{ iCode->push_back(new Tryout()); }
void beginWith(Register obj)
void beginWith(TypedRegister obj)
{ iCode->push_back(new Within(obj)); }
void endWith()
{ iCode->push_back(new Without()); }
@ -164,7 +159,7 @@ namespace ICG {
void resetStatement() { resetTopRegister(); }
void setRegisterForVariable(const StringAtom& name, Register r)
void setRegisterForVariable(const StringAtom& name, TypedRegister r)
{ (*variableList)[name] = r; }
@ -172,16 +167,18 @@ namespace ICG {
ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind);
Register grabRegister(const StringAtom& name)
TypedRegister grabRegister(const StringAtom& name, const JSType *type)
{
Register result = getRegister();
TypedRegister result(getRegister(), type);
(*variableList)[name] = result;
registerBase = topRegister;
return result;
}
const JSType *findType(const StringAtom& typeName);
public:
ICodeGenerator(World *world = NULL);
ICodeGenerator(World *world, JSScope *global);
~ICodeGenerator()
{
@ -193,65 +190,66 @@ namespace ICG {
ICodeModule *complete();
Result genExpr(ExprNode *p,
TypedRegister genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
void preprocess(StmtNode *p);
Register genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL);
TypedRegister genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL);
void isScript() { mWithinWith = true; }
void returnStmt(Register r);
void throwStmt(Register r)
void returnStmt(TypedRegister r);
void throwStmt(TypedRegister r)
{ iCode->push_back(new Throw(r)); }
Register allocateVariable(const StringAtom& name);
Register allocateVariable(const StringAtom& name, const StringAtom& /*type */)
{ return allocateVariable(name); }
TypedRegister allocateVariable(const StringAtom& name);
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName);
Register findVariable(const StringAtom& name)
TypedRegister findVariable(const StringAtom& name)
{ VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? NotARegister : (*i).second; }
return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; }
Register allocateParameter(const StringAtom& name)
{ parameterCount++; return grabRegister(name); }
TypedRegister allocateParameter(const StringAtom& name)
{ parameterCount++; return grabRegister(name, &Any_Type); }
TypedRegister allocateParameter(const StringAtom& name, const StringAtom& typeName)
{ parameterCount++; return grabRegister(name, findType(typeName)); }
Formatter& print(Formatter& f);
Register op(ICodeOp op, Register source);
Register op(ICodeOp op, Register source1, Register source2);
Register call(Register target, RegisterList args);
void callVoid(Register target, RegisterList args);
TypedRegister op(ICodeOp op, TypedRegister source);
TypedRegister op(ICodeOp op, TypedRegister source1, TypedRegister source2);
TypedRegister call(TypedRegister target, RegisterList args);
void callVoid(TypedRegister target, RegisterList args);
void move(Register destination, Register source);
Register logicalNot(Register source);
Register test(Register source);
void move(TypedRegister destination, TypedRegister source);
TypedRegister logicalNot(TypedRegister source);
TypedRegister test(TypedRegister source);
Register loadValue(JSValue value);
Register loadImmediate(double value);
Register loadString(String &value);
TypedRegister loadBoolean(bool value);
TypedRegister loadImmediate(double value);
TypedRegister loadString(String &value);
Register newObject();
Register newArray();
TypedRegister newObject();
TypedRegister newArray();
Register loadName(const StringAtom &name);
void saveName(const StringAtom &name, Register value);
Register nameInc(const StringAtom &name);
Register nameDec(const StringAtom &name);
TypedRegister loadName(const StringAtom &name);
void saveName(const StringAtom &name, TypedRegister value);
TypedRegister nameInc(const StringAtom &name);
TypedRegister nameDec(const StringAtom &name);
Register getProperty(Register base, const StringAtom &name);
void setProperty(Register base, const StringAtom &name, Register value);
Register propertyInc(Register base, const StringAtom &name);
Register propertyDec(Register base, const StringAtom &name);
TypedRegister getProperty(TypedRegister base, const StringAtom &name);
void setProperty(TypedRegister base, const StringAtom &name, TypedRegister value);
TypedRegister propertyInc(TypedRegister base, const StringAtom &name);
TypedRegister propertyDec(TypedRegister base, const StringAtom &name);
Register getElement(Register base, Register index);
void setElement(Register base, Register index, Register value);
Register elementInc(Register base, Register index);
Register elementDec(Register base, Register index);
TypedRegister getElement(TypedRegister base, TypedRegister index);
void setElement(TypedRegister base, TypedRegister index, TypedRegister value);
TypedRegister elementInc(TypedRegister base, TypedRegister index);
TypedRegister elementDec(TypedRegister base, TypedRegister index);
Register varInc(Register var);
Register varDec(Register var);
TypedRegister varInc(TypedRegister var);
TypedRegister varDec(TypedRegister var);
Register getRegisterBase() { return topRegister; }
InstructionStream *get_iCode() { return iCode; }

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

@ -98,7 +98,7 @@ struct Activation : public gc_base {
const JSValues& params = caller->mRegisters;
for (RegisterList::const_iterator src = list.begin(),
end = list.end(); src != end; ++src, ++dest) {
*dest = params[*src];
*dest = params[(*src).first];
}
}
@ -128,10 +128,10 @@ struct Linkage : public Context::Frame, public gc_base {
Linkage* mNext; // next linkage in linkage stack.
InstructionIterator mReturnPC;
Activation* mActivation; // caller's activation.
Register mResult; // the desired target register for the return value
TypedRegister mResult; // the desired target register for the return value
Linkage(Linkage* linkage, InstructionIterator returnPC,
Activation* activation, Register result)
Activation* activation, TypedRegister result)
: mNext(linkage), mReturnPC(returnPC),
mActivation(activation), mResult(result)
{
@ -146,31 +146,6 @@ void getState(InstructionIterator& pc, JSValues*& registers, ICodeModule*& iCode
iCode = mActivation->mICode;
}
};
/*
void Context::doCall(JSFunction *target, Instruction *pc)
{
if (target->isNative()) {
RegisterList &params = op3(call);
JSValues argv(params.size());
JSValues::size_type i = 0;
for (RegisterList::const_iterator src = params.begin(), end = params.end();
src != end; ++src, ++i) {
argv[i] = (*registers)[*src];
}
if (op2(call) != NotARegister)
(*registers)[op2(call)] = static_cast<JSNativeFunction*>(target)->mCode(argv);
return pc;
}
else {
mLinkage = new Linkage(mLinkage, ++mPC,
mActivation, op1(call));
iCode = target->getICode();
mActivation = new Activation(iCode, mActivation, op3(call));
registers = &mActivation->mRegisters;
continue;
}
}
*/
static JSValue shiftLeft_Default(const JSValue& r1, const JSValue& r2)
{
@ -517,17 +492,17 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
case CALL:
{
Call* call = static_cast<Call*>(instruction);
JSFunction *target = (*registers)[op2(call)].function;
JSFunction *target = (*registers)[op2(call).first].function;
if (target->isNative()) {
RegisterList &params = op3(call);
JSValues argv(params.size());
JSValues::size_type i = 0;
for (RegisterList::const_iterator src = params.begin(), end = params.end();
src != end; ++src, ++i) {
argv[i] = (*registers)[*src];
argv[i] = (*registers)[src->first];
}
if (op2(call) != NotARegister)
(*registers)[op2(call)] = static_cast<JSNativeFunction*>(target)->mCode(argv);
if (op2(call).first != NotARegister)
(*registers)[op2(call).first] = static_cast<JSNativeFunction*>(target)->mCode(argv);
break;
}
else {
@ -553,7 +528,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
mLinkage = linkage->mNext;
mActivation = linkage->mActivation;
registers = &mActivation->mRegisters;
(*registers)[linkage->mResult] = result;
(*registers)[linkage->mResult.first] = result;
mPC = linkage->mReturnPC;
}
continue;
@ -562,8 +537,8 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
{
Return* ret = static_cast<Return*>(instruction);
JSValue result;
if (op1(ret) != NotARegister)
result = (*registers)[op1(ret)];
if (op1(ret).first != NotARegister)
result = (*registers)[op1(ret).first];
Linkage* linkage = mLinkage;
if (!linkage)
{
@ -574,57 +549,57 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
mLinkage = linkage->mNext;
mActivation = linkage->mActivation;
registers = &mActivation->mRegisters;
(*registers)[linkage->mResult] = result;
(*registers)[linkage->mResult.first] = result;
mPC = linkage->mReturnPC;
}
continue;
case MOVE:
{
Move* mov = static_cast<Move*>(instruction);
(*registers)[dst(mov)] = (*registers)[src1(mov)];
(*registers)[dst(mov).first] = (*registers)[src1(mov).first];
}
break;
case LOAD_NAME:
{
LoadName* ln = static_cast<LoadName*>(instruction);
(*registers)[dst(ln)] = mGlobal->getVariable(*src1(ln));
(*registers)[dst(ln).first] = mGlobal->getVariable(*src1(ln));
}
break;
case SAVE_NAME:
{
SaveName* sn = static_cast<SaveName*>(instruction);
mGlobal->setVariable(*dst(sn), (*registers)[src1(sn)]);
mGlobal->setVariable(*dst(sn), (*registers)[src1(sn).first]);
}
break;
case NEW_OBJECT:
{
NewObject* no = static_cast<NewObject*>(instruction);
(*registers)[dst(no)] = JSValue(new JSObject());
(*registers)[dst(no).first] = JSValue(new JSObject());
}
break;
case NEW_ARRAY:
{
NewArray* na = static_cast<NewArray*>(instruction);
(*registers)[dst(na)] = JSValue(new JSArray());
(*registers)[dst(na).first] = JSValue(new JSArray());
}
break;
case GET_PROP:
{
GetProp* gp = static_cast<GetProp*>(instruction);
JSValue& value = (*registers)[src1(gp)];
JSValue& value = (*registers)[src1(gp).first];
if (value.tag == JSValue::object_tag) {
JSObject* object = value.object;
(*registers)[dst(gp)] = object->getProperty(*src2(gp));
(*registers)[dst(gp).first] = object->getProperty(*src2(gp));
}
}
break;
case SET_PROP:
{
SetProp* sp = static_cast<SetProp*>(instruction);
JSValue& value = (*registers)[dst(sp)];
JSValue& value = (*registers)[dst(sp).first];
if (value.tag == JSValue::object_tag) {
JSObject* object = value.object;
object->setProperty(*src1(sp), (*registers)[src2(sp)]);
object->setProperty(*src1(sp), (*registers)[src2(sp).first]);
}
}
break;
@ -647,20 +622,20 @@ using JSString throughout.
case GET_ELEMENT:
{
GetElement* ge = static_cast<GetElement*>(instruction);
JSValue& value = (*registers)[src1(ge)];
JSValue& value = (*registers)[src1(ge).first];
if (value.tag == JSValue::array_tag) {
JSArray* array = value.array;
(*registers)[dst(ge)] = (*array)[(*registers)[src2(ge)]];
(*registers)[dst(ge).first] = (*array)[(*registers)[src2(ge).first]];
}
}
break;
case SET_ELEMENT:
{
SetElement* se = static_cast<SetElement*>(instruction);
JSValue& value = (*registers)[dst(se)];
JSValue& value = (*registers)[dst(se).first];
if (value.tag == JSValue::array_tag) {
JSArray* array = value.array;
(*array)[(*registers)[src1(se)]] = (*registers)[src2(se)];
(*array)[(*registers)[src1(se).first]] = (*registers)[src2(se).first];
}
}
break;
@ -668,19 +643,19 @@ using JSString throughout.
case LOAD_IMMEDIATE:
{
LoadImmediate* li = static_cast<LoadImmediate*>(instruction);
(*registers)[dst(li)] = JSValue(src1(li));
(*registers)[dst(li).first] = JSValue(src1(li));
}
break;
case LOAD_STRING:
{
LoadString* ls = static_cast<LoadString*>(instruction);
(*registers)[dst(ls)] = JSValue(src1(ls));
(*registers)[dst(ls).first] = JSValue(src1(ls));
}
break;
case LOAD_VALUE:
case LOAD_BOOLEAN:
{
LoadValue* lv = static_cast<LoadValue*>(instruction);
(*registers)[dst(lv)] = src1(lv);
LoadBoolean* lb = static_cast<LoadBoolean*>(instruction);
(*registers)[dst(lb).first] = JSValue(src1(lb));
}
break;
case BRANCH:
@ -695,8 +670,8 @@ using JSString throughout.
{
GenericBranch* bc =
static_cast<GenericBranch*>(instruction);
ASSERT((*registers)[src1(bc)].isBoolean());
if ((*registers)[src1(bc)].boolean) {
ASSERT((*registers)[src1(bc).first].isBoolean());
if ((*registers)[src1(bc).first].boolean) {
mPC = mActivation->mICode->its_iCode->begin() + ofs(bc);
continue;
}
@ -706,8 +681,8 @@ using JSString throughout.
{
GenericBranch* bc =
static_cast<GenericBranch*>(instruction);
ASSERT((*registers)[src1(bc)].isBoolean());
if (!(*registers)[src1(bc)].boolean) {
ASSERT((*registers)[src1(bc).first].isBoolean());
if (!(*registers)[src1(bc).first].boolean) {
mPC = mActivation->mICode->its_iCode->begin() + ofs(bc);
continue;
}
@ -730,9 +705,9 @@ using JSString throughout.
case STRICT_EQ:
{
Arithmetic* mul = static_cast<Arithmetic*>(instruction);
JSValue& dest = (*registers)[dst(mul)];
JSValue& r1 = (*registers)[src1(mul)];
JSValue& r2 = (*registers)[src2(mul)];
JSValue& dest = (*registers)[dst(mul).first];
JSValue& r1 = (*registers)[src1(mul).first];
JSValue& r2 = (*registers)[src2(mul).first];
const JSValue ovr = findBinaryOverride(r1, r2, BinaryOperator::mapICodeOp(instruction->op()));
JSFunction *target = ovr.function;
if (target->isNative()) {
@ -756,19 +731,19 @@ using JSString throughout.
case VAR_XCR:
{
VarXcr *vx = static_cast<VarXcr*>(instruction);
JSValue& dest = (*registers)[dst(vx)];
JSValue r = (*registers)[src1(vx)].toNumber();
JSValue& dest = (*registers)[dst(vx).first];
JSValue r = (*registers)[src1(vx).first].toNumber();
dest = r;
r.f64 += val3(vx);
(*registers)[src1(vx)] = r;
(*registers)[src1(vx).first] = r;
}
break;
case PROP_XCR:
{
PropXcr *px = static_cast<PropXcr*>(instruction);
JSValue& dest = (*registers)[dst(px)];
JSValue& base = (*registers)[src1(px)];
JSValue& dest = (*registers)[dst(px).first];
JSValue& base = (*registers)[src1(px).first];
JSObject *object = base.object;
JSValue r = object->getProperty(*src2(px)).toNumber();
dest = r;
@ -780,7 +755,7 @@ using JSString throughout.
case NAME_XCR:
{
NameXcr *nx = static_cast<NameXcr*>(instruction);
JSValue& dest = (*registers)[dst(nx)];
JSValue& dest = (*registers)[dst(nx).first];
JSValue r = mGlobal->getVariable(*src1(nx)).toNumber();
dest = r;
r.f64 += val3(nx);
@ -791,38 +766,38 @@ using JSString throughout.
case TEST:
{
Test* tst = static_cast<Test*>(instruction);
(*registers)[dst(tst)] = (*registers)[src1(tst)].toBoolean();
(*registers)[dst(tst).first] = (*registers)[src1(tst).first].toBoolean();
}
break;
case NEGATE:
{
Negate* neg = static_cast<Negate*>(instruction);
(*registers)[dst(neg)] = JSValue(-(*registers)[src1(neg)].toNumber().f64);
(*registers)[dst(neg).first] = JSValue(-(*registers)[src1(neg).first].toNumber().f64);
}
break;
case POSATE:
{
Posate* pos = static_cast<Posate*>(instruction);
(*registers)[dst(pos)] = (*registers)[src1(pos)].toNumber();
(*registers)[dst(pos).first] = (*registers)[src1(pos).first].toNumber();
}
break;
case BITNOT:
{
Bitnot* bn = static_cast<Bitnot*>(instruction);
(*registers)[dst(bn)] = JSValue(~(*registers)[src1(bn)].toInt32().i32);
(*registers)[dst(bn).first] = JSValue(~(*registers)[src1(bn).first].toInt32().i32);
}
break;
case NOT:
{
Not* nt = static_cast<Not*>(instruction);
ASSERT((*registers)[src1(nt)].isBoolean());
(*registers)[dst(nt)] = JSValue(!(*registers)[src1(nt)].boolean);
ASSERT((*registers)[src1(nt).first].isBoolean());
(*registers)[dst(nt).first] = JSValue(!(*registers)[src1(nt).first].boolean);
}
break;
case THROW:
{
Throw* thrw = static_cast<Throw*>(instruction);
throw new JSException((*registers)[op1(thrw)]);
throw new JSException((*registers)[op1(thrw).first]);
}
case TRYIN:
@ -857,7 +832,7 @@ using JSString throughout.
case WITHIN:
{
Within* within = static_cast<Within*>(instruction);
JSValue& value = (*registers)[op1(within)];
JSValue& value = (*registers)[op1(within).first];
assert(value.tag == JSValue::object_tag);
mGlobal = new JSScope(mGlobal, value.object);
}

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

@ -101,9 +101,10 @@ static JSValue print(const JSValues &argv)
static void genCode(World &world, Context &cx, StmtNode *p)
{
ICodeGenerator icg(&world);
JSScope glob;
ICodeGenerator icg(&world, &glob);
icg.isScript();
Register ret = NotARegister;
TypedRegister ret(NotARegister, &None_Type);
while (p) {
ret = icg.genStmt(p);
p = p->next;
@ -210,86 +211,6 @@ class Tracer : public Context::Listener {
};
static float64 testFactorial(World &world, float64 n)
{
JSScope glob;
Context cx(world, &glob);
// generate code for factorial, and interpret it.
uint32 pos = 0;
ICodeGenerator icg(&world);
// fact(n) {
// var result = 1;
StringAtom &n_name = world.identifiers[widenCString("n")];
StringAtom &result_name = world.identifiers[widenCString("result")];
Register r_n = icg.allocateParameter(n_name);
Register r_result = icg.allocateVariable(result_name);
Arena a;
ExprStmtNode *e = new(a) ExprStmtNode(pos, StmtNode::expression, new(a) BinaryExprNode(pos, ExprNode::assignment,
new(a) IdentifierExprNode(pos, ExprNode::identifier, result_name),
new(a) NumberExprNode(pos, 1.0) ) );
icg.genStmt(e);
// while (n > 1) {
// result = result * n;
// n = n - 1;
// }
{
BinaryExprNode *c = new(a) BinaryExprNode(pos, ExprNode::greaterThan,
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name),
new(a) NumberExprNode(pos, 1.0) ) ;
ExprStmtNode *e1 = new(a) ExprStmtNode(pos, StmtNode::expression, new(a) BinaryExprNode(pos, ExprNode::assignment,
new(a) IdentifierExprNode(pos, ExprNode::identifier, result_name),
new(a) BinaryExprNode(pos, ExprNode::multiply,
new(a) IdentifierExprNode(pos, ExprNode::identifier, result_name),
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name) ) ) );
ExprStmtNode *e2 = new(a) ExprStmtNode(pos, StmtNode::expression, new(a) BinaryExprNode(pos, ExprNode::assignment,
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name),
new(a) BinaryExprNode(pos, ExprNode::subtract,
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name),
new(a) NumberExprNode(pos, 1.0) ) ) );
e1->next = e2;
BlockStmtNode *b = new(a) BlockStmtNode(pos, StmtNode::block, NULL, e1);
UnaryStmtNode *w = new(a) UnaryStmtNode(pos, StmtNode::While, c, b);
icg.genStmt(w);
}
// return result;
icg.returnStmt(r_result);
ICodeModule *icm = icg.complete();
stdOut << icg;
// preset the global property "fact" to contain the above function
StringAtom& fact = world.identifiers[widenCString("fact")];
glob.defineFunction(fact, icm);
// now a script :
// return fact(n);
ICodeGenerator script(&world);
RegisterList args(1);
args[0] = script.loadImmediate(n);
script.returnStmt(script.call(script.loadName(fact), args));
stdOut << script;
// install a listener so we can trace execution of factorial.
Tracer t;
cx.addListener(&t);
// test the iCode interpreter.
JSValue result = cx.interpret(script.complete(), JSValues());
stdOut << "fact(" << n << ") = " << result.f64 << "\n";
delete icm;
return result.f64;
}
char * tests[] = {
"function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" ,
@ -308,8 +229,8 @@ void testCompile()
Arena a;
Parser p(world, a, testScript, widenCString("testCompile"));
StmtNode *parsedStatements = p.parseProgram();
ICodeGenerator icg(&world);
JSScope glob;
ICodeGenerator icg(&world, &glob);
icg.isScript();
while (parsedStatements) {
icg.genStmt(parsedStatements);
@ -333,7 +254,6 @@ int main(int argc, char **argv)
using namespace JavaScript;
using namespace Shell;
#if 0
assert(testFactorial(world, 5) == 120);
testCompile();
#endif
readEvalPrint(stdin, world);

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

@ -36,6 +36,8 @@
namespace JavaScript {
namespace VM {
using namespace JSTypes;
Formatter& operator<< (Formatter& f, Instruction& i)
{
@ -44,11 +46,11 @@ namespace VM {
Formatter& operator<< (Formatter& f, RegisterList& rl)
{
Register* e = rl.end();
TypedRegister* e = rl.end();
f << "(";
for (RegisterList::iterator r = rl.begin(); r != e; r++) {
f << "R" << (*r);
f << "R" << r->first;
if ((r + 1) != e)
f << ", ";
}
@ -64,11 +66,11 @@ namespace VM {
f << "(";
RegisterList::const_iterator i = rl.begin(), e = rl.end();
if (i != e) {
Register r = *i++;
f << "R" << r << '=' << registers[r];
TypedRegister r = *i++;
f << "R" << r.first << '=' << registers[r.first];
while (i != e) {
r = *i++;
f << ", R" << r << '=' << registers[r];
f << ", R" << r.first << '=' << registers[r.first];
}
}
f << ")";

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

@ -49,9 +49,7 @@ namespace ICG {
namespace JavaScript {
namespace VM {
using JSTypes::JSValue;
using JSTypes::JSValues;
using JSTypes::JSString;
using namespace JSTypes;
enum ICodeOp {
ADD, /* dest, source1, source2 */
@ -75,10 +73,10 @@ namespace VM {
GET_PROP, /* dest, object, prop name */
INSTANCEOF, /* dest, source1, source2 */
JSR, /* target */
LOAD_BOOLEAN, /* dest, immediate value (boolean) */
LOAD_IMMEDIATE, /* dest, immediate value (double) */
LOAD_NAME, /* dest, name */
LOAD_STRING, /* dest, immediate value (string) */
LOAD_VALUE, /* dest, immediate value (JSValue) */
MOVE, /* dest, source */
MULTIPLY, /* dest, source1, source2 */
NAME_XCR, /* dest, name, value */
@ -113,8 +111,6 @@ namespace VM {
XOR, /* dest, source1, source2 */
};
/********************************************************************/
static char *opcodeNames[] = {
@ -139,10 +135,10 @@ namespace VM {
"GET_PROP ",
"INSTANCEOF ",
"JSR ",
"LOAD_BOOLEAN ",
"LOAD_IMMEDIATE",
"LOAD_NAME ",
"LOAD_STRING ",
"LOAD_VALUE ",
"MOVE ",
"MULTIPLY ",
"NAME_XCR ",
@ -233,10 +229,12 @@ namespace VM {
/********************************************************************/
typedef uint32 Register;
typedef std::vector<Register> RegisterList;
typedef std::pair<Register, const JSType*> TypedRegister;
typedef std::vector<TypedRegister> RegisterList;
typedef std::vector<Instruction *> InstructionStream;
typedef InstructionStream::iterator InstructionIterator;
typedef std::map<String, Register, std::less<String> > VariableMap;
typedef std::map<String, TypedRegister, std::less<String> > VariableMap;
/**
* Helper to print Call operands.
@ -343,60 +341,59 @@ namespace VM {
/* Instruction groups */
class Arithmetic : public Instruction_3<Register, Register, Register> {
class Arithmetic : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
Arithmetic (ICodeOp aOpcode, Register aDest, Register aSrc1,
Register aSrc2) :
Instruction_3<Register, Register, Register>(aOpcode, aDest, aSrc1,
aSrc2) {}
Arithmetic (ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc1,
TypedRegister aSrc2) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>(aOpcode, aDest, aSrc1, aSrc2) {}
virtual Formatter& print(Formatter& f)
{
f << opcodeNames[mOpcode] << "\tR" << mOp1 << ", R" << mOp2 << ", R" << mOp3;
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first << ", R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class Unary : public Instruction_2<Register, Register> {
class Unary : public Instruction_2<TypedRegister, TypedRegister> {
public:
Unary(ICodeOp aOpcode, Register aDest, Register aSrc) :
Instruction_2<Register, Register>(aOpcode, aDest, aSrc) {}
Unary(ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc) :
Instruction_2<TypedRegister, TypedRegister>(aOpcode, aDest, aSrc) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tR" << mOp1 << ", R" << mOp2;
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class GenericBranch : public Instruction_2<Label*, Register> {
class GenericBranch : public Instruction_2<Label*, TypedRegister> {
public:
GenericBranch (ICodeOp aOpcode, Label* aLabel,
Register aR = NotARegister) :
Instruction_2<Label*, Register>(aOpcode, aLabel, aR) {}
TypedRegister aR = TypedRegister(NotARegister, &Any_Type) ) :
Instruction_2<Label*, TypedRegister>(aOpcode, aLabel, aR) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset;
if (mOp2 == NotARegister) {
if (mOp2.first == NotARegister) {
f << ", R~";
} else {
f << ", R" << mOp2;
f << ", R" << mOp2.first;
}
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
if (mOp2 != NotARegister)
f << "R" << mOp2 << '=' << registers[mOp2];
if (mOp2.first != NotARegister)
f << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
@ -411,7 +408,7 @@ namespace VM {
class Add : public Arithmetic {
public:
/* dest, source1, source2 */
Add (Register aOp1, Register aOp2, Register aOp3) :
Add (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(ADD, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
@ -420,24 +417,24 @@ namespace VM {
class And : public Arithmetic {
public:
/* dest, source1, source2 */
And (Register aOp1, Register aOp2, Register aOp3) :
And (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(AND, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Bitnot : public Instruction_2<Register, Register> {
class Bitnot : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Bitnot (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Bitnot (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(BITNOT, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[BITNOT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[BITNOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -460,7 +457,7 @@ namespace VM {
class BranchFalse : public GenericBranch {
public:
/* target label, condition */
BranchFalse (Label* aOp1, Register aOp2) :
BranchFalse (Label* aOp1, TypedRegister aOp2) :
GenericBranch
(BRANCH_FALSE, aOp1, aOp2) {};
/* print() and printOperands() inherited from GenericBranch */
@ -469,155 +466,155 @@ namespace VM {
class BranchTrue : public GenericBranch {
public:
/* target label, condition */
BranchTrue (Label* aOp1, Register aOp2) :
BranchTrue (Label* aOp1, TypedRegister aOp2) :
GenericBranch
(BRANCH_TRUE, aOp1, aOp2) {};
/* print() and printOperands() inherited from GenericBranch */
};
class Call : public Instruction_3<Register, Register, RegisterList> {
class Call : public Instruction_3<TypedRegister, TypedRegister, RegisterList> {
public:
/* result, target, args */
Call (Register aOp1, Register aOp2, RegisterList aOp3) :
Instruction_3<Register, Register, RegisterList>
Call (TypedRegister aOp1, TypedRegister aOp2, RegisterList aOp3) :
Instruction_3<TypedRegister, TypedRegister, RegisterList>
(CALL, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[CALL] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << mOp3;
f << opcodeNames[CALL] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << ArgList(mOp3, registers);
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << ArgList(mOp3, registers);
return f;
}
};
class CompareEQ : public Instruction_3<Register, Register, Register> {
class CompareEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareEQ (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareEQ (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_EQ, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareGE : public Instruction_3<Register, Register, Register> {
class CompareGE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareGE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareGE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_GE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareGT : public Instruction_3<Register, Register, Register> {
class CompareGT : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareGT (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareGT (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_GT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareIN : public Instruction_3<Register, Register, Register> {
class CompareIN : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareIN (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareIN (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_IN, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareLE : public Instruction_3<Register, Register, Register> {
class CompareLE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareLE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareLE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_LE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareLT : public Instruction_3<Register, Register, Register> {
class CompareLT : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareLT (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareLT (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_LT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareNE : public Instruction_3<Register, Register, Register> {
class CompareNE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareNE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareNE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_NE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class Divide : public Arithmetic {
public:
/* dest, source1, source2 */
Divide (Register aOp1, Register aOp2, Register aOp3) :
Divide (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(DIVIDE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class ElemXcr : public Instruction_4<Register, Register, Register, double> {
class ElemXcr : public Instruction_4<TypedRegister, TypedRegister, TypedRegister, double> {
public:
/* dest, base, index, value */
ElemXcr (Register aOp1, Register aOp2, Register aOp3, double aOp4) :
Instruction_4<Register, Register, Register, double>
ElemXcr (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3, double aOp4) :
Instruction_4<TypedRegister, TypedRegister, TypedRegister, double>
(ELEM_XCR, aOp1, aOp2, aOp3, aOp4) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[ELEM_XCR] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "R" << mOp3 << ", " << mOp4;
f << opcodeNames[ELEM_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first << ", " << mOp4;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class GetElement : public Instruction_3<Register, Register, Register> {
class GetElement : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, base, index */
GetElement (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
GetElement (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(GET_ELEMENT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[GET_ELEMENT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "R" << mOp3;
f << opcodeNames[GET_ELEMENT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class GetProp : public Instruction_3<Register, Register, const StringAtom*> {
class GetProp : public Instruction_3<TypedRegister, TypedRegister, const StringAtom*> {
public:
/* dest, object, prop name */
GetProp (Register aOp1, Register aOp2, const StringAtom* aOp3) :
Instruction_3<Register, Register, const StringAtom*>
GetProp (TypedRegister aOp1, TypedRegister aOp2, const StringAtom* aOp3) :
Instruction_3<TypedRegister, TypedRegister, const StringAtom*>
(GET_PROP, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[GET_PROP] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "'" << *mOp3 << "'";
f << opcodeNames[GET_PROP] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Instanceof : public Instruction_3<Register, Register, Register> {
class Instanceof : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
Instanceof (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
Instanceof (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(INSTANCEOF, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class Jsr : public GenericBranch {
@ -635,82 +632,82 @@ namespace VM {
}
};
class LoadImmediate : public Instruction_2<Register, double> {
class LoadBoolean : public Instruction_2<TypedRegister, bool> {
public:
/* dest, immediate value (boolean) */
LoadBoolean (TypedRegister aOp1, bool aOp2) :
Instruction_2<TypedRegister, bool>
(LOAD_BOOLEAN, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_BOOLEAN] << "\t" << "R" << mOp1.first << ", " << "'" << ((mOp2) ? "true" : "false") << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadImmediate : public Instruction_2<TypedRegister, double> {
public:
/* dest, immediate value (double) */
LoadImmediate (Register aOp1, double aOp2) :
Instruction_2<Register, double>
LoadImmediate (TypedRegister aOp1, double aOp2) :
Instruction_2<TypedRegister, double>
(LOAD_IMMEDIATE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_IMMEDIATE] << "\t" << "R" << mOp1 << ", " << mOp2;
f << opcodeNames[LOAD_IMMEDIATE] << "\t" << "R" << mOp1.first << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadName : public Instruction_2<Register, const StringAtom*> {
class LoadName : public Instruction_2<TypedRegister, const StringAtom*> {
public:
/* dest, name */
LoadName (Register aOp1, const StringAtom* aOp2) :
Instruction_2<Register, const StringAtom*>
LoadName (TypedRegister aOp1, const StringAtom* aOp2) :
Instruction_2<TypedRegister, const StringAtom*>
(LOAD_NAME, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_NAME] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'";
f << opcodeNames[LOAD_NAME] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadString : public Instruction_2<Register, JSString*> {
class LoadString : public Instruction_2<TypedRegister, JSString*> {
public:
/* dest, immediate value (string) */
LoadString (Register aOp1, JSString* aOp2) :
Instruction_2<Register, JSString*>
LoadString (TypedRegister aOp1, JSString* aOp2) :
Instruction_2<TypedRegister, JSString*>
(LOAD_STRING, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_STRING] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'";
f << opcodeNames[LOAD_STRING] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadValue : public Instruction_2<Register, JSValue> {
public:
/* dest, immediate value (JSValue) */
LoadValue (Register aOp1, JSValue aOp2) :
Instruction_2<Register, JSValue>
(LOAD_VALUE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_VALUE] << "\t" << "R" << mOp1 << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
return f;
}
};
class Move : public Instruction_2<Register, Register> {
class Move : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Move (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Move (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(MOVE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[MOVE] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[MOVE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -718,72 +715,72 @@ namespace VM {
class Multiply : public Arithmetic {
public:
/* dest, source1, source2 */
Multiply (Register aOp1, Register aOp2, Register aOp3) :
Multiply (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(MULTIPLY, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class NameXcr : public Instruction_3<Register, const StringAtom*, double> {
class NameXcr : public Instruction_3<TypedRegister, const StringAtom*, double> {
public:
/* dest, name, value */
NameXcr (Register aOp1, const StringAtom* aOp2, double aOp3) :
Instruction_3<Register, const StringAtom*, double>
NameXcr (TypedRegister aOp1, const StringAtom* aOp2, double aOp3) :
Instruction_3<TypedRegister, const StringAtom*, double>
(NAME_XCR, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NAME_XCR] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'" << ", " << mOp3;
f << opcodeNames[NAME_XCR] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class Negate : public Instruction_2<Register, Register> {
class Negate : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Negate (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Negate (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(NEGATE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEGATE] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[NEGATE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class NewArray : public Instruction_1<Register> {
class NewArray : public Instruction_1<TypedRegister> {
public:
/* dest */
NewArray (Register aOp1) :
Instruction_1<Register>
NewArray (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(NEW_ARRAY, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEW_ARRAY] << "\t" << "R" << mOp1;
f << opcodeNames[NEW_ARRAY] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class NewObject : public Instruction_1<Register> {
class NewObject : public Instruction_1<TypedRegister> {
public:
/* dest */
NewObject (Register aOp1) :
Instruction_1<Register>
NewObject (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(NEW_OBJECT, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEW_OBJECT] << "\t" << "R" << mOp1;
f << opcodeNames[NEW_OBJECT] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -803,18 +800,18 @@ namespace VM {
}
};
class Not : public Instruction_2<Register, Register> {
class Not : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Not (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Not (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(NOT, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NOT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[NOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -822,40 +819,40 @@ namespace VM {
class Or : public Arithmetic {
public:
/* dest, source1, source2 */
Or (Register aOp1, Register aOp2, Register aOp3) :
Or (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(OR, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Posate : public Instruction_2<Register, Register> {
class Posate : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Posate (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Posate (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(POSATE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[POSATE] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[POSATE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class PropXcr : public Instruction_4<Register, Register, const StringAtom*, double> {
class PropXcr : public Instruction_4<TypedRegister, TypedRegister, const StringAtom*, double> {
public:
/* dest, source, name, value */
PropXcr (Register aOp1, Register aOp2, const StringAtom* aOp3, double aOp4) :
Instruction_4<Register, Register, const StringAtom*, double>
PropXcr (TypedRegister aOp1, TypedRegister aOp2, const StringAtom* aOp3, double aOp4) :
Instruction_4<TypedRegister, TypedRegister, const StringAtom*, double>
(PROP_XCR, aOp1, aOp2, aOp3, aOp4) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[PROP_XCR] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "'" << *mOp3 << "'" << ", " << mOp4;
f << opcodeNames[PROP_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'" << ", " << mOp4;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -863,24 +860,24 @@ namespace VM {
class Remainder : public Arithmetic {
public:
/* dest, source1, source2 */
Remainder (Register aOp1, Register aOp2, Register aOp3) :
Remainder (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(REMAINDER, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Return : public Instruction_1<Register> {
class Return : public Instruction_1<TypedRegister> {
public:
/* return value */
Return (Register aOp1) :
Instruction_1<Register>
Return (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(RETURN, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[RETURN] << "\t" << "R" << mOp1;
f << opcodeNames[RETURN] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -915,50 +912,50 @@ namespace VM {
}
};
class SaveName : public Instruction_2<const StringAtom*, Register> {
class SaveName : public Instruction_2<const StringAtom*, TypedRegister> {
public:
/* name, source */
SaveName (const StringAtom* aOp1, Register aOp2) :
Instruction_2<const StringAtom*, Register>
SaveName (const StringAtom* aOp1, TypedRegister aOp2) :
Instruction_2<const StringAtom*, TypedRegister>
(SAVE_NAME, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SAVE_NAME] << "\t" << "'" << *mOp1 << "'" << ", " << "R" << mOp2;
f << opcodeNames[SAVE_NAME] << "\t" << "'" << *mOp1 << "'" << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class SetElement : public Instruction_3<Register, Register, Register> {
class SetElement : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* base, index, value */
SetElement (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
SetElement (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(SET_ELEMENT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SET_ELEMENT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "R" << mOp3;
f << opcodeNames[SET_ELEMENT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class SetProp : public Instruction_3<Register, const StringAtom*, Register> {
class SetProp : public Instruction_3<TypedRegister, const StringAtom*, TypedRegister> {
public:
/* object, name, source */
SetProp (Register aOp1, const StringAtom* aOp2, Register aOp3) :
Instruction_3<Register, const StringAtom*, Register>
SetProp (TypedRegister aOp1, const StringAtom* aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, const StringAtom*, TypedRegister>
(SET_PROP, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SET_PROP] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'" << ", " << "R" << mOp3;
f << opcodeNames[SET_PROP] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
@ -966,7 +963,7 @@ namespace VM {
class Shiftleft : public Arithmetic {
public:
/* dest, source1, source2 */
Shiftleft (Register aOp1, Register aOp2, Register aOp3) :
Shiftleft (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(SHIFTLEFT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
@ -975,67 +972,67 @@ namespace VM {
class Shiftright : public Arithmetic {
public:
/* dest, source1, source2 */
Shiftright (Register aOp1, Register aOp2, Register aOp3) :
Shiftright (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(SHIFTRIGHT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class StrictEQ : public Instruction_3<Register, Register, Register> {
class StrictEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
StrictEQ (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
StrictEQ (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(STRICT_EQ, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class StrictNE : public Instruction_3<Register, Register, Register> {
class StrictNE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
StrictNE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
StrictNE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(STRICT_NE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class Subtract : public Arithmetic {
public:
/* dest, source1, source2 */
Subtract (Register aOp1, Register aOp2, Register aOp3) :
Subtract (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(SUBTRACT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Test : public Instruction_2<Register, Register> {
class Test : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Test (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Test (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(TEST, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[TEST] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[TEST] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Throw : public Instruction_1<Register> {
class Throw : public Instruction_1<TypedRegister> {
public:
/* exception value */
Throw (Register aOp1) :
Instruction_1<Register>
Throw (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(THROW, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[THROW] << "\t" << "R" << mOp1;
f << opcodeNames[THROW] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -1073,40 +1070,40 @@ namespace VM {
class Ushiftright : public Arithmetic {
public:
/* dest, source1, source2 */
Ushiftright (Register aOp1, Register aOp2, Register aOp3) :
Ushiftright (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(USHIFTRIGHT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class VarXcr : public Instruction_3<Register, Register, double> {
class VarXcr : public Instruction_3<TypedRegister, TypedRegister, double> {
public:
/* dest, source, value */
VarXcr (Register aOp1, Register aOp2, double aOp3) :
Instruction_3<Register, Register, double>
VarXcr (TypedRegister aOp1, TypedRegister aOp2, double aOp3) :
Instruction_3<TypedRegister, TypedRegister, double>
(VAR_XCR, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[VAR_XCR] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << mOp3;
f << opcodeNames[VAR_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Within : public Instruction_1<Register> {
class Within : public Instruction_1<TypedRegister> {
public:
/* within this object */
Within (Register aOp1) :
Instruction_1<Register>
Within (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(WITHIN, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[WITHIN] << "\t" << "R" << mOp1;
f << opcodeNames[WITHIN] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -1129,14 +1126,12 @@ namespace VM {
class Xor : public Arithmetic {
public:
/* dest, source1, source2 */
Xor (Register aOp1, Register aOp2, Register aOp3) :
Xor (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(XOR, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
} /* namespace VM */
} /* namespace JavaScript */

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

@ -61,14 +61,15 @@ Formatter& operator<<(Formatter &f, ICodeModule &i)
// ICodeGenerator
//
ICodeGenerator::ICodeGenerator(World *world)
ICodeGenerator::ICodeGenerator(World *world, JSScope *global)
: topRegister(0),
registerBase(0),
maxRegister(0),
parameterCount(0),
exceptionRegister(NotARegister),
exceptionRegister(TypedRegister(NotARegister, &None_Type)),
variableList(new VariableList()),
mWorld(world),
mGlobal(global),
mInstructionMap(new InstructionMap()),
mWithinWith(false)
@ -77,12 +78,28 @@ ICodeGenerator::ICodeGenerator(World *world)
iCodeOwner = true;
}
Register ICodeGenerator::allocateVariable(const StringAtom& name)
const JSType *ICodeGenerator::findType(const StringAtom& typeName)
{
const JSValue& type = mGlobal->getVariable(typeName);
if (type.isType())
return type.type;
return &Any_Type;
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name, const StringAtom& typeName)
{
if (exceptionRegister == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")]);
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name);
return grabRegister(name, findType(typeName));
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name)
{
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name, &Any_Type);
}
ICodeModule *ICodeGenerator::complete()
@ -126,41 +143,41 @@ ICodeModule *ICodeGenerator::complete()
/********************************************************************/
Register ICodeGenerator::loadImmediate(double value)
TypedRegister ICodeGenerator::loadImmediate(double value)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
LoadImmediate *instr = new LoadImmediate(dest, value);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::loadString(String &value)
TypedRegister ICodeGenerator::loadString(String &value)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &String_Type);
LoadString *instr = new LoadString(dest, new JSString(value));
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::loadValue(JSValue value)
TypedRegister ICodeGenerator::loadBoolean(bool value)
{
Register dest = getRegister();
LoadValue *instr = new LoadValue(dest, value);
TypedRegister dest(getRegister(), &Boolean_Type);
LoadBoolean *instr = new LoadBoolean(dest, value);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::newObject()
TypedRegister ICodeGenerator::newObject()
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
NewObject *instr = new NewObject(dest);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::newArray()
TypedRegister ICodeGenerator::newArray()
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Array_Type);
NewArray *instr = new NewArray(dest);
iCode->push_back(instr);
return dest;
@ -168,47 +185,47 @@ Register ICodeGenerator::newArray()
Register ICodeGenerator::loadName(const StringAtom &name)
TypedRegister ICodeGenerator::loadName(const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
LoadName *instr = new LoadName(dest, &name);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::saveName(const StringAtom &name, Register value)
void ICodeGenerator::saveName(const StringAtom &name, TypedRegister value)
{
SaveName *instr = new SaveName(&name, value);
iCode->push_back(instr);
}
Register ICodeGenerator::nameInc(const StringAtom &name)
TypedRegister ICodeGenerator::nameInc(const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
NameXcr *instr = new NameXcr(dest, &name, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::nameDec(const StringAtom &name)
TypedRegister ICodeGenerator::nameDec(const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
NameXcr *instr = new NameXcr(dest, &name, -1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::varInc(Register var)
TypedRegister ICodeGenerator::varInc(TypedRegister var)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
VarXcr *instr = new VarXcr(dest, var, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::varDec(Register var)
TypedRegister ICodeGenerator::varDec(TypedRegister var)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
VarXcr *instr = new VarXcr(dest, var, -1.0);
iCode->push_back(instr);
return dest;
@ -216,32 +233,32 @@ Register ICodeGenerator::varDec(Register var)
Register ICodeGenerator::getProperty(Register base, const StringAtom &name)
TypedRegister ICodeGenerator::getProperty(TypedRegister base, const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
GetProp *instr = new GetProp(dest, base, &name);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::setProperty(Register base, const StringAtom &name,
Register value)
void ICodeGenerator::setProperty(TypedRegister base, const StringAtom &name,
TypedRegister value)
{
SetProp *instr = new SetProp(base, &name, value);
iCode->push_back(instr);
}
Register ICodeGenerator::propertyInc(Register base, const StringAtom &name)
TypedRegister ICodeGenerator::propertyInc(TypedRegister base, const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
PropXcr *instr = new PropXcr(dest, base, &name, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::propertyDec(Register base, const StringAtom &name)
TypedRegister ICodeGenerator::propertyDec(TypedRegister base, const StringAtom &name)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
PropXcr *instr = new PropXcr(dest, base, &name, -1.0);
iCode->push_back(instr);
return dest;
@ -249,94 +266,94 @@ Register ICodeGenerator::propertyDec(Register base, const StringAtom &name)
Register ICodeGenerator::getElement(Register base, Register index)
TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
GetElement *instr = new GetElement(dest, base, index);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::setElement(Register base, Register index,
Register value)
void ICodeGenerator::setElement(TypedRegister base, TypedRegister index,
TypedRegister value)
{
SetElement *instr = new SetElement(base, index, value);
iCode->push_back(instr);
}
Register ICodeGenerator::elementInc(Register base, Register index)
TypedRegister ICodeGenerator::elementInc(TypedRegister base, TypedRegister index)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
ElemXcr *instr = new ElemXcr(dest, base, index, 1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::elementDec(Register base, Register index)
TypedRegister ICodeGenerator::elementDec(TypedRegister base, TypedRegister index)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Number_Type);
ElemXcr *instr = new ElemXcr(dest, base, index, -1.0);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::op(ICodeOp op, Register source)
TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source)
{
Register dest = getRegister();
ASSERT(source != NotARegister);
TypedRegister dest(getRegister(), &Any_Type);
ASSERT(source.first != NotARegister);
Unary *instr = new Unary (op, dest, source);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::move(Register destination, Register source)
void ICodeGenerator::move(TypedRegister destination, TypedRegister source)
{
ASSERT(destination != NotARegister);
ASSERT(source != NotARegister);
ASSERT(destination.first != NotARegister);
ASSERT(source.first != NotARegister);
Move *instr = new Move(destination, source);
iCode->push_back(instr);
}
Register ICodeGenerator::logicalNot(Register source)
TypedRegister ICodeGenerator::logicalNot(TypedRegister source)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
Not *instr = new Not(dest, source);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::test(Register source)
TypedRegister ICodeGenerator::test(TypedRegister source)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
Test *instr = new Test(dest, source);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::op(ICodeOp op, Register source1,
Register source2)
TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1,
TypedRegister source2)
{
ASSERT(source1 != NotARegister);
ASSERT(source2 != NotARegister);
Register dest = getRegister();
ASSERT(source1.first != NotARegister);
ASSERT(source2.first != NotARegister);
TypedRegister dest(getRegister(), &Any_Type);
Arithmetic *instr = new Arithmetic(op, dest, source1, source2);
iCode->push_back(instr);
return dest;
}
Register ICodeGenerator::call(Register target, RegisterList args)
TypedRegister ICodeGenerator::call(TypedRegister target, RegisterList args)
{
Register dest = getRegister();
TypedRegister dest(getRegister(), &Any_Type);
Call *instr = new Call(dest, target, args);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::callVoid(Register target, RegisterList args)
void ICodeGenerator::callVoid(TypedRegister target, RegisterList args)
{
Call *instr = new Call(NotARegister, target, args);
Call *instr = new Call(TypedRegister(NotARegister, &Void_Type), target, args);
iCode->push_back(instr);
}
@ -346,23 +363,23 @@ void ICodeGenerator::branch(Label *label)
iCode->push_back(instr);
}
GenericBranch *ICodeGenerator::branchTrue(Label *label, Register condition)
GenericBranch *ICodeGenerator::branchTrue(Label *label, TypedRegister condition)
{
GenericBranch *instr = new GenericBranch(BRANCH_TRUE, label, condition);
iCode->push_back(instr);
return instr;
}
GenericBranch *ICodeGenerator::branchFalse(Label *label, Register condition)
GenericBranch *ICodeGenerator::branchFalse(Label *label, TypedRegister condition)
{
GenericBranch *instr = new GenericBranch(BRANCH_FALSE, label, condition);
iCode->push_back(instr);
return instr;
}
void ICodeGenerator::returnStmt(Register r)
void ICodeGenerator::returnStmt(TypedRegister r)
{
if (r == NotARegister)
if (r.first == NotARegister)
iCode->push_back(new ReturnVoid());
else
iCode->push_back(new Return(r));
@ -504,37 +521,37 @@ static bool generatedBoolean(ExprNode *p)
a conditional branch to the appropriate target. If either branch is NULL, it
indicates that the label is immediately forthcoming.
*/
Result ICodeGenerator::genExpr(ExprNode *p,
TypedRegister ICodeGenerator::genExpr(ExprNode *p,
bool needBoolValueInBranch,
Label *trueBranch,
Label *falseBranch)
{
Register ret = NotARegister;
TypedRegister ret(NotARegister, &None_Type);
switch (p->getKind()) {
case ExprNode::True:
if (trueBranch || falseBranch) {
if (needBoolValueInBranch)
ret = loadValue(kTrue);
ret = loadBoolean(true);
if (trueBranch)
branch(trueBranch);
}
else
ret = loadValue(kTrue);
ret = loadBoolean(true);
break;
case ExprNode::False:
if (trueBranch || falseBranch) {
if (needBoolValueInBranch)
ret = loadValue(kFalse);
ret = loadBoolean(false);
if (falseBranch)
branch(falseBranch);
}
else
ret = loadValue(kFalse);
ret = loadBoolean(false);
break;
case ExprNode::parentheses:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch).reg;
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch);
}
break;
case ExprNode::New:
@ -546,11 +563,11 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::call :
{
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
Register fn = genExpr(i->op).reg;
TypedRegister fn = genExpr(i->op);
RegisterList args;
ExprPairList *p = i->pairs;
while (p) {
args.push_back(genExpr(p->value).reg);
args.push_back(genExpr(p->value));
p = p->next;
}
ret = call(fn, args);
@ -559,23 +576,23 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
}
break;
case ExprNode::dot :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
break;
case ExprNode::identifier :
{
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(p))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(p))->name);
if (v.first != NotARegister)
ret = v;
else
ret = loadName((static_cast<IdentifierExprNode *>(p))->name);
@ -595,7 +612,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
ret = op(ADD, ret, loadImmediate(1.0));
setProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name, ret);
@ -603,8 +620,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = op(ADD, ret, loadImmediate(1.0));
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
@ -621,8 +638,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
ret = op(ADD, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -634,14 +651,14 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = propertyInc(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = varInc(v);
else
ret = nameInc((static_cast<IdentifierExprNode *>(u->op))->name);
@ -652,8 +669,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = elementInc(base, index);
}
}
@ -663,7 +680,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name, ret);
@ -671,8 +688,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = op(SUBTRACT, ret, loadImmediate(1.0));
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
@ -689,8 +706,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -702,14 +719,14 @@ Result ICodeGenerator::genExpr(ExprNode *p,
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
TypedRegister base = genExpr(b->op1);
ret = propertyDec(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = varDec(v);
else
ret = nameDec((static_cast<IdentifierExprNode *>(u->op))->name);
@ -720,8 +737,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = elementInc(base, index);
}
}
@ -731,7 +748,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::complement:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
Register r = genExpr(u->op).reg;
TypedRegister r = genExpr(u->op);
ret = op(mapExprNodeToICodeOp(p->getKind()), r);
}
break;
@ -748,19 +765,19 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOr:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
}
break;
case ExprNode::assignment:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2).reg;
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v != NotARegister)
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v.first != NotARegister)
move(v, ret);
else
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
@ -771,14 +788,14 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
TypedRegister base = genExpr(lb->op1);
setProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name, ret);
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
setElement(base, index, ret);
}
}
@ -796,11 +813,11 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOrEquals:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2).reg;
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v != NotARegister) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v.first != NotARegister) {
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
move(v, ret);
}
@ -811,7 +828,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
}
}
else {
Register v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
TypedRegister v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
}
@ -819,17 +836,17 @@ Result ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
Register v = getProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name);
TypedRegister base = genExpr(lb->op1);
TypedRegister v = getProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name, ret);
}
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
Register v = getElement(base, index);
TypedRegister base = genExpr(lb->op1);
TypedRegister index = genExpr(lb->op2);
TypedRegister v = getElement(base, index);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setElement(base, index, ret);
}
@ -843,8 +860,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::Instanceof:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -861,8 +878,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::greaterThanOrEqual:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r2, r1); // will return reverse case
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -880,8 +897,8 @@ Result ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::notIdentical:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
TypedRegister r1 = genExpr(b->op1);
TypedRegister r2 = genExpr(b->op2);
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -907,12 +924,12 @@ Result ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *fBranch = getLabel();
Register r1 = genExpr(b->op1, true, NULL, fBranch).reg;
TypedRegister r1 = genExpr(b->op1, true, NULL, fBranch);
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchFalse(fBranch, r1);
}
Register r2 = genExpr(b->op2).reg;
TypedRegister r2 = genExpr(b->op2);
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -932,12 +949,12 @@ Result ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *tBranch = getLabel();
Register r1 = genExpr(b->op1, true, tBranch, NULL).reg;
TypedRegister r1 = genExpr(b->op1, true, tBranch, NULL);
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchTrue(tBranch, r1);
}
Register r2 = genExpr(b->op2).reg;
TypedRegister r2 = genExpr(b->op2);
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -954,13 +971,13 @@ Result ICodeGenerator::genExpr(ExprNode *p,
TernaryExprNode *t = static_cast<TernaryExprNode *>(p);
Label *fBranch = getLabel();
Label *beyondBranch = getLabel();
Register c = genExpr(t->op1, false, NULL, fBranch).reg;
TypedRegister c = genExpr(t->op1, false, NULL, fBranch);
if (!generatedBoolean(t->op1))
branchFalse(fBranch, test(c));
Register r1 = genExpr(t->op2).reg;
TypedRegister r1 = genExpr(t->op2);
branch(beyondBranch);
setLabel(fBranch);
Register r2 = genExpr(t->op3).reg;
TypedRegister r2 = genExpr(t->op3);
if (r1 != r2) // FIXME, need a way to specify a dest???
move(r1, r2);
setLabel(beyondBranch);
@ -976,7 +993,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
ExprPairList *e = plen->pairs;
while (e) {
if (e->field && e->value && (e->field->getKind() == ExprNode::identifier))
setProperty(ret, (static_cast<IdentifierExprNode *>(e->field))->name, genExpr(e->value).reg);
setProperty(ret, (static_cast<IdentifierExprNode *>(e->field))->name, genExpr(e->value));
e = e->next;
}
}
@ -987,7 +1004,7 @@ Result ICodeGenerator::genExpr(ExprNode *p,
NOT_REACHED("Unsupported ExprNode kind");
}
}
return Result(ret, Any_Type);
return ret;
}
/*
@ -1110,20 +1127,20 @@ void ICodeGenerator::preprocess(StmtNode *p)
}
}
Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
{
Register ret = NotARegister;
TypedRegister ret(NotARegister, &None_Type);
startStatement(p->pos);
if (exceptionRegister == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")]);
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
switch (p->getKind()) {
case StmtNode::Function:
{
FunctionStmtNode *f = static_cast<FunctionStmtNode *>(p);
ICodeGenerator icg(mWorld);
ICodeGenerator icg(mWorld, mGlobal);
VariableBinding *v = f->function.parameters;
while (v) {
if (v->name && (v->name->getKind() == ExprNode::identifier))
@ -1146,12 +1163,12 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
if (v->name && v->initializer) {
if (v->name->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register r = genExpr(v->name).reg;
Register val = genExpr(v->initializer).reg;
TypedRegister r = genExpr(v->name);
TypedRegister val = genExpr(v->initializer);
move(r, val);
}
else {
Register val = genExpr(v->initializer).reg;
TypedRegister val = genExpr(v->initializer);
saveName((static_cast<IdentifierExprNode *>(v->name))->name, val);
}
}
@ -1164,29 +1181,29 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::expression:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
ret = genExpr(e->expr).reg;
ret = genExpr(e->expr);
}
break;
case StmtNode::Throw:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
throwStmt(genExpr(e->expr).reg);
throwStmt(genExpr(e->expr));
}
break;
case StmtNode::Return:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
if (e->expr)
returnStmt(ret = genExpr(e->expr).reg);
returnStmt(ret = genExpr(e->expr));
else
returnStmt(NotARegister);
returnStmt(TypedRegister(NotARegister, &Void_Type));
}
break;
case StmtNode::If:
{
Label *falseLabel = getLabel();
UnaryStmtNode *i = static_cast<UnaryStmtNode *>(p);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
TypedRegister c = genExpr(i->expr, false, NULL, falseLabel);
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1198,7 +1215,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
Label *falseLabel = getLabel();
Label *beyondLabel = getLabel();
BinaryStmtNode *i = static_cast<BinaryStmtNode *>(p);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
TypedRegister c = genExpr(i->expr, false, NULL, falseLabel);
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1211,7 +1228,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::With:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
Register o = genExpr(w->expr).reg;
TypedRegister o = genExpr(w->expr);
bool withinWith = mWithinWith;
mWithinWith = true;
beginWith(o);
@ -1226,7 +1243,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
LabelEntry *e = new LabelEntry(currentLabelSet, getLabel());
mLabelStack.push_back(e);
SwitchStmtNode *sw = static_cast<SwitchStmtNode *>(p);
Register sc = genExpr(sw->expr).reg;
TypedRegister sc = genExpr(sw->expr);
StmtNode *s = sw->statements;
// ECMA requires case & default statements to be immediate children of switch
// unlike C where they can be arbitrarily deeply nested in other statements.
@ -1239,8 +1256,8 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
if (nextCaseLabel)
setLabel(nextCaseLabel);
nextCaseLabel = getLabel();
Register r = genExpr(c->expr).reg;
Register eq = op(COMPARE_EQ, r, sc);
TypedRegister r = genExpr(c->expr);
TypedRegister eq = op(COMPARE_EQ, r, sc);
lastBranch = branchFalse(nextCaseLabel, eq);
}
else {
@ -1270,7 +1287,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(doBodyTopLabel);
genStmt(d->stmt);
setLabel(e->continueLabel);
Register c = genExpr(d->expr, false, doBodyTopLabel, NULL).reg;
TypedRegister c = genExpr(d->expr, false, doBodyTopLabel, NULL);
if (!generatedBoolean(d->expr))
branchTrue(doBodyTopLabel, test(c));
setLabel(e->breakLabel);
@ -1290,7 +1307,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
genStmt(w->stmt);
setLabel(e->continueLabel);
Register c = genExpr(w->expr, false, whileBodyTopLabel, NULL).reg;
TypedRegister c = genExpr(w->expr, false, whileBodyTopLabel, NULL);
if (!generatedBoolean(w->expr))
branchTrue(whileBodyTopLabel, test(c));
@ -1315,11 +1332,11 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(e->continueLabel);
if (f->expr3)
genExpr(f->expr3).reg;
genExpr(f->expr3);
setLabel(forTestLabel);
if (f->expr2) {
Register c = genExpr(f->expr2, false, forBlockTop, NULL).reg;
TypedRegister c = genExpr(f->expr2, false, forBlockTop, NULL);
if (!generatedBoolean(f->expr2))
branchTrue(forBlockTop, test(c));
}

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

@ -46,9 +46,9 @@ namespace JavaScript {
namespace ICG {
using namespace VM;
using namespace JSTypes;
typedef std::map<String, Register, std::less<String> > VariableList;
typedef std::map<String, TypedRegister, std::less<String> > VariableList;
typedef std::pair<uint32, uint32> InstructionMapping;
typedef std::vector<InstructionMapping *> InstructionMap;
@ -105,12 +105,6 @@ namespace ICG {
// function/script, adds statements and expressions to it and then
// converts it into an ICodeModule, ready for execution.
struct Result {
Result(Register reg, JSTypes::JSType type) : reg(reg), type(type) {}
Register reg;
JSTypes::JSType type;
};
class ICodeGenerator {
private:
InstructionStream *iCode;
@ -122,10 +116,11 @@ namespace ICG {
uint32 maxRegister; // highest (ever) allocated register
uint32 parameterCount; // number of parameters declared for the function
// these must come before any variables declared.
Register exceptionRegister; // reserved to carry the exception object.
TypedRegister exceptionRegister;// reserved to carry the exception object.
VariableList *variableList; // name|register pair for each variable
World *mWorld; // used to register strings
World *mWorld; // used to register strings
JSScope *mGlobal; // the scope for compiling within
LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct
InstructionMap *mInstructionMap;// maps source position to instruction index
@ -146,15 +141,15 @@ namespace ICG {
void jsr(Label *label) { iCode->push_back(new Jsr(label)); }
void rts() { iCode->push_back(new Rts()); }
void branch(Label *label);
GenericBranch *branchTrue(Label *label, Register condition);
GenericBranch *branchFalse(Label *label, Register condition);
GenericBranch *branchTrue(Label *label, TypedRegister condition);
GenericBranch *branchFalse(Label *label, TypedRegister condition);
void beginTry(Label *catchLabel, Label *finallyLabel)
{ iCode->push_back(new Tryin(catchLabel, finallyLabel)); }
void endTry()
{ iCode->push_back(new Tryout()); }
void beginWith(Register obj)
void beginWith(TypedRegister obj)
{ iCode->push_back(new Within(obj)); }
void endWith()
{ iCode->push_back(new Without()); }
@ -164,7 +159,7 @@ namespace ICG {
void resetStatement() { resetTopRegister(); }
void setRegisterForVariable(const StringAtom& name, Register r)
void setRegisterForVariable(const StringAtom& name, TypedRegister r)
{ (*variableList)[name] = r; }
@ -172,16 +167,18 @@ namespace ICG {
ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind);
Register grabRegister(const StringAtom& name)
TypedRegister grabRegister(const StringAtom& name, const JSType *type)
{
Register result = getRegister();
TypedRegister result(getRegister(), type);
(*variableList)[name] = result;
registerBase = topRegister;
return result;
}
const JSType *findType(const StringAtom& typeName);
public:
ICodeGenerator(World *world = NULL);
ICodeGenerator(World *world, JSScope *global);
~ICodeGenerator()
{
@ -193,65 +190,66 @@ namespace ICG {
ICodeModule *complete();
Result genExpr(ExprNode *p,
TypedRegister genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
void preprocess(StmtNode *p);
Register genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL);
TypedRegister genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL);
void isScript() { mWithinWith = true; }
void returnStmt(Register r);
void throwStmt(Register r)
void returnStmt(TypedRegister r);
void throwStmt(TypedRegister r)
{ iCode->push_back(new Throw(r)); }
Register allocateVariable(const StringAtom& name);
Register allocateVariable(const StringAtom& name, const StringAtom& /*type */)
{ return allocateVariable(name); }
TypedRegister allocateVariable(const StringAtom& name);
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName);
Register findVariable(const StringAtom& name)
TypedRegister findVariable(const StringAtom& name)
{ VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? NotARegister : (*i).second; }
return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; }
Register allocateParameter(const StringAtom& name)
{ parameterCount++; return grabRegister(name); }
TypedRegister allocateParameter(const StringAtom& name)
{ parameterCount++; return grabRegister(name, &Any_Type); }
TypedRegister allocateParameter(const StringAtom& name, const StringAtom& typeName)
{ parameterCount++; return grabRegister(name, findType(typeName)); }
Formatter& print(Formatter& f);
Register op(ICodeOp op, Register source);
Register op(ICodeOp op, Register source1, Register source2);
Register call(Register target, RegisterList args);
void callVoid(Register target, RegisterList args);
TypedRegister op(ICodeOp op, TypedRegister source);
TypedRegister op(ICodeOp op, TypedRegister source1, TypedRegister source2);
TypedRegister call(TypedRegister target, RegisterList args);
void callVoid(TypedRegister target, RegisterList args);
void move(Register destination, Register source);
Register logicalNot(Register source);
Register test(Register source);
void move(TypedRegister destination, TypedRegister source);
TypedRegister logicalNot(TypedRegister source);
TypedRegister test(TypedRegister source);
Register loadValue(JSValue value);
Register loadImmediate(double value);
Register loadString(String &value);
TypedRegister loadBoolean(bool value);
TypedRegister loadImmediate(double value);
TypedRegister loadString(String &value);
Register newObject();
Register newArray();
TypedRegister newObject();
TypedRegister newArray();
Register loadName(const StringAtom &name);
void saveName(const StringAtom &name, Register value);
Register nameInc(const StringAtom &name);
Register nameDec(const StringAtom &name);
TypedRegister loadName(const StringAtom &name);
void saveName(const StringAtom &name, TypedRegister value);
TypedRegister nameInc(const StringAtom &name);
TypedRegister nameDec(const StringAtom &name);
Register getProperty(Register base, const StringAtom &name);
void setProperty(Register base, const StringAtom &name, Register value);
Register propertyInc(Register base, const StringAtom &name);
Register propertyDec(Register base, const StringAtom &name);
TypedRegister getProperty(TypedRegister base, const StringAtom &name);
void setProperty(TypedRegister base, const StringAtom &name, TypedRegister value);
TypedRegister propertyInc(TypedRegister base, const StringAtom &name);
TypedRegister propertyDec(TypedRegister base, const StringAtom &name);
Register getElement(Register base, Register index);
void setElement(Register base, Register index, Register value);
Register elementInc(Register base, Register index);
Register elementDec(Register base, Register index);
TypedRegister getElement(TypedRegister base, TypedRegister index);
void setElement(TypedRegister base, TypedRegister index, TypedRegister value);
TypedRegister elementInc(TypedRegister base, TypedRegister index);
TypedRegister elementDec(TypedRegister base, TypedRegister index);
Register varInc(Register var);
Register varDec(Register var);
TypedRegister varInc(TypedRegister var);
TypedRegister varDec(TypedRegister var);
Register getRegisterBase() { return topRegister; }
InstructionStream *get_iCode() { return iCode; }

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

@ -98,7 +98,7 @@ struct Activation : public gc_base {
const JSValues& params = caller->mRegisters;
for (RegisterList::const_iterator src = list.begin(),
end = list.end(); src != end; ++src, ++dest) {
*dest = params[*src];
*dest = params[(*src).first];
}
}
@ -128,10 +128,10 @@ struct Linkage : public Context::Frame, public gc_base {
Linkage* mNext; // next linkage in linkage stack.
InstructionIterator mReturnPC;
Activation* mActivation; // caller's activation.
Register mResult; // the desired target register for the return value
TypedRegister mResult; // the desired target register for the return value
Linkage(Linkage* linkage, InstructionIterator returnPC,
Activation* activation, Register result)
Activation* activation, TypedRegister result)
: mNext(linkage), mReturnPC(returnPC),
mActivation(activation), mResult(result)
{
@ -146,31 +146,6 @@ void getState(InstructionIterator& pc, JSValues*& registers, ICodeModule*& iCode
iCode = mActivation->mICode;
}
};
/*
void Context::doCall(JSFunction *target, Instruction *pc)
{
if (target->isNative()) {
RegisterList &params = op3(call);
JSValues argv(params.size());
JSValues::size_type i = 0;
for (RegisterList::const_iterator src = params.begin(), end = params.end();
src != end; ++src, ++i) {
argv[i] = (*registers)[*src];
}
if (op2(call) != NotARegister)
(*registers)[op2(call)] = static_cast<JSNativeFunction*>(target)->mCode(argv);
return pc;
}
else {
mLinkage = new Linkage(mLinkage, ++mPC,
mActivation, op1(call));
iCode = target->getICode();
mActivation = new Activation(iCode, mActivation, op3(call));
registers = &mActivation->mRegisters;
continue;
}
}
*/
static JSValue shiftLeft_Default(const JSValue& r1, const JSValue& r2)
{
@ -517,17 +492,17 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
case CALL:
{
Call* call = static_cast<Call*>(instruction);
JSFunction *target = (*registers)[op2(call)].function;
JSFunction *target = (*registers)[op2(call).first].function;
if (target->isNative()) {
RegisterList &params = op3(call);
JSValues argv(params.size());
JSValues::size_type i = 0;
for (RegisterList::const_iterator src = params.begin(), end = params.end();
src != end; ++src, ++i) {
argv[i] = (*registers)[*src];
argv[i] = (*registers)[src->first];
}
if (op2(call) != NotARegister)
(*registers)[op2(call)] = static_cast<JSNativeFunction*>(target)->mCode(argv);
if (op2(call).first != NotARegister)
(*registers)[op2(call).first] = static_cast<JSNativeFunction*>(target)->mCode(argv);
break;
}
else {
@ -553,7 +528,7 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
mLinkage = linkage->mNext;
mActivation = linkage->mActivation;
registers = &mActivation->mRegisters;
(*registers)[linkage->mResult] = result;
(*registers)[linkage->mResult.first] = result;
mPC = linkage->mReturnPC;
}
continue;
@ -562,8 +537,8 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
{
Return* ret = static_cast<Return*>(instruction);
JSValue result;
if (op1(ret) != NotARegister)
result = (*registers)[op1(ret)];
if (op1(ret).first != NotARegister)
result = (*registers)[op1(ret).first];
Linkage* linkage = mLinkage;
if (!linkage)
{
@ -574,57 +549,57 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
mLinkage = linkage->mNext;
mActivation = linkage->mActivation;
registers = &mActivation->mRegisters;
(*registers)[linkage->mResult] = result;
(*registers)[linkage->mResult.first] = result;
mPC = linkage->mReturnPC;
}
continue;
case MOVE:
{
Move* mov = static_cast<Move*>(instruction);
(*registers)[dst(mov)] = (*registers)[src1(mov)];
(*registers)[dst(mov).first] = (*registers)[src1(mov).first];
}
break;
case LOAD_NAME:
{
LoadName* ln = static_cast<LoadName*>(instruction);
(*registers)[dst(ln)] = mGlobal->getVariable(*src1(ln));
(*registers)[dst(ln).first] = mGlobal->getVariable(*src1(ln));
}
break;
case SAVE_NAME:
{
SaveName* sn = static_cast<SaveName*>(instruction);
mGlobal->setVariable(*dst(sn), (*registers)[src1(sn)]);
mGlobal->setVariable(*dst(sn), (*registers)[src1(sn).first]);
}
break;
case NEW_OBJECT:
{
NewObject* no = static_cast<NewObject*>(instruction);
(*registers)[dst(no)] = JSValue(new JSObject());
(*registers)[dst(no).first] = JSValue(new JSObject());
}
break;
case NEW_ARRAY:
{
NewArray* na = static_cast<NewArray*>(instruction);
(*registers)[dst(na)] = JSValue(new JSArray());
(*registers)[dst(na).first] = JSValue(new JSArray());
}
break;
case GET_PROP:
{
GetProp* gp = static_cast<GetProp*>(instruction);
JSValue& value = (*registers)[src1(gp)];
JSValue& value = (*registers)[src1(gp).first];
if (value.tag == JSValue::object_tag) {
JSObject* object = value.object;
(*registers)[dst(gp)] = object->getProperty(*src2(gp));
(*registers)[dst(gp).first] = object->getProperty(*src2(gp));
}
}
break;
case SET_PROP:
{
SetProp* sp = static_cast<SetProp*>(instruction);
JSValue& value = (*registers)[dst(sp)];
JSValue& value = (*registers)[dst(sp).first];
if (value.tag == JSValue::object_tag) {
JSObject* object = value.object;
object->setProperty(*src1(sp), (*registers)[src2(sp)]);
object->setProperty(*src1(sp), (*registers)[src2(sp).first]);
}
}
break;
@ -647,20 +622,20 @@ using JSString throughout.
case GET_ELEMENT:
{
GetElement* ge = static_cast<GetElement*>(instruction);
JSValue& value = (*registers)[src1(ge)];
JSValue& value = (*registers)[src1(ge).first];
if (value.tag == JSValue::array_tag) {
JSArray* array = value.array;
(*registers)[dst(ge)] = (*array)[(*registers)[src2(ge)]];
(*registers)[dst(ge).first] = (*array)[(*registers)[src2(ge).first]];
}
}
break;
case SET_ELEMENT:
{
SetElement* se = static_cast<SetElement*>(instruction);
JSValue& value = (*registers)[dst(se)];
JSValue& value = (*registers)[dst(se).first];
if (value.tag == JSValue::array_tag) {
JSArray* array = value.array;
(*array)[(*registers)[src1(se)]] = (*registers)[src2(se)];
(*array)[(*registers)[src1(se).first]] = (*registers)[src2(se).first];
}
}
break;
@ -668,19 +643,19 @@ using JSString throughout.
case LOAD_IMMEDIATE:
{
LoadImmediate* li = static_cast<LoadImmediate*>(instruction);
(*registers)[dst(li)] = JSValue(src1(li));
(*registers)[dst(li).first] = JSValue(src1(li));
}
break;
case LOAD_STRING:
{
LoadString* ls = static_cast<LoadString*>(instruction);
(*registers)[dst(ls)] = JSValue(src1(ls));
(*registers)[dst(ls).first] = JSValue(src1(ls));
}
break;
case LOAD_VALUE:
case LOAD_BOOLEAN:
{
LoadValue* lv = static_cast<LoadValue*>(instruction);
(*registers)[dst(lv)] = src1(lv);
LoadBoolean* lb = static_cast<LoadBoolean*>(instruction);
(*registers)[dst(lb).first] = JSValue(src1(lb));
}
break;
case BRANCH:
@ -695,8 +670,8 @@ using JSString throughout.
{
GenericBranch* bc =
static_cast<GenericBranch*>(instruction);
ASSERT((*registers)[src1(bc)].isBoolean());
if ((*registers)[src1(bc)].boolean) {
ASSERT((*registers)[src1(bc).first].isBoolean());
if ((*registers)[src1(bc).first].boolean) {
mPC = mActivation->mICode->its_iCode->begin() + ofs(bc);
continue;
}
@ -706,8 +681,8 @@ using JSString throughout.
{
GenericBranch* bc =
static_cast<GenericBranch*>(instruction);
ASSERT((*registers)[src1(bc)].isBoolean());
if (!(*registers)[src1(bc)].boolean) {
ASSERT((*registers)[src1(bc).first].isBoolean());
if (!(*registers)[src1(bc).first].boolean) {
mPC = mActivation->mICode->its_iCode->begin() + ofs(bc);
continue;
}
@ -730,9 +705,9 @@ using JSString throughout.
case STRICT_EQ:
{
Arithmetic* mul = static_cast<Arithmetic*>(instruction);
JSValue& dest = (*registers)[dst(mul)];
JSValue& r1 = (*registers)[src1(mul)];
JSValue& r2 = (*registers)[src2(mul)];
JSValue& dest = (*registers)[dst(mul).first];
JSValue& r1 = (*registers)[src1(mul).first];
JSValue& r2 = (*registers)[src2(mul).first];
const JSValue ovr = findBinaryOverride(r1, r2, BinaryOperator::mapICodeOp(instruction->op()));
JSFunction *target = ovr.function;
if (target->isNative()) {
@ -756,19 +731,19 @@ using JSString throughout.
case VAR_XCR:
{
VarXcr *vx = static_cast<VarXcr*>(instruction);
JSValue& dest = (*registers)[dst(vx)];
JSValue r = (*registers)[src1(vx)].toNumber();
JSValue& dest = (*registers)[dst(vx).first];
JSValue r = (*registers)[src1(vx).first].toNumber();
dest = r;
r.f64 += val3(vx);
(*registers)[src1(vx)] = r;
(*registers)[src1(vx).first] = r;
}
break;
case PROP_XCR:
{
PropXcr *px = static_cast<PropXcr*>(instruction);
JSValue& dest = (*registers)[dst(px)];
JSValue& base = (*registers)[src1(px)];
JSValue& dest = (*registers)[dst(px).first];
JSValue& base = (*registers)[src1(px).first];
JSObject *object = base.object;
JSValue r = object->getProperty(*src2(px)).toNumber();
dest = r;
@ -780,7 +755,7 @@ using JSString throughout.
case NAME_XCR:
{
NameXcr *nx = static_cast<NameXcr*>(instruction);
JSValue& dest = (*registers)[dst(nx)];
JSValue& dest = (*registers)[dst(nx).first];
JSValue r = mGlobal->getVariable(*src1(nx)).toNumber();
dest = r;
r.f64 += val3(nx);
@ -791,38 +766,38 @@ using JSString throughout.
case TEST:
{
Test* tst = static_cast<Test*>(instruction);
(*registers)[dst(tst)] = (*registers)[src1(tst)].toBoolean();
(*registers)[dst(tst).first] = (*registers)[src1(tst).first].toBoolean();
}
break;
case NEGATE:
{
Negate* neg = static_cast<Negate*>(instruction);
(*registers)[dst(neg)] = JSValue(-(*registers)[src1(neg)].toNumber().f64);
(*registers)[dst(neg).first] = JSValue(-(*registers)[src1(neg).first].toNumber().f64);
}
break;
case POSATE:
{
Posate* pos = static_cast<Posate*>(instruction);
(*registers)[dst(pos)] = (*registers)[src1(pos)].toNumber();
(*registers)[dst(pos).first] = (*registers)[src1(pos).first].toNumber();
}
break;
case BITNOT:
{
Bitnot* bn = static_cast<Bitnot*>(instruction);
(*registers)[dst(bn)] = JSValue(~(*registers)[src1(bn)].toInt32().i32);
(*registers)[dst(bn).first] = JSValue(~(*registers)[src1(bn).first].toInt32().i32);
}
break;
case NOT:
{
Not* nt = static_cast<Not*>(instruction);
ASSERT((*registers)[src1(nt)].isBoolean());
(*registers)[dst(nt)] = JSValue(!(*registers)[src1(nt)].boolean);
ASSERT((*registers)[src1(nt).first].isBoolean());
(*registers)[dst(nt).first] = JSValue(!(*registers)[src1(nt).first].boolean);
}
break;
case THROW:
{
Throw* thrw = static_cast<Throw*>(instruction);
throw new JSException((*registers)[op1(thrw)]);
throw new JSException((*registers)[op1(thrw).first]);
}
case TRYIN:
@ -857,7 +832,7 @@ using JSString throughout.
case WITHIN:
{
Within* within = static_cast<Within*>(instruction);
JSValue& value = (*registers)[op1(within)];
JSValue& value = (*registers)[op1(within).first];
assert(value.tag == JSValue::object_tag);
mGlobal = new JSScope(mGlobal, value.object);
}

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

@ -36,6 +36,8 @@
namespace JavaScript {
namespace VM {
using namespace JSTypes;
Formatter& operator<< (Formatter& f, Instruction& i)
{
@ -44,11 +46,11 @@ namespace VM {
Formatter& operator<< (Formatter& f, RegisterList& rl)
{
Register* e = rl.end();
TypedRegister* e = rl.end();
f << "(";
for (RegisterList::iterator r = rl.begin(); r != e; r++) {
f << "R" << (*r);
f << "R" << r->first;
if ((r + 1) != e)
f << ", ";
}
@ -64,11 +66,11 @@ namespace VM {
f << "(";
RegisterList::const_iterator i = rl.begin(), e = rl.end();
if (i != e) {
Register r = *i++;
f << "R" << r << '=' << registers[r];
TypedRegister r = *i++;
f << "R" << r.first << '=' << registers[r.first];
while (i != e) {
r = *i++;
f << ", R" << r << '=' << registers[r];
f << ", R" << r.first << '=' << registers[r.first];
}
}
f << ")";

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

@ -49,9 +49,7 @@ namespace ICG {
namespace JavaScript {
namespace VM {
using JSTypes::JSValue;
using JSTypes::JSValues;
using JSTypes::JSString;
using namespace JSTypes;
enum ICodeOp {
ADD, /* dest, source1, source2 */
@ -75,10 +73,10 @@ namespace VM {
GET_PROP, /* dest, object, prop name */
INSTANCEOF, /* dest, source1, source2 */
JSR, /* target */
LOAD_BOOLEAN, /* dest, immediate value (boolean) */
LOAD_IMMEDIATE, /* dest, immediate value (double) */
LOAD_NAME, /* dest, name */
LOAD_STRING, /* dest, immediate value (string) */
LOAD_VALUE, /* dest, immediate value (JSValue) */
MOVE, /* dest, source */
MULTIPLY, /* dest, source1, source2 */
NAME_XCR, /* dest, name, value */
@ -113,8 +111,6 @@ namespace VM {
XOR, /* dest, source1, source2 */
};
/********************************************************************/
static char *opcodeNames[] = {
@ -139,10 +135,10 @@ namespace VM {
"GET_PROP ",
"INSTANCEOF ",
"JSR ",
"LOAD_BOOLEAN ",
"LOAD_IMMEDIATE",
"LOAD_NAME ",
"LOAD_STRING ",
"LOAD_VALUE ",
"MOVE ",
"MULTIPLY ",
"NAME_XCR ",
@ -233,10 +229,12 @@ namespace VM {
/********************************************************************/
typedef uint32 Register;
typedef std::vector<Register> RegisterList;
typedef std::pair<Register, const JSType*> TypedRegister;
typedef std::vector<TypedRegister> RegisterList;
typedef std::vector<Instruction *> InstructionStream;
typedef InstructionStream::iterator InstructionIterator;
typedef std::map<String, Register, std::less<String> > VariableMap;
typedef std::map<String, TypedRegister, std::less<String> > VariableMap;
/**
* Helper to print Call operands.
@ -343,60 +341,59 @@ namespace VM {
/* Instruction groups */
class Arithmetic : public Instruction_3<Register, Register, Register> {
class Arithmetic : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
Arithmetic (ICodeOp aOpcode, Register aDest, Register aSrc1,
Register aSrc2) :
Instruction_3<Register, Register, Register>(aOpcode, aDest, aSrc1,
aSrc2) {}
Arithmetic (ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc1,
TypedRegister aSrc2) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>(aOpcode, aDest, aSrc1, aSrc2) {}
virtual Formatter& print(Formatter& f)
{
f << opcodeNames[mOpcode] << "\tR" << mOp1 << ", R" << mOp2 << ", R" << mOp3;
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first << ", R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class Unary : public Instruction_2<Register, Register> {
class Unary : public Instruction_2<TypedRegister, TypedRegister> {
public:
Unary(ICodeOp aOpcode, Register aDest, Register aSrc) :
Instruction_2<Register, Register>(aOpcode, aDest, aSrc) {}
Unary(ICodeOp aOpcode, TypedRegister aDest, TypedRegister aSrc) :
Instruction_2<TypedRegister, TypedRegister>(aOpcode, aDest, aSrc) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tR" << mOp1 << ", R" << mOp2;
f << opcodeNames[mOpcode] << "\tR" << mOp1.first << ", R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class GenericBranch : public Instruction_2<Label*, Register> {
class GenericBranch : public Instruction_2<Label*, TypedRegister> {
public:
GenericBranch (ICodeOp aOpcode, Label* aLabel,
Register aR = NotARegister) :
Instruction_2<Label*, Register>(aOpcode, aLabel, aR) {}
TypedRegister aR = TypedRegister(NotARegister, &Any_Type) ) :
Instruction_2<Label*, TypedRegister>(aOpcode, aLabel, aR) {}
virtual Formatter& print (Formatter& f) {
f << opcodeNames[mOpcode] << "\tOffset " << mOp1->mOffset;
if (mOp2 == NotARegister) {
if (mOp2.first == NotARegister) {
f << ", R~";
} else {
f << ", R" << mOp2;
f << ", R" << mOp2.first;
}
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers)
{
if (mOp2 != NotARegister)
f << "R" << mOp2 << '=' << registers[mOp2];
if (mOp2.first != NotARegister)
f << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
@ -411,7 +408,7 @@ namespace VM {
class Add : public Arithmetic {
public:
/* dest, source1, source2 */
Add (Register aOp1, Register aOp2, Register aOp3) :
Add (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(ADD, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
@ -420,24 +417,24 @@ namespace VM {
class And : public Arithmetic {
public:
/* dest, source1, source2 */
And (Register aOp1, Register aOp2, Register aOp3) :
And (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(AND, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Bitnot : public Instruction_2<Register, Register> {
class Bitnot : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Bitnot (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Bitnot (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(BITNOT, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[BITNOT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[BITNOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -460,7 +457,7 @@ namespace VM {
class BranchFalse : public GenericBranch {
public:
/* target label, condition */
BranchFalse (Label* aOp1, Register aOp2) :
BranchFalse (Label* aOp1, TypedRegister aOp2) :
GenericBranch
(BRANCH_FALSE, aOp1, aOp2) {};
/* print() and printOperands() inherited from GenericBranch */
@ -469,155 +466,155 @@ namespace VM {
class BranchTrue : public GenericBranch {
public:
/* target label, condition */
BranchTrue (Label* aOp1, Register aOp2) :
BranchTrue (Label* aOp1, TypedRegister aOp2) :
GenericBranch
(BRANCH_TRUE, aOp1, aOp2) {};
/* print() and printOperands() inherited from GenericBranch */
};
class Call : public Instruction_3<Register, Register, RegisterList> {
class Call : public Instruction_3<TypedRegister, TypedRegister, RegisterList> {
public:
/* result, target, args */
Call (Register aOp1, Register aOp2, RegisterList aOp3) :
Instruction_3<Register, Register, RegisterList>
Call (TypedRegister aOp1, TypedRegister aOp2, RegisterList aOp3) :
Instruction_3<TypedRegister, TypedRegister, RegisterList>
(CALL, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[CALL] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << mOp3;
f << opcodeNames[CALL] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << ArgList(mOp3, registers);
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << ArgList(mOp3, registers);
return f;
}
};
class CompareEQ : public Instruction_3<Register, Register, Register> {
class CompareEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareEQ (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareEQ (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_EQ, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareGE : public Instruction_3<Register, Register, Register> {
class CompareGE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareGE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareGE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_GE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareGT : public Instruction_3<Register, Register, Register> {
class CompareGT : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareGT (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareGT (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_GT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareIN : public Instruction_3<Register, Register, Register> {
class CompareIN : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareIN (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareIN (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_IN, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareLE : public Instruction_3<Register, Register, Register> {
class CompareLE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareLE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareLE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_LE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareLT : public Instruction_3<Register, Register, Register> {
class CompareLT : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareLT (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareLT (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_LT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class CompareNE : public Instruction_3<Register, Register, Register> {
class CompareNE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
CompareNE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
CompareNE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(COMPARE_NE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class Divide : public Arithmetic {
public:
/* dest, source1, source2 */
Divide (Register aOp1, Register aOp2, Register aOp3) :
Divide (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(DIVIDE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class ElemXcr : public Instruction_4<Register, Register, Register, double> {
class ElemXcr : public Instruction_4<TypedRegister, TypedRegister, TypedRegister, double> {
public:
/* dest, base, index, value */
ElemXcr (Register aOp1, Register aOp2, Register aOp3, double aOp4) :
Instruction_4<Register, Register, Register, double>
ElemXcr (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3, double aOp4) :
Instruction_4<TypedRegister, TypedRegister, TypedRegister, double>
(ELEM_XCR, aOp1, aOp2, aOp3, aOp4) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[ELEM_XCR] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "R" << mOp3 << ", " << mOp4;
f << opcodeNames[ELEM_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first << ", " << mOp4;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class GetElement : public Instruction_3<Register, Register, Register> {
class GetElement : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, base, index */
GetElement (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
GetElement (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(GET_ELEMENT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[GET_ELEMENT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "R" << mOp3;
f << opcodeNames[GET_ELEMENT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class GetProp : public Instruction_3<Register, Register, const StringAtom*> {
class GetProp : public Instruction_3<TypedRegister, TypedRegister, const StringAtom*> {
public:
/* dest, object, prop name */
GetProp (Register aOp1, Register aOp2, const StringAtom* aOp3) :
Instruction_3<Register, Register, const StringAtom*>
GetProp (TypedRegister aOp1, TypedRegister aOp2, const StringAtom* aOp3) :
Instruction_3<TypedRegister, TypedRegister, const StringAtom*>
(GET_PROP, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[GET_PROP] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "'" << *mOp3 << "'";
f << opcodeNames[GET_PROP] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Instanceof : public Instruction_3<Register, Register, Register> {
class Instanceof : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
Instanceof (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
Instanceof (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(INSTANCEOF, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class Jsr : public GenericBranch {
@ -635,82 +632,82 @@ namespace VM {
}
};
class LoadImmediate : public Instruction_2<Register, double> {
class LoadBoolean : public Instruction_2<TypedRegister, bool> {
public:
/* dest, immediate value (boolean) */
LoadBoolean (TypedRegister aOp1, bool aOp2) :
Instruction_2<TypedRegister, bool>
(LOAD_BOOLEAN, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_BOOLEAN] << "\t" << "R" << mOp1.first << ", " << "'" << ((mOp2) ? "true" : "false") << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadImmediate : public Instruction_2<TypedRegister, double> {
public:
/* dest, immediate value (double) */
LoadImmediate (Register aOp1, double aOp2) :
Instruction_2<Register, double>
LoadImmediate (TypedRegister aOp1, double aOp2) :
Instruction_2<TypedRegister, double>
(LOAD_IMMEDIATE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_IMMEDIATE] << "\t" << "R" << mOp1 << ", " << mOp2;
f << opcodeNames[LOAD_IMMEDIATE] << "\t" << "R" << mOp1.first << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadName : public Instruction_2<Register, const StringAtom*> {
class LoadName : public Instruction_2<TypedRegister, const StringAtom*> {
public:
/* dest, name */
LoadName (Register aOp1, const StringAtom* aOp2) :
Instruction_2<Register, const StringAtom*>
LoadName (TypedRegister aOp1, const StringAtom* aOp2) :
Instruction_2<TypedRegister, const StringAtom*>
(LOAD_NAME, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_NAME] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'";
f << opcodeNames[LOAD_NAME] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadString : public Instruction_2<Register, JSString*> {
class LoadString : public Instruction_2<TypedRegister, JSString*> {
public:
/* dest, immediate value (string) */
LoadString (Register aOp1, JSString* aOp2) :
Instruction_2<Register, JSString*>
LoadString (TypedRegister aOp1, JSString* aOp2) :
Instruction_2<TypedRegister, JSString*>
(LOAD_STRING, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_STRING] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'";
f << opcodeNames[LOAD_STRING] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'";
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class LoadValue : public Instruction_2<Register, JSValue> {
public:
/* dest, immediate value (JSValue) */
LoadValue (Register aOp1, JSValue aOp2) :
Instruction_2<Register, JSValue>
(LOAD_VALUE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[LOAD_VALUE] << "\t" << "R" << mOp1 << ", " << mOp2;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
return f;
}
};
class Move : public Instruction_2<Register, Register> {
class Move : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Move (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Move (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(MOVE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[MOVE] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[MOVE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -718,72 +715,72 @@ namespace VM {
class Multiply : public Arithmetic {
public:
/* dest, source1, source2 */
Multiply (Register aOp1, Register aOp2, Register aOp3) :
Multiply (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(MULTIPLY, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class NameXcr : public Instruction_3<Register, const StringAtom*, double> {
class NameXcr : public Instruction_3<TypedRegister, const StringAtom*, double> {
public:
/* dest, name, value */
NameXcr (Register aOp1, const StringAtom* aOp2, double aOp3) :
Instruction_3<Register, const StringAtom*, double>
NameXcr (TypedRegister aOp1, const StringAtom* aOp2, double aOp3) :
Instruction_3<TypedRegister, const StringAtom*, double>
(NAME_XCR, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NAME_XCR] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'" << ", " << mOp3;
f << opcodeNames[NAME_XCR] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class Negate : public Instruction_2<Register, Register> {
class Negate : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Negate (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Negate (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(NEGATE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEGATE] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[NEGATE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class NewArray : public Instruction_1<Register> {
class NewArray : public Instruction_1<TypedRegister> {
public:
/* dest */
NewArray (Register aOp1) :
Instruction_1<Register>
NewArray (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(NEW_ARRAY, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEW_ARRAY] << "\t" << "R" << mOp1;
f << opcodeNames[NEW_ARRAY] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
class NewObject : public Instruction_1<Register> {
class NewObject : public Instruction_1<TypedRegister> {
public:
/* dest */
NewObject (Register aOp1) :
Instruction_1<Register>
NewObject (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(NEW_OBJECT, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEW_OBJECT] << "\t" << "R" << mOp1;
f << opcodeNames[NEW_OBJECT] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -803,18 +800,18 @@ namespace VM {
}
};
class Not : public Instruction_2<Register, Register> {
class Not : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Not (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Not (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(NOT, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NOT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[NOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -822,40 +819,40 @@ namespace VM {
class Or : public Arithmetic {
public:
/* dest, source1, source2 */
Or (Register aOp1, Register aOp2, Register aOp3) :
Or (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(OR, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Posate : public Instruction_2<Register, Register> {
class Posate : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Posate (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Posate (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(POSATE, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[POSATE] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[POSATE] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class PropXcr : public Instruction_4<Register, Register, const StringAtom*, double> {
class PropXcr : public Instruction_4<TypedRegister, TypedRegister, const StringAtom*, double> {
public:
/* dest, source, name, value */
PropXcr (Register aOp1, Register aOp2, const StringAtom* aOp3, double aOp4) :
Instruction_4<Register, Register, const StringAtom*, double>
PropXcr (TypedRegister aOp1, TypedRegister aOp2, const StringAtom* aOp3, double aOp4) :
Instruction_4<TypedRegister, TypedRegister, const StringAtom*, double>
(PROP_XCR, aOp1, aOp2, aOp3, aOp4) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[PROP_XCR] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "'" << *mOp3 << "'" << ", " << mOp4;
f << opcodeNames[PROP_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "'" << *mOp3 << "'" << ", " << mOp4;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
@ -863,24 +860,24 @@ namespace VM {
class Remainder : public Arithmetic {
public:
/* dest, source1, source2 */
Remainder (Register aOp1, Register aOp2, Register aOp3) :
Remainder (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(REMAINDER, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Return : public Instruction_1<Register> {
class Return : public Instruction_1<TypedRegister> {
public:
/* return value */
Return (Register aOp1) :
Instruction_1<Register>
Return (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(RETURN, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[RETURN] << "\t" << "R" << mOp1;
f << opcodeNames[RETURN] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -915,50 +912,50 @@ namespace VM {
}
};
class SaveName : public Instruction_2<const StringAtom*, Register> {
class SaveName : public Instruction_2<const StringAtom*, TypedRegister> {
public:
/* name, source */
SaveName (const StringAtom* aOp1, Register aOp2) :
Instruction_2<const StringAtom*, Register>
SaveName (const StringAtom* aOp1, TypedRegister aOp2) :
Instruction_2<const StringAtom*, TypedRegister>
(SAVE_NAME, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SAVE_NAME] << "\t" << "'" << *mOp1 << "'" << ", " << "R" << mOp2;
f << opcodeNames[SAVE_NAME] << "\t" << "'" << *mOp1 << "'" << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class SetElement : public Instruction_3<Register, Register, Register> {
class SetElement : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* base, index, value */
SetElement (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
SetElement (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(SET_ELEMENT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SET_ELEMENT] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << "R" << mOp3;
f << opcodeNames[SET_ELEMENT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class SetProp : public Instruction_3<Register, const StringAtom*, Register> {
class SetProp : public Instruction_3<TypedRegister, const StringAtom*, TypedRegister> {
public:
/* object, name, source */
SetProp (Register aOp1, const StringAtom* aOp2, Register aOp3) :
Instruction_3<Register, const StringAtom*, Register>
SetProp (TypedRegister aOp1, const StringAtom* aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, const StringAtom*, TypedRegister>
(SET_PROP, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SET_PROP] << "\t" << "R" << mOp1 << ", " << "'" << *mOp2 << "'" << ", " << "R" << mOp3;
f << opcodeNames[SET_PROP] << "\t" << "R" << mOp1.first << ", " << "'" << *mOp2 << "'" << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp3 << '=' << registers[mOp3];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
@ -966,7 +963,7 @@ namespace VM {
class Shiftleft : public Arithmetic {
public:
/* dest, source1, source2 */
Shiftleft (Register aOp1, Register aOp2, Register aOp3) :
Shiftleft (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(SHIFTLEFT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
@ -975,67 +972,67 @@ namespace VM {
class Shiftright : public Arithmetic {
public:
/* dest, source1, source2 */
Shiftright (Register aOp1, Register aOp2, Register aOp3) :
Shiftright (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(SHIFTRIGHT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class StrictEQ : public Instruction_3<Register, Register, Register> {
class StrictEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
StrictEQ (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
StrictEQ (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(STRICT_EQ, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class StrictNE : public Instruction_3<Register, Register, Register> {
class StrictNE : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
StrictNE (Register aOp1, Register aOp2, Register aOp3) :
Instruction_3<Register, Register, Register>
StrictNE (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, TypedRegister, TypedRegister>
(STRICT_NE, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Instruction_3<Register, Register, Register> */
/* print() and printOperands() inherited from Instruction_3<TypedRegister, TypedRegister, TypedRegister> */
};
class Subtract : public Arithmetic {
public:
/* dest, source1, source2 */
Subtract (Register aOp1, Register aOp2, Register aOp3) :
Subtract (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(SUBTRACT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class Test : public Instruction_2<Register, Register> {
class Test : public Instruction_2<TypedRegister, TypedRegister> {
public:
/* dest, source */
Test (Register aOp1, Register aOp2) :
Instruction_2<Register, Register>
Test (TypedRegister aOp1, TypedRegister aOp2) :
Instruction_2<TypedRegister, TypedRegister>
(TEST, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[TEST] << "\t" << "R" << mOp1 << ", " << "R" << mOp2;
f << opcodeNames[TEST] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Throw : public Instruction_1<Register> {
class Throw : public Instruction_1<TypedRegister> {
public:
/* exception value */
Throw (Register aOp1) :
Instruction_1<Register>
Throw (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(THROW, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[THROW] << "\t" << "R" << mOp1;
f << opcodeNames[THROW] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -1073,40 +1070,40 @@ namespace VM {
class Ushiftright : public Arithmetic {
public:
/* dest, source1, source2 */
Ushiftright (Register aOp1, Register aOp2, Register aOp3) :
Ushiftright (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(USHIFTRIGHT, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
class VarXcr : public Instruction_3<Register, Register, double> {
class VarXcr : public Instruction_3<TypedRegister, TypedRegister, double> {
public:
/* dest, source, value */
VarXcr (Register aOp1, Register aOp2, double aOp3) :
Instruction_3<Register, Register, double>
VarXcr (TypedRegister aOp1, TypedRegister aOp2, double aOp3) :
Instruction_3<TypedRegister, TypedRegister, double>
(VAR_XCR, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[VAR_XCR] << "\t" << "R" << mOp1 << ", " << "R" << mOp2 << ", " << mOp3;
f << opcodeNames[VAR_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1] << ", " << "R" << mOp2 << '=' << registers[mOp2];
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Within : public Instruction_1<Register> {
class Within : public Instruction_1<TypedRegister> {
public:
/* within this object */
Within (Register aOp1) :
Instruction_1<Register>
Within (TypedRegister aOp1) :
Instruction_1<TypedRegister>
(WITHIN, aOp1) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[WITHIN] << "\t" << "R" << mOp1;
f << opcodeNames[WITHIN] << "\t" << "R" << mOp1.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1 << '=' << registers[mOp1];
f << "R" << mOp1.first << '=' << registers[mOp1.first];
return f;
}
};
@ -1129,14 +1126,12 @@ namespace VM {
class Xor : public Arithmetic {
public:
/* dest, source1, source2 */
Xor (Register aOp1, Register aOp2, Register aOp3) :
Xor (TypedRegister aOp1, TypedRegister aOp2, TypedRegister aOp3) :
Arithmetic
(XOR, aOp1, aOp2, aOp3) {};
/* print() and printOperands() inherited from Arithmetic */
};
} /* namespace VM */
} /* namespace JavaScript */

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

@ -101,9 +101,10 @@ static JSValue print(const JSValues &argv)
static void genCode(World &world, Context &cx, StmtNode *p)
{
ICodeGenerator icg(&world);
JSScope glob;
ICodeGenerator icg(&world, &glob);
icg.isScript();
Register ret = NotARegister;
TypedRegister ret(NotARegister, &None_Type);
while (p) {
ret = icg.genStmt(p);
p = p->next;
@ -210,86 +211,6 @@ class Tracer : public Context::Listener {
};
static float64 testFactorial(World &world, float64 n)
{
JSScope glob;
Context cx(world, &glob);
// generate code for factorial, and interpret it.
uint32 pos = 0;
ICodeGenerator icg(&world);
// fact(n) {
// var result = 1;
StringAtom &n_name = world.identifiers[widenCString("n")];
StringAtom &result_name = world.identifiers[widenCString("result")];
Register r_n = icg.allocateParameter(n_name);
Register r_result = icg.allocateVariable(result_name);
Arena a;
ExprStmtNode *e = new(a) ExprStmtNode(pos, StmtNode::expression, new(a) BinaryExprNode(pos, ExprNode::assignment,
new(a) IdentifierExprNode(pos, ExprNode::identifier, result_name),
new(a) NumberExprNode(pos, 1.0) ) );
icg.genStmt(e);
// while (n > 1) {
// result = result * n;
// n = n - 1;
// }
{
BinaryExprNode *c = new(a) BinaryExprNode(pos, ExprNode::greaterThan,
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name),
new(a) NumberExprNode(pos, 1.0) ) ;
ExprStmtNode *e1 = new(a) ExprStmtNode(pos, StmtNode::expression, new(a) BinaryExprNode(pos, ExprNode::assignment,
new(a) IdentifierExprNode(pos, ExprNode::identifier, result_name),
new(a) BinaryExprNode(pos, ExprNode::multiply,
new(a) IdentifierExprNode(pos, ExprNode::identifier, result_name),
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name) ) ) );
ExprStmtNode *e2 = new(a) ExprStmtNode(pos, StmtNode::expression, new(a) BinaryExprNode(pos, ExprNode::assignment,
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name),
new(a) BinaryExprNode(pos, ExprNode::subtract,
new(a) IdentifierExprNode(pos, ExprNode::identifier, n_name),
new(a) NumberExprNode(pos, 1.0) ) ) );
e1->next = e2;
BlockStmtNode *b = new(a) BlockStmtNode(pos, StmtNode::block, NULL, e1);
UnaryStmtNode *w = new(a) UnaryStmtNode(pos, StmtNode::While, c, b);
icg.genStmt(w);
}
// return result;
icg.returnStmt(r_result);
ICodeModule *icm = icg.complete();
stdOut << icg;
// preset the global property "fact" to contain the above function
StringAtom& fact = world.identifiers[widenCString("fact")];
glob.defineFunction(fact, icm);
// now a script :
// return fact(n);
ICodeGenerator script(&world);
RegisterList args(1);
args[0] = script.loadImmediate(n);
script.returnStmt(script.call(script.loadName(fact), args));
stdOut << script;
// install a listener so we can trace execution of factorial.
Tracer t;
cx.addListener(&t);
// test the iCode interpreter.
JSValue result = cx.interpret(script.complete(), JSValues());
stdOut << "fact(" << n << ") = " << result.f64 << "\n";
delete icm;
return result.f64;
}
char * tests[] = {
"function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" ,
@ -308,8 +229,8 @@ void testCompile()
Arena a;
Parser p(world, a, testScript, widenCString("testCompile"));
StmtNode *parsedStatements = p.parseProgram();
ICodeGenerator icg(&world);
JSScope glob;
ICodeGenerator icg(&world, &glob);
icg.isScript();
while (parsedStatements) {
icg.genStmt(parsedStatements);
@ -333,7 +254,6 @@ int main(int argc, char **argv)
using namespace JavaScript;
using namespace Shell;
#if 0
assert(testFactorial(world, 5) == 120);
testCompile();
#endif
readEvalPrint(stdin, world);