Adding slot handling to code gen.

This commit is contained in:
rogerl%netscape.com 2000-06-23 23:43:24 +00:00
parent 841b79b5eb
commit e939fbddc4
12 changed files with 398 additions and 44 deletions

View File

@ -46,6 +46,7 @@ namespace ICG {
using namespace VM;
using namespace JSTypes;
using namespace JSClasses;
uint32 ICodeModule::sMaxID = 0;
@ -80,7 +81,7 @@ ICodeGenerator::ICodeGenerator(World *world, JSScope *global)
iCodeOwner = true;
}
const JSType *ICodeGenerator::findType(const StringAtom& typeName)
JSType *ICodeGenerator::findType(const StringAtom& typeName)
{
const JSValue& type = mGlobal->getVariable(typeName);
if (type.isType())
@ -293,6 +294,39 @@ TypedRegister ICodeGenerator::propertyDec(TypedRegister base, const StringAtom &
TypedRegister ICodeGenerator::getSlot(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
GetSlot *instr = new GetSlot(dest, base, slot);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::setSlot(TypedRegister base, uint32 slot,
TypedRegister value)
{
SetSlot *instr = new SetSlot(base, slot, value);
iCode->push_back(instr);
}
TypedRegister ICodeGenerator::slotInc(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
SlotXcr *instr = new SlotXcr(dest, base, slot, 1.0);
iCode->push_back(instr);
return dest;
}
TypedRegister ICodeGenerator::slotDec(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
SlotXcr *instr = new SlotXcr(dest, base, slot, -1.0);
iCode->push_back(instr);
return dest;
}
TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index)
{
TypedRegister dest(getRegister(), &Any_Type);
@ -545,6 +579,19 @@ static bool generatedBoolean(ExprNode *p)
return false;
}
bool isSlotName(JSType *t, const StringAtom &name, uint32 &slotIndex)
{
if (t->isClassType()) {
JSClass *c = static_cast<JSClass *>(t);
if (c->hasSlot(name)) {
JSSlot &s = c->getSlot(name);
slotIndex = s.mIndex;
return true;
}
}
return false;
}
/*
if trueBranch OR falseBranch are not null, the sub-expression should generate
a conditional branch to the appropriate target. If either branch is NULL, it
@ -628,7 +675,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister base = genExpr(b->op1);
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
}
@ -636,8 +683,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::dot :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
TypedRegister base = genExpr(b->op1);
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
ret = getSlot(base, slotIndex);
else
ret = getProperty(base, name);
}
break;
case ExprNode::This :
@ -670,9 +722,18 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
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);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex)) {
ret = slotInc(base, slotIndex);
ret = op(ADD, ret, loadImmediate(1.0));
setSlot(base, slotIndex, ret);
}
else {
ret = getProperty(base, name);
ret = op(ADD, ret, loadImmediate(1.0));
setProperty(base, name, ret);
}
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -711,7 +772,12 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
ret = propertyInc(base, static_cast<IdentifierExprNode *>(b->op2)->name);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
ret = slotInc(base, slotIndex);
else
ret = propertyInc(base, name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -742,9 +808,18 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
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);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex)) {
ret = getSlot(base, slotIndex);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setSlot(base, slotIndex, ret);
}
else {
ret = getProperty(base, name);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setProperty(base, name, ret);
}
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -783,7 +858,12 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
ret = propertyDec(base, static_cast<IdentifierExprNode *>(b->op2)->name);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
slotDec(base, slotIndex);
else
ret = propertyDec(base, name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -853,8 +933,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
TypedRegister base = genExpr(lb->op1);
setProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name, ret);
TypedRegister base = genExpr(lb->op1);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
setSlot(base, slotIndex, ret);
else
setProperty(base, name, ret);
}
else
if (b->op1->getKind() == ExprNode::index) {
@ -904,9 +989,18 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
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);
const StringAtom &name = static_cast<IdentifierExprNode *>(lb->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex)) {
TypedRegister v = getSlot(base, slotIndex);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setSlot(base, slotIndex, ret);
}
else {
TypedRegister v = getProperty(base, name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setProperty(base, name, ret);
}
}
else
if (b->op1->getKind() == ExprNode::index) {
@ -1232,7 +1326,6 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::Class:
{
// FIXME: need a semantic check to make sure a class isn't being redefined(?)
using JSClasses::JSClass;
ClassStmtNode *classStmt = static_cast<ClassStmtNode *>(p);
ASSERT(classStmt->name->getKind() == ExprNode::identifier);
IdentifierExprNode* nameExpr = static_cast<IdentifierExprNode*>(classStmt->name);
@ -1490,11 +1583,14 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
genStmt(f->stmt);
setLabel(e->continueLabel);
if (f->expr3)
if (f->expr3) {
(*mInstructionMap)[iCode->size()] = f->expr3->pos;
genExpr(f->expr3);
}
setLabel(forTestLabel);
if (f->expr2) {
(*mInstructionMap)[iCode->size()] = f->expr2->pos;
TypedRegister c = genExpr(f->expr2, false, forBlockTop, NULL);
if (!generatedBoolean(f->expr2))
branchTrue(forBlockTop, test(c));

View File

@ -168,7 +168,7 @@ namespace ICG {
ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind);
TypedRegister grabRegister(const StringAtom& name, const JSType *type)
TypedRegister grabRegister(const StringAtom& name, JSType *type)
{
TypedRegister result(getRegister(), type);
(*variableList)[name] = result;
@ -176,7 +176,7 @@ namespace ICG {
return result;
}
const JSType *findType(const StringAtom& typeName);
JSType *findType(const StringAtom& typeName);
public:
ICodeGenerator(World *world, JSScope *global);
@ -254,6 +254,11 @@ namespace ICG {
TypedRegister elementInc(TypedRegister base, TypedRegister index);
TypedRegister elementDec(TypedRegister base, TypedRegister index);
TypedRegister getSlot(TypedRegister base, uint32 slot);
void setSlot(TypedRegister base, uint32 slot, TypedRegister value);
TypedRegister slotInc(TypedRegister base, uint32 slot);
TypedRegister slotDec(TypedRegister base, uint32 slot);
TypedRegister varInc(TypedRegister var);
TypedRegister varDec(TypedRegister var);

View File

@ -88,6 +88,8 @@ namespace JSClasses {
JSClass* getSuperClass() { return mSuperClass; }
JSScope* getScope() { return mScope; }
virtual bool isClassType() const { return true; }
JSSlot& addSlot(const String& name, const JSType* type)
{
JSSlot& slot = mSlots[name];

View File

@ -450,6 +450,8 @@ namespace JSTypes {
const String& getName() const { return mName; }
virtual bool isClassType() const { return false; }
int32 distance(const JSType *other) const;
};

View File

@ -150,6 +150,24 @@ $ops{"SET_PROP"} =
rem => "object, name, source",
params => [ ("TypedRegister", "const StringAtom*", "TypedRegister") ]
};
$ops{"GET_SLOT"} =
{
super => "Instruction_3",
rem => "dest, object, slot number",
params => [ ("TypedRegister", "TypedRegister", "uint32") ]
};
$ops{"SET_SLOT"} =
{
super => "Instruction_3",
rem => "object, slot number, source",
params => [ ("TypedRegister", "uint32", "TypedRegister") ]
};
$ops{"SLOT_XCR"} =
{
super => "Instruction_4",
rem => "dest, source, slot number, value",
params => [ ("TypedRegister", "TypedRegister", "uint32", "double") ]
};
$ops{"PROP_XCR"} =
{
super => "Instruction_4",

View File

@ -71,6 +71,7 @@ namespace VM {
ELEM_XCR, /* dest, base, index, value */
GET_ELEMENT, /* dest, base, index */
GET_PROP, /* dest, object, prop name */
GET_SLOT, /* dest, object, slot number */
INSTANCEOF, /* dest, source1, source2 */
JSR, /* target */
LOAD_BOOLEAN, /* dest, immediate value (boolean) */
@ -97,8 +98,10 @@ namespace VM {
SAVE_NAME, /* name, source */
SET_ELEMENT, /* base, index, value */
SET_PROP, /* object, name, source */
SET_SLOT, /* object, slot number, source */
SHIFTLEFT, /* dest, source1, source2 */
SHIFTRIGHT, /* dest, source1, source2 */
SLOT_XCR, /* dest, source, slot number, value */
STRICT_EQ, /* dest, source1, source2 */
STRICT_NE, /* dest, source1, source2 */
SUBTRACT, /* dest, source1, source2 */
@ -135,6 +138,7 @@ namespace VM {
"ELEM_XCR ",
"GET_ELEMENT ",
"GET_PROP ",
"GET_SLOT ",
"INSTANCEOF ",
"JSR ",
"LOAD_BOOLEAN ",
@ -161,8 +165,10 @@ namespace VM {
"SAVE_NAME ",
"SET_ELEMENT ",
"SET_PROP ",
"SET_SLOT ",
"SHIFTLEFT ",
"SHIFTRIGHT ",
"SLOT_XCR ",
"STRICT_EQ ",
"STRICT_NE ",
"SUBTRACT ",
@ -216,7 +222,7 @@ namespace VM {
/********************************************************************/
typedef uint32 Register;
typedef std::pair<Register, const JSType*> TypedRegister;
typedef std::pair<Register, JSType*> TypedRegister;
typedef std::vector<TypedRegister> RegisterList;
typedef std::vector<Instruction *> InstructionStream;
typedef InstructionStream::iterator InstructionIterator;
@ -610,6 +616,22 @@ namespace VM {
}
};
class GetSlot : public Instruction_3<TypedRegister, TypedRegister, uint32> {
public:
/* dest, object, slot number */
GetSlot (TypedRegister aOp1, TypedRegister aOp2, uint32 aOp3) :
Instruction_3<TypedRegister, TypedRegister, uint32>
(GET_SLOT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[GET_SLOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Instanceof : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
@ -994,6 +1016,22 @@ namespace VM {
}
};
class SetSlot : public Instruction_3<TypedRegister, uint32, TypedRegister> {
public:
/* object, slot number, source */
SetSlot (TypedRegister aOp1, uint32 aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, uint32, TypedRegister>
(SET_SLOT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SET_SLOT] << "\t" << "R" << mOp1.first << ", " << mOp2 << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class Shiftleft : public Arithmetic {
public:
/* dest, source1, source2 */
@ -1012,6 +1050,22 @@ namespace VM {
/* print() and printOperands() inherited from Arithmetic */
};
class SlotXcr : public Instruction_4<TypedRegister, TypedRegister, uint32, double> {
public:
/* dest, source, slot number, value */
SlotXcr (TypedRegister aOp1, TypedRegister aOp2, uint32 aOp3, double aOp4) :
Instruction_4<TypedRegister, TypedRegister, uint32, double>
(SLOT_XCR, aOp1, aOp2, aOp3, aOp4) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SLOT_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3 << ", " << mOp4;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class StrictEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */

View File

@ -46,6 +46,7 @@ namespace ICG {
using namespace VM;
using namespace JSTypes;
using namespace JSClasses;
uint32 ICodeModule::sMaxID = 0;
@ -80,7 +81,7 @@ ICodeGenerator::ICodeGenerator(World *world, JSScope *global)
iCodeOwner = true;
}
const JSType *ICodeGenerator::findType(const StringAtom& typeName)
JSType *ICodeGenerator::findType(const StringAtom& typeName)
{
const JSValue& type = mGlobal->getVariable(typeName);
if (type.isType())
@ -293,6 +294,39 @@ TypedRegister ICodeGenerator::propertyDec(TypedRegister base, const StringAtom &
TypedRegister ICodeGenerator::getSlot(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
GetSlot *instr = new GetSlot(dest, base, slot);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::setSlot(TypedRegister base, uint32 slot,
TypedRegister value)
{
SetSlot *instr = new SetSlot(base, slot, value);
iCode->push_back(instr);
}
TypedRegister ICodeGenerator::slotInc(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
SlotXcr *instr = new SlotXcr(dest, base, slot, 1.0);
iCode->push_back(instr);
return dest;
}
TypedRegister ICodeGenerator::slotDec(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
SlotXcr *instr = new SlotXcr(dest, base, slot, -1.0);
iCode->push_back(instr);
return dest;
}
TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index)
{
TypedRegister dest(getRegister(), &Any_Type);
@ -545,6 +579,19 @@ static bool generatedBoolean(ExprNode *p)
return false;
}
bool isSlotName(JSType *t, const StringAtom &name, uint32 &slotIndex)
{
if (t->isClassType()) {
JSClass *c = static_cast<JSClass *>(t);
if (c->hasSlot(name)) {
JSSlot &s = c->getSlot(name);
slotIndex = s.mIndex;
return true;
}
}
return false;
}
/*
if trueBranch OR falseBranch are not null, the sub-expression should generate
a conditional branch to the appropriate target. If either branch is NULL, it
@ -628,7 +675,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister base = genExpr(b->op1);
TypedRegister base = genExpr(b->op1);
TypedRegister index = genExpr(b->op2);
ret = getElement(base, index);
}
@ -636,8 +683,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::dot :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
TypedRegister base = genExpr(b->op1);
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
TypedRegister base = genExpr(b->op1);
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
ret = getSlot(base, slotIndex);
else
ret = getProperty(base, name);
}
break;
case ExprNode::This :
@ -670,9 +722,18 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
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);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex)) {
ret = slotInc(base, slotIndex);
ret = op(ADD, ret, loadImmediate(1.0));
setSlot(base, slotIndex, ret);
}
else {
ret = getProperty(base, name);
ret = op(ADD, ret, loadImmediate(1.0));
setProperty(base, name, ret);
}
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -711,7 +772,12 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
ret = propertyInc(base, static_cast<IdentifierExprNode *>(b->op2)->name);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
ret = slotInc(base, slotIndex);
else
ret = propertyInc(base, name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -742,9 +808,18 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
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);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex)) {
ret = getSlot(base, slotIndex);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setSlot(base, slotIndex, ret);
}
else {
ret = getProperty(base, name);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setProperty(base, name, ret);
}
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -783,7 +858,12 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
TypedRegister base = genExpr(b->op1);
ret = propertyDec(base, static_cast<IdentifierExprNode *>(b->op2)->name);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
slotDec(base, slotIndex);
else
ret = propertyDec(base, name);
}
else
if (u->op->getKind() == ExprNode::identifier) {
@ -853,8 +933,13 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
TypedRegister base = genExpr(lb->op1);
setProperty(base, static_cast<IdentifierExprNode *>(lb->op2)->name, ret);
TypedRegister base = genExpr(lb->op1);
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex))
setSlot(base, slotIndex, ret);
else
setProperty(base, name, ret);
}
else
if (b->op1->getKind() == ExprNode::index) {
@ -904,9 +989,18 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
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);
const StringAtom &name = static_cast<IdentifierExprNode *>(lb->op2)->name;
uint32 slotIndex;
if (isSlotName(base.second, name, slotIndex)) {
TypedRegister v = getSlot(base, slotIndex);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setSlot(base, slotIndex, ret);
}
else {
TypedRegister v = getProperty(base, name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setProperty(base, name, ret);
}
}
else
if (b->op1->getKind() == ExprNode::index) {
@ -1232,7 +1326,6 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::Class:
{
// FIXME: need a semantic check to make sure a class isn't being redefined(?)
using JSClasses::JSClass;
ClassStmtNode *classStmt = static_cast<ClassStmtNode *>(p);
ASSERT(classStmt->name->getKind() == ExprNode::identifier);
IdentifierExprNode* nameExpr = static_cast<IdentifierExprNode*>(classStmt->name);
@ -1490,11 +1583,14 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
genStmt(f->stmt);
setLabel(e->continueLabel);
if (f->expr3)
if (f->expr3) {
(*mInstructionMap)[iCode->size()] = f->expr3->pos;
genExpr(f->expr3);
}
setLabel(forTestLabel);
if (f->expr2) {
(*mInstructionMap)[iCode->size()] = f->expr2->pos;
TypedRegister c = genExpr(f->expr2, false, forBlockTop, NULL);
if (!generatedBoolean(f->expr2))
branchTrue(forBlockTop, test(c));

View File

@ -168,7 +168,7 @@ namespace ICG {
ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind);
TypedRegister grabRegister(const StringAtom& name, const JSType *type)
TypedRegister grabRegister(const StringAtom& name, JSType *type)
{
TypedRegister result(getRegister(), type);
(*variableList)[name] = result;
@ -176,7 +176,7 @@ namespace ICG {
return result;
}
const JSType *findType(const StringAtom& typeName);
JSType *findType(const StringAtom& typeName);
public:
ICodeGenerator(World *world, JSScope *global);
@ -254,6 +254,11 @@ namespace ICG {
TypedRegister elementInc(TypedRegister base, TypedRegister index);
TypedRegister elementDec(TypedRegister base, TypedRegister index);
TypedRegister getSlot(TypedRegister base, uint32 slot);
void setSlot(TypedRegister base, uint32 slot, TypedRegister value);
TypedRegister slotInc(TypedRegister base, uint32 slot);
TypedRegister slotDec(TypedRegister base, uint32 slot);
TypedRegister varInc(TypedRegister var);
TypedRegister varDec(TypedRegister var);

View File

@ -88,6 +88,8 @@ namespace JSClasses {
JSClass* getSuperClass() { return mSuperClass; }
JSScope* getScope() { return mScope; }
virtual bool isClassType() const { return true; }
JSSlot& addSlot(const String& name, const JSType* type)
{
JSSlot& slot = mSlots[name];

View File

@ -450,6 +450,8 @@ namespace JSTypes {
const String& getName() const { return mName; }
virtual bool isClassType() const { return false; }
int32 distance(const JSType *other) const;
};

View File

@ -71,6 +71,7 @@ namespace VM {
ELEM_XCR, /* dest, base, index, value */
GET_ELEMENT, /* dest, base, index */
GET_PROP, /* dest, object, prop name */
GET_SLOT, /* dest, object, slot number */
INSTANCEOF, /* dest, source1, source2 */
JSR, /* target */
LOAD_BOOLEAN, /* dest, immediate value (boolean) */
@ -97,8 +98,10 @@ namespace VM {
SAVE_NAME, /* name, source */
SET_ELEMENT, /* base, index, value */
SET_PROP, /* object, name, source */
SET_SLOT, /* object, slot number, source */
SHIFTLEFT, /* dest, source1, source2 */
SHIFTRIGHT, /* dest, source1, source2 */
SLOT_XCR, /* dest, source, slot number, value */
STRICT_EQ, /* dest, source1, source2 */
STRICT_NE, /* dest, source1, source2 */
SUBTRACT, /* dest, source1, source2 */
@ -135,6 +138,7 @@ namespace VM {
"ELEM_XCR ",
"GET_ELEMENT ",
"GET_PROP ",
"GET_SLOT ",
"INSTANCEOF ",
"JSR ",
"LOAD_BOOLEAN ",
@ -161,8 +165,10 @@ namespace VM {
"SAVE_NAME ",
"SET_ELEMENT ",
"SET_PROP ",
"SET_SLOT ",
"SHIFTLEFT ",
"SHIFTRIGHT ",
"SLOT_XCR ",
"STRICT_EQ ",
"STRICT_NE ",
"SUBTRACT ",
@ -216,7 +222,7 @@ namespace VM {
/********************************************************************/
typedef uint32 Register;
typedef std::pair<Register, const JSType*> TypedRegister;
typedef std::pair<Register, JSType*> TypedRegister;
typedef std::vector<TypedRegister> RegisterList;
typedef std::vector<Instruction *> InstructionStream;
typedef InstructionStream::iterator InstructionIterator;
@ -610,6 +616,22 @@ namespace VM {
}
};
class GetSlot : public Instruction_3<TypedRegister, TypedRegister, uint32> {
public:
/* dest, object, slot number */
GetSlot (TypedRegister aOp1, TypedRegister aOp2, uint32 aOp3) :
Instruction_3<TypedRegister, TypedRegister, uint32>
(GET_SLOT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[GET_SLOT] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class Instanceof : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
@ -994,6 +1016,22 @@ namespace VM {
}
};
class SetSlot : public Instruction_3<TypedRegister, uint32, TypedRegister> {
public:
/* object, slot number, source */
SetSlot (TypedRegister aOp1, uint32 aOp2, TypedRegister aOp3) :
Instruction_3<TypedRegister, uint32, TypedRegister>
(SET_SLOT, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SET_SLOT] << "\t" << "R" << mOp1.first << ", " << mOp2 << ", " << "R" << mOp3.first;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp3.first << '=' << registers[mOp3.first];
return f;
}
};
class Shiftleft : public Arithmetic {
public:
/* dest, source1, source2 */
@ -1012,6 +1050,22 @@ namespace VM {
/* print() and printOperands() inherited from Arithmetic */
};
class SlotXcr : public Instruction_4<TypedRegister, TypedRegister, uint32, double> {
public:
/* dest, source, slot number, value */
SlotXcr (TypedRegister aOp1, TypedRegister aOp2, uint32 aOp3, double aOp4) :
Instruction_4<TypedRegister, TypedRegister, uint32, double>
(SLOT_XCR, aOp1, aOp2, aOp3, aOp4) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[SLOT_XCR] << "\t" << "R" << mOp1.first << ", " << "R" << mOp2.first << ", " << mOp3 << ", " << mOp4;
return f;
}
virtual Formatter& printOperands(Formatter& f, const JSValues& registers) {
f << "R" << mOp1.first << '=' << registers[mOp1.first] << ", " << "R" << mOp2.first << '=' << registers[mOp2.first];
return f;
}
};
class StrictEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */

View File

@ -150,6 +150,24 @@ $ops{"SET_PROP"} =
rem => "object, name, source",
params => [ ("TypedRegister", "const StringAtom*", "TypedRegister") ]
};
$ops{"GET_SLOT"} =
{
super => "Instruction_3",
rem => "dest, object, slot number",
params => [ ("TypedRegister", "TypedRegister", "uint32") ]
};
$ops{"SET_SLOT"} =
{
super => "Instruction_3",
rem => "object, slot number, source",
params => [ ("TypedRegister", "uint32", "TypedRegister") ]
};
$ops{"SLOT_XCR"} =
{
super => "Instruction_4",
rem => "dest, source, slot number, value",
params => [ ("TypedRegister", "TypedRegister", "uint32", "double") ]
};
$ops{"PROP_XCR"} =
{
super => "Instruction_4",