Some parts of x@<name> working.

This commit is contained in:
rogerl%netscape.com 2000-07-10 23:18:07 +00:00
parent 5cefdedddb
commit 087d2475a7
12 changed files with 146 additions and 116 deletions

View File

@ -10,6 +10,7 @@
BRANCH_FALSE, /* target label, condition */
BRANCH_TRUE, /* target label, condition */
CALL, /* result, target, name, args */
CAST, /* dest, rvalue, toType */
COMPARE_EQ, /* dest, source1, source2 */
COMPARE_GE, /* dest, source1, source2 */
COMPARE_GT, /* dest, source1, source2 */
@ -158,6 +159,22 @@
}
};
class Cast : public Instruction_3<TypedRegister, TypedRegister, JSType*> {
public:
/* dest, rvalue, toType */
Cast (TypedRegister aOp1, TypedRegister aOp2, JSType* aOp3) :
Instruction_3<TypedRegister, TypedRegister, JSType*>
(CAST, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[CAST] << "\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 CompareEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
@ -550,11 +567,11 @@
}
};
class NewFunction : public Instruction_2<TypedRegister, ICodeModule *> {
class NewFunction : public Instruction_2<TypedRegister, ICodeModule*> {
public:
/* dest, ICodeModule */
NewFunction (TypedRegister aOp1, ICodeModule * aOp2) :
Instruction_2<TypedRegister, ICodeModule *>
NewFunction (TypedRegister aOp1, ICodeModule* aOp2) :
Instruction_2<TypedRegister, ICodeModule*>
(NEW_FUNCTION, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEW_FUNCTION] << "\t" << "R" << mOp1.first << ", " << "ICodeModule";
@ -1035,6 +1052,7 @@
"BRANCH_FALSE ",
"BRANCH_TRUE ",
"CALL ",
"CAST ",
"COMPARE_EQ ",
"COMPARE_GE ",
"COMPARE_GT ",

View File

@ -482,6 +482,14 @@ TypedRegister ICodeGenerator::super()
return dest;
}
TypedRegister ICodeGenerator::cast(TypedRegister arg, JSType *toType)
{
TypedRegister dest(getTempRegister(), toType);
Cast *instr = new Cast(dest, arg, toType);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::branch(Label *label)
{
Branch *instr = new Branch(label);
@ -1216,17 +1224,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
/*
if (!isWithinWith()) {
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);
}
else
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
*/
}
else
if (b->op1->getKind() == ExprNode::dot) {
@ -1259,27 +1256,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
/*
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v.first != NotARegister) {
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
move(v, ret);
}
else {
v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
}
}
else {
TypedRegister v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
}
*/
}
else
if (b->op1->getKind() == ExprNode::dot) {
@ -1463,6 +1440,31 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
break;
case ExprNode::at:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
// for now, just handle simple identifiers on the rhs.
ret = genExpr(b->op1);
if (b->op2->getKind() == ExprNode::identifier) {
TypedRegister t;
uint32 slotIndex;
const StringAtom &name = (static_cast<IdentifierExprNode *>(b->op2))->name;
LValueKind lvk = resolveIdentifier(name, t, slotIndex);
ASSERT(t.second == &Type_Type);
const JSValue &v = mGlobal->getVariable(name);
ASSERT(v.isType());
JSClass *clazz = dynamic_cast<JSClass*>(v.type);
if (clazz)
ret = cast(ret, clazz);
else
ret = cast(ret, t.second);
}
else
NOT_REACHED("Anything more complex than <expr>@<name> is not implemented");
}
break;
default:
{
NOT_REACHED("Unsupported ExprNode kind");

View File

@ -260,6 +260,8 @@ namespace ICG {
TypedRegister newArray();
TypedRegister newFunction(ICodeModule *icm);
TypedRegister newClass(JSClass *clazz);
TypedRegister cast(TypedRegister arg, JSType *toType);
TypedRegister super();
TypedRegister loadName(const StringAtom &name);

View File

@ -481,6 +481,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
assert(mPC != endPC);
Instruction* instruction = *mPC;
switch (instruction->op()) {
case CAST:
{
Cast* c = static_cast<Cast*>(instruction);
JSType *toType = op3(c);
(*registers)[dst(c).first] = (*registers)[src1(c).first];
}
break;
case SUPER:
{
Super* su = static_cast<Super*>(instruction);
@ -710,28 +717,6 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
JSClass* thisClass = src1(nc);
JSInstance* thisInstance = new(thisClass) JSInstance(thisClass);
(*registers)[dst(nc).first] = thisInstance;
/*
JSValues args(1);
args[0] = thisInstance;
TypedRegister voidRegister(NotARegister, &None_Type);
InstructionIterator nextPC = ++mPC;
do {
// call the constructor(s), if any.
ICodeModule* init = thisClass->getInitializer();
if (init) {
mLinkage = new Linkage(mLinkage, nextPC,
mActivation, mGlobal, voidRegister);
mActivation = new Activation(init, args);
registers = &mActivation->mRegisters;
nextPC = init->its_iCode->begin();
endPC = init->its_iCode->end();
}
thisClass = thisClass->getSuperClass();
} while (thisClass);
mPC = nextPC;
continue;
*/
}
break;
case NEW_FUNCTION:

View File

@ -341,7 +341,7 @@ class Tracer : public Context::Listener {
char * tests[] = {
"function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" ,
"a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" ,
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s()); print(A.b); return;"
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s(), \" should be 3\"); print(A.b, \" should be 4\"); return;"
};
static void testCompile()

View File

@ -136,7 +136,7 @@ $ops{"NEW_FUNCTION"} =
{
super => "Instruction_2",
rem => "dest, ICodeModule",
params => [ ("TypedRegister", "ICodeModule *") ]
params => [ ("TypedRegister", "ICodeModule*") ]
};
$ops{"NEW_ARRAY"} =
{
@ -342,6 +342,12 @@ $ops{"WITHOUT"} =
super => "Instruction",
rem => "without this object",
};
$ops{"CAST"} =
{
super => "Instruction_3",
rem => "dest, rvalue, toType",
params => [ ("TypedRegister", "TypedRegister", "JSType*") ]
};
#
# nasty perl code, you probably don't need to muck around below this line
@ -539,6 +545,8 @@ sub get_print_body {
push (@oplist, "\"Offset \" << ((mOp$op) ? mOp$op->mOffset : NotAnOffset)")
} elsif ($type =~ /String/) {
push (@oplist, "\"'\" << *mOp$op << \"'\"");
} elsif ($type =~ /JSType\*/) {
push (@oplist, "\"'\" << *mOp$op << \"'\"");
} elsif ($type =~ /bool/) {
push (@oplist, "\"'\" << ((mOp$op) ? \"true\" : \"false\") << \"'\"");
} elsif ($type =~ /ICodeModule/) {

View File

@ -10,6 +10,7 @@
BRANCH_FALSE, /* target label, condition */
BRANCH_TRUE, /* target label, condition */
CALL, /* result, target, name, args */
CAST, /* dest, rvalue, toType */
COMPARE_EQ, /* dest, source1, source2 */
COMPARE_GE, /* dest, source1, source2 */
COMPARE_GT, /* dest, source1, source2 */
@ -158,6 +159,22 @@
}
};
class Cast : public Instruction_3<TypedRegister, TypedRegister, JSType*> {
public:
/* dest, rvalue, toType */
Cast (TypedRegister aOp1, TypedRegister aOp2, JSType* aOp3) :
Instruction_3<TypedRegister, TypedRegister, JSType*>
(CAST, aOp1, aOp2, aOp3) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[CAST] << "\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 CompareEQ : public Instruction_3<TypedRegister, TypedRegister, TypedRegister> {
public:
/* dest, source1, source2 */
@ -550,11 +567,11 @@
}
};
class NewFunction : public Instruction_2<TypedRegister, ICodeModule *> {
class NewFunction : public Instruction_2<TypedRegister, ICodeModule*> {
public:
/* dest, ICodeModule */
NewFunction (TypedRegister aOp1, ICodeModule * aOp2) :
Instruction_2<TypedRegister, ICodeModule *>
NewFunction (TypedRegister aOp1, ICodeModule* aOp2) :
Instruction_2<TypedRegister, ICodeModule*>
(NEW_FUNCTION, aOp1, aOp2) {};
virtual Formatter& print(Formatter& f) {
f << opcodeNames[NEW_FUNCTION] << "\t" << "R" << mOp1.first << ", " << "ICodeModule";
@ -1035,6 +1052,7 @@
"BRANCH_FALSE ",
"BRANCH_TRUE ",
"CALL ",
"CAST ",
"COMPARE_EQ ",
"COMPARE_GE ",
"COMPARE_GT ",

View File

@ -482,6 +482,14 @@ TypedRegister ICodeGenerator::super()
return dest;
}
TypedRegister ICodeGenerator::cast(TypedRegister arg, JSType *toType)
{
TypedRegister dest(getTempRegister(), toType);
Cast *instr = new Cast(dest, arg, toType);
iCode->push_back(instr);
return dest;
}
void ICodeGenerator::branch(Label *label)
{
Branch *instr = new Branch(label);
@ -1216,17 +1224,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
/*
if (!isWithinWith()) {
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);
}
else
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
*/
}
else
if (b->op1->getKind() == ExprNode::dot) {
@ -1259,27 +1256,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2);
if (b->op1->getKind() == ExprNode::identifier) {
ret = handleIdentifier(static_cast<IdentifierExprNode *>(b->op1), p->getKind(), xcrementOp, ret, NULL);
/*
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
if (v.first != NotARegister) {
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
move(v, ret);
}
else {
v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
}
}
else {
TypedRegister v = loadName((static_cast<IdentifierExprNode *>(b->op1))->name);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
saveName((static_cast<IdentifierExprNode *>(b->op1))->name, ret);
}
*/
}
else
if (b->op1->getKind() == ExprNode::dot) {
@ -1463,6 +1440,31 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
}
break;
case ExprNode::at:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
// for now, just handle simple identifiers on the rhs.
ret = genExpr(b->op1);
if (b->op2->getKind() == ExprNode::identifier) {
TypedRegister t;
uint32 slotIndex;
const StringAtom &name = (static_cast<IdentifierExprNode *>(b->op2))->name;
LValueKind lvk = resolveIdentifier(name, t, slotIndex);
ASSERT(t.second == &Type_Type);
const JSValue &v = mGlobal->getVariable(name);
ASSERT(v.isType());
JSClass *clazz = dynamic_cast<JSClass*>(v.type);
if (clazz)
ret = cast(ret, clazz);
else
ret = cast(ret, t.second);
}
else
NOT_REACHED("Anything more complex than <expr>@<name> is not implemented");
}
break;
default:
{
NOT_REACHED("Unsupported ExprNode kind");

View File

@ -260,6 +260,8 @@ namespace ICG {
TypedRegister newArray();
TypedRegister newFunction(ICodeModule *icm);
TypedRegister newClass(JSClass *clazz);
TypedRegister cast(TypedRegister arg, JSType *toType);
TypedRegister super();
TypedRegister loadName(const StringAtom &name);

View File

@ -481,6 +481,13 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
assert(mPC != endPC);
Instruction* instruction = *mPC;
switch (instruction->op()) {
case CAST:
{
Cast* c = static_cast<Cast*>(instruction);
JSType *toType = op3(c);
(*registers)[dst(c).first] = (*registers)[src1(c).first];
}
break;
case SUPER:
{
Super* su = static_cast<Super*>(instruction);
@ -710,28 +717,6 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
JSClass* thisClass = src1(nc);
JSInstance* thisInstance = new(thisClass) JSInstance(thisClass);
(*registers)[dst(nc).first] = thisInstance;
/*
JSValues args(1);
args[0] = thisInstance;
TypedRegister voidRegister(NotARegister, &None_Type);
InstructionIterator nextPC = ++mPC;
do {
// call the constructor(s), if any.
ICodeModule* init = thisClass->getInitializer();
if (init) {
mLinkage = new Linkage(mLinkage, nextPC,
mActivation, mGlobal, voidRegister);
mActivation = new Activation(init, args);
registers = &mActivation->mRegisters;
nextPC = init->its_iCode->begin();
endPC = init->its_iCode->end();
}
thisClass = thisClass->getSuperClass();
} while (thisClass);
mPC = nextPC;
continue;
*/
}
break;
case NEW_FUNCTION:

View File

@ -341,7 +341,7 @@ class Tracer : public Context::Listener {
char * tests[] = {
"function fact(n) { if (n > 1) return n * fact(n-1); else return 1; } print(fact(6), \" should be 720\"); return;" ,
"a = { f1: 1, f2: 2}; print(a.f2++, \" should be 2\"); print(a.f2 <<= 1, \" should be 6\"); return;" ,
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s()); print(A.b); return;"
"class A { static var b = 3; static function s() { return b++; } } var a:A = new A; print(a.s(), \" should be 3\"); print(A.b, \" should be 4\"); return;"
};
static void testCompile()

View File

@ -136,7 +136,7 @@ $ops{"NEW_FUNCTION"} =
{
super => "Instruction_2",
rem => "dest, ICodeModule",
params => [ ("TypedRegister", "ICodeModule *") ]
params => [ ("TypedRegister", "ICodeModule*") ]
};
$ops{"NEW_ARRAY"} =
{
@ -342,6 +342,12 @@ $ops{"WITHOUT"} =
super => "Instruction",
rem => "without this object",
};
$ops{"CAST"} =
{
super => "Instruction_3",
rem => "dest, rvalue, toType",
params => [ ("TypedRegister", "TypedRegister", "JSType*") ]
};
#
# nasty perl code, you probably don't need to muck around below this line
@ -539,6 +545,8 @@ sub get_print_body {
push (@oplist, "\"Offset \" << ((mOp$op) ? mOp$op->mOffset : NotAnOffset)")
} elsif ($type =~ /String/) {
push (@oplist, "\"'\" << *mOp$op << \"'\"");
} elsif ($type =~ /JSType\*/) {
push (@oplist, "\"'\" << *mOp$op << \"'\"");
} elsif ($type =~ /bool/) {
push (@oplist, "\"'\" << ((mOp$op) ? \"true\" : \"false\") << \"'\"");
} elsif ($type =~ /ICodeModule/) {