Mucking about with operator overlaoding plus initializing global context

- beginning type stuff.
This commit is contained in:
rogerl%netscape.com 2000-06-16 01:36:59 +00:00
parent 670a8310fb
commit ecd0d99e85
12 changed files with 300 additions and 170 deletions

View File

@ -498,12 +498,13 @@ static bool generatedBoolean(ExprNode *p)
}
/*
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
indicates that the label is immediately forthcoming.
*/
Register ICodeGenerator::genExpr(ExprNode *p,
Result ICodeGenerator::genExpr(ExprNode *p,
bool needBoolValueInBranch,
Label *trueBranch,
Label *falseBranch)
@ -533,7 +534,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::parentheses:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch);
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch).reg;
}
break;
case ExprNode::New:
@ -545,11 +546,11 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::call :
{
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
Register fn = genExpr(i->op);
Register fn = genExpr(i->op).reg;
RegisterList args;
ExprPairList *p = i->pairs;
while (p) {
args.push_back(genExpr(p->value));
args.push_back(genExpr(p->value).reg);
p = p->next;
}
ret = call(fn, args);
@ -558,15 +559,15 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = getElement(base, index);
}
break;
case ExprNode::dot :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1);
Register base = genExpr(b->op1).reg;
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
break;
@ -594,7 +595,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
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);
@ -620,8 +621,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = getElement(base, index);
ret = op(ADD, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -633,7 +634,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
ret = propertyInc(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
@ -651,8 +652,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = elementInc(base, index);
}
}
@ -662,7 +663,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
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);
@ -688,8 +689,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = getElement(base, index);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -701,7 +702,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
ret = propertyDec(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
@ -719,8 +720,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = elementInc(base, index);
}
}
@ -730,7 +731,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::complement:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
Register r = genExpr(u->op);
Register r = genExpr(u->op).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r);
}
break;
@ -747,15 +748,15 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOr:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
}
break;
case ExprNode::assignment:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2);
ret = genExpr(b->op2).reg;
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
@ -770,14 +771,14 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1);
Register base = genExpr(lb->op1).reg;
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);
Register index = genExpr(lb->op2);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
setElement(base, index, ret);
}
}
@ -795,7 +796,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOrEquals:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2);
ret = genExpr(b->op2).reg;
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
@ -818,7 +819,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1);
Register base = genExpr(lb->op1).reg;
Register 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);
@ -826,8 +827,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1);
Register index = genExpr(lb->op2);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
Register v = getElement(base, index);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setElement(base, index, ret);
@ -842,8 +843,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::Instanceof:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -860,8 +861,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::greaterThanOrEqual:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r2, r1); // will return reverse case
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -879,8 +880,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::notIdentical:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -906,12 +907,12 @@ Register ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *fBranch = getLabel();
Register r1 = genExpr(b->op1, true, NULL, fBranch);
Register r1 = genExpr(b->op1, true, NULL, fBranch).reg;
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchFalse(fBranch, r1);
}
Register r2 = genExpr(b->op2);
Register r2 = genExpr(b->op2).reg;
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -931,12 +932,12 @@ Register ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *tBranch = getLabel();
Register r1 = genExpr(b->op1, true, tBranch, NULL);
Register r1 = genExpr(b->op1, true, tBranch, NULL).reg;
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchTrue(tBranch, r1);
}
Register r2 = genExpr(b->op2);
Register r2 = genExpr(b->op2).reg;
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -953,13 +954,13 @@ Register ICodeGenerator::genExpr(ExprNode *p,
TernaryExprNode *t = static_cast<TernaryExprNode *>(p);
Label *fBranch = getLabel();
Label *beyondBranch = getLabel();
Register c = genExpr(t->op1, false, NULL, fBranch);
Register c = genExpr(t->op1, false, NULL, fBranch).reg;
if (!generatedBoolean(t->op1))
branchFalse(fBranch, test(c));
Register r1 = genExpr(t->op2);
Register r1 = genExpr(t->op2).reg;
branch(beyondBranch);
setLabel(fBranch);
Register r2 = genExpr(t->op3);
Register r2 = genExpr(t->op3).reg;
if (r1 != r2) // FIXME, need a way to specify a dest???
move(r1, r2);
setLabel(beyondBranch);
@ -975,7 +976,7 @@ Register 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));
setProperty(ret, (static_cast<IdentifierExprNode *>(e->field))->name, genExpr(e->value).reg);
e = e->next;
}
}
@ -986,7 +987,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
NOT_REACHED("Unsupported ExprNode kind");
}
}
return ret;
return Result(ret, Any_Type);
}
/*
@ -1026,7 +1027,11 @@ void ICodeGenerator::preprocess(StmtNode *p)
VariableBinding *v = vs->bindings;
while (v) {
if (v->name && (v->name->getKind() == ExprNode::identifier))
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
if (v->type->getKind() == ExprNode::identifier)
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name,
(static_cast<IdentifierExprNode *>(v->type))->name);
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
}
@ -1141,12 +1146,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);
Register val = genExpr(v->initializer);
Register r = genExpr(v->name).reg;
Register val = genExpr(v->initializer).reg;
move(r, val);
}
else {
Register val = genExpr(v->initializer);
Register val = genExpr(v->initializer).reg;
saveName((static_cast<IdentifierExprNode *>(v->name))->name, val);
}
}
@ -1159,20 +1164,20 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::expression:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
ret = genExpr(e->expr);
ret = genExpr(e->expr).reg;
}
break;
case StmtNode::Throw:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
throwStmt(genExpr(e->expr));
throwStmt(genExpr(e->expr).reg);
}
break;
case StmtNode::Return:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
if (e->expr)
returnStmt(ret = genExpr(e->expr));
returnStmt(ret = genExpr(e->expr).reg);
else
returnStmt(NotARegister);
}
@ -1181,7 +1186,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
{
Label *falseLabel = getLabel();
UnaryStmtNode *i = static_cast<UnaryStmtNode *>(p);
Register c = genExpr(i->expr, false, NULL, falseLabel);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1193,7 +1198,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);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1206,7 +1211,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::With:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
Register o = genExpr(w->expr);
Register o = genExpr(w->expr).reg;
bool withinWith = mWithinWith;
mWithinWith = true;
beginWith(o);
@ -1221,7 +1226,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);
Register sc = genExpr(sw->expr).reg;
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.
@ -1234,7 +1239,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
if (nextCaseLabel)
setLabel(nextCaseLabel);
nextCaseLabel = getLabel();
Register r = genExpr(c->expr);
Register r = genExpr(c->expr).reg;
Register eq = op(COMPARE_EQ, r, sc);
lastBranch = branchFalse(nextCaseLabel, eq);
}
@ -1265,7 +1270,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(doBodyTopLabel);
genStmt(d->stmt);
setLabel(e->continueLabel);
Register c = genExpr(d->expr, false, doBodyTopLabel, NULL);
Register c = genExpr(d->expr, false, doBodyTopLabel, NULL).reg;
if (!generatedBoolean(d->expr))
branchTrue(doBodyTopLabel, test(c));
setLabel(e->breakLabel);
@ -1285,7 +1290,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
genStmt(w->stmt);
setLabel(e->continueLabel);
Register c = genExpr(w->expr, false, whileBodyTopLabel, NULL);
Register c = genExpr(w->expr, false, whileBodyTopLabel, NULL).reg;
if (!generatedBoolean(w->expr))
branchTrue(whileBodyTopLabel, test(c));
@ -1310,11 +1315,11 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(e->continueLabel);
if (f->expr3)
genExpr(f->expr3);
genExpr(f->expr3).reg;
setLabel(forTestLabel);
if (f->expr2) {
Register c = genExpr(f->expr2, false, forBlockTop, NULL);
Register c = genExpr(f->expr2, false, forBlockTop, NULL).reg;
if (!generatedBoolean(f->expr2))
branchTrue(forBlockTop, test(c));
}

View File

@ -105,6 +105,12 @@ 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;
@ -187,7 +193,7 @@ namespace ICG {
ICodeModule *complete();
Register genExpr(ExprNode *p,
Result genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
@ -201,6 +207,9 @@ namespace ICG {
{ iCode->push_back(new Throw(r)); }
Register allocateVariable(const StringAtom& name);
Register allocateVariable(const StringAtom& name, const StringAtom& /*type */)
{ return allocateVariable(name); }
Register findVariable(const StringAtom& name)
{ VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? NotARegister : (*i).second; }

View File

@ -349,11 +349,14 @@ public:
BinaryOperator(const JSType *t1, const JSType *t2, JSBinaryOperator *function) :
t1(t1), t2(t2), function(function) { }
BinaryOperator(const JSType *t1, const JSType *t2, JSFunction *function) :
t1(t1), t2(t2), function(function) { }
static BinaryOp mapICodeOp(ICodeOp op);
const JSType *t1;
const JSType *t2;
JSBinaryOperator *function;
JSFunction *function;
};
@ -389,28 +392,74 @@ typedef std::vector<BinaryOperator *> BinaryOperatorList;
BinaryOperatorList binaryOperators[15];
JSBinaryOperator::JSBinaryCode defaultFunction[] = {
add_Default,
subtract_Default,
multiply_Default,
divide_Default,
remainder_Default,
shiftLeft_Default,
shiftRight_Default,
UshiftRight_Default,
or_Default,
xor_Default,
and_Default,
less_Default,
lessEqual_Default,
equal_Default,
identical_Default
};
class InitBinaryOperators {
public:
InitBinaryOperators() {
binaryOperators[BinaryOperator::Add].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(add_Default)));
binaryOperators[BinaryOperator::Subtract].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(subtract_Default)));
binaryOperators[BinaryOperator::Multiply].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(multiply_Default)));
binaryOperators[BinaryOperator::Divide].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(divide_Default)));
binaryOperators[BinaryOperator::Remainder].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(remainder_Default)));
binaryOperators[BinaryOperator::LeftShift].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(shiftLeft_Default)));
binaryOperators[BinaryOperator::RightShift].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(shiftRight_Default)));
binaryOperators[BinaryOperator::LogicalRightShift].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(UshiftRight_Default)));
binaryOperators[BinaryOperator::BitwiseOr].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(or_Default)));
binaryOperators[BinaryOperator::BitwiseXor].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(xor_Default)));
binaryOperators[BinaryOperator::BitwiseAnd].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(and_Default)));
binaryOperators[BinaryOperator::Less].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(less_Default)));
binaryOperators[BinaryOperator::LessEqual].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(lessEqual_Default)));
binaryOperators[BinaryOperator::Equal].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(equal_Default)));
binaryOperators[BinaryOperator::Identical].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(identical_Default)));
}
for (int i = BinaryOperator::Add; i <= BinaryOperator::Identical; i++)
binaryOperators[i].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(defaultFunction[i])));
}
} initializer = InitBinaryOperators();
static JSValue defineAdd(const JSValues& argv)
{
// should be three args, first two are types, third is a function.
ASSERT(argv[0].isType());
ASSERT(argv[1].isType());
ASSERT(argv[2].isFunction());
// XXX need to prove that argv[2].function takes T1 and T2 as args and returns Boolean for the relational operators ?
// stdOut << *argv[2].function->getICode();
binaryOperators[BinaryOperator::Add].push_back(new BinaryOperator(argv[0].type, argv[1].type, argv[2].function));
return kUndefinedValue;
}
void Context::initContext()
{
// predefine the predefined types;
mGlobal->defineVariable(widenCString("any"), JSValue(&Any_Type));
mGlobal->defineVariable(widenCString("Integer"), JSValue(&Integer_Type));
mGlobal->defineVariable(widenCString("Number"), JSValue(&Number_Type));
mGlobal->defineVariable(widenCString("Character"), JSValue(&Character_Type));
mGlobal->defineVariable(widenCString("String"), JSValue(&String_Type));
mGlobal->defineVariable(widenCString("Function"), JSValue(&Function_Type));
mGlobal->defineVariable(widenCString("Array"), JSValue(&Array_Type));
mGlobal->defineVariable(widenCString("Type"), JSValue(&Type_Type));
mGlobal->defineVariable(widenCString("Boolean"), JSValue(&Boolean_Type));
mGlobal->defineVariable(widenCString("Null"), JSValue(&Null_Type));
mGlobal->defineVariable(widenCString("Void"), JSValue(&Void_Type));
mGlobal->defineVariable(widenCString("none"), JSValue(&None_Type));
// hack - the following should be available only after importing the 'Operators' package
// (hmm, how will that work - the import needs to connect the functions into this mechanism
// do we watch for the specific package name???)
StringAtom& name = mWorld.identifiers[widenCString("defineAdd")];
mGlobal->defineNativeFunction(name, defineAdd);
}
static const JSValue findBinaryOverride(JSValue &operand1, JSValue &operand2, BinaryOperator::BinaryOp op)
{

View File

@ -37,9 +37,10 @@ namespace Interpreter {
struct Linkage;
class Context : public gc_base {
void initContext();
public:
explicit Context(World& world, JSScope* aGlobal)
: mWorld(world), mGlobal(aGlobal), mLinkage(0), mActivation(0) {}
: mWorld(world), mGlobal(aGlobal), mLinkage(0), mActivation(0) { initContext(); }
World& getWorld() { return mWorld; }
JSScope* getGlobalObject() { return mGlobal; }

View File

@ -189,7 +189,7 @@ Formatter& operator<<(Formatter& f, const JSValue& value)
printFormat(f, "Function @ 0x%08X", value.object);
break;
case JSValue::string_tag:
f << "\"" << *value.string << "\"";
f << *value.string;
break;
case JSValue::boolean_tag:
f << ((value.boolean) ? "true" : "false");

View File

@ -77,7 +77,7 @@ namespace JSTypes {
JSArray* array;
JSFunction *function;
JSString *string;
JSType *type;
const JSType *type;
bool boolean;
};
@ -106,7 +106,7 @@ namespace JSTypes {
explicit JSValue(JSFunction* function) : function(function), tag(function_tag) {}
explicit JSValue(JSString* string) : string(string), tag(string_tag) {}
explicit JSValue(bool boolean) : boolean(boolean), tag(boolean_tag) {}
explicit JSValue(JSType* type) : type(type), tag(type_tag) {}
explicit JSValue(const JSType* type) : type(type), tag(type_tag) {}
int32& operator=(int32 i32) { return (tag = i32_tag, this->i32 = i32); }
uint32& operator=(uint32 u32) { return (tag = u32_tag, this->u32 = u32); }
@ -116,7 +116,7 @@ namespace JSTypes {
JSFunction*& operator=(JSFunction* function) { return (tag = function_tag, this->function = function); }
JSString*& operator=(JSString* string) { return (tag = string_tag, this->string = string); }
bool& operator=(bool boolean) { return (tag = boolean_tag, this->boolean = boolean); }
JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); }
const JSType*& operator=(const JSType* type) { return (tag = type_tag, this->type = type); }
bool isFunction() const { return (tag == function_tag); }
bool isObject() const { return ((tag == object_tag) || (tag == function_tag) || (tag == array_tag)); }
@ -129,6 +129,7 @@ namespace JSTypes {
bool isUndefined() const { return (tag == undefined_tag); }
bool isNull() const { return ((tag == object_tag) && (this->object == NULL)); }
bool isNaN() const;
bool isType() const { return (tag == type_tag); }
JSValue toString() const { return (isString() ? *this : valueToString(*this)); }
JSValue toNumber() const { return (isNumber() ? *this : valueToNumber(*this)); }
@ -146,7 +147,7 @@ namespace JSTypes {
static JSValue valueToBoolean(const JSValue& value);
const JSType *getType() const;
const JSType *getType() const; // map from tag type to JS2 type
int operator==(const JSValue& value) const;
};

View File

@ -498,12 +498,13 @@ static bool generatedBoolean(ExprNode *p)
}
/*
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
indicates that the label is immediately forthcoming.
*/
Register ICodeGenerator::genExpr(ExprNode *p,
Result ICodeGenerator::genExpr(ExprNode *p,
bool needBoolValueInBranch,
Label *trueBranch,
Label *falseBranch)
@ -533,7 +534,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::parentheses:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch);
ret = genExpr(u->op, needBoolValueInBranch, trueBranch, falseBranch).reg;
}
break;
case ExprNode::New:
@ -545,11 +546,11 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::call :
{
InvokeExprNode *i = static_cast<InvokeExprNode *>(p);
Register fn = genExpr(i->op);
Register fn = genExpr(i->op).reg;
RegisterList args;
ExprPairList *p = i->pairs;
while (p) {
args.push_back(genExpr(p->value));
args.push_back(genExpr(p->value).reg);
p = p->next;
}
ret = call(fn, args);
@ -558,15 +559,15 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::index :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = getElement(base, index);
}
break;
case ExprNode::dot :
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register base = genExpr(b->op1);
Register base = genExpr(b->op1).reg;
ret = getProperty(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
break;
@ -594,7 +595,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
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);
@ -620,8 +621,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = getElement(base, index);
ret = op(ADD, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -633,7 +634,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
ret = propertyInc(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
@ -651,8 +652,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = elementInc(base, index);
}
}
@ -662,7 +663,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
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);
@ -688,8 +689,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = getElement(base, index);
ret = op(SUBTRACT, ret, loadImmediate(1.0));
setElement(base, index, ret);
@ -701,7 +702,7 @@ Register 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);
Register base = genExpr(b->op1).reg;
ret = propertyDec(base, static_cast<IdentifierExprNode *>(b->op2)->name);
}
else
@ -719,8 +720,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (u->op->getKind() == ExprNode::index) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
Register base = genExpr(b->op1);
Register index = genExpr(b->op2);
Register base = genExpr(b->op1).reg;
Register index = genExpr(b->op2).reg;
ret = elementInc(base, index);
}
}
@ -730,7 +731,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::complement:
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
Register r = genExpr(u->op);
Register r = genExpr(u->op).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r);
}
break;
@ -747,15 +748,15 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOr:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
}
break;
case ExprNode::assignment:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2);
ret = genExpr(b->op2).reg;
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
@ -770,14 +771,14 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1);
Register base = genExpr(lb->op1).reg;
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);
Register index = genExpr(lb->op2);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
setElement(base, index, ret);
}
}
@ -795,7 +796,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::bitwiseOrEquals:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
ret = genExpr(b->op2);
ret = genExpr(b->op2).reg;
if (b->op1->getKind() == ExprNode::identifier) {
if (!mWithinWith) {
Register v = findVariable((static_cast<IdentifierExprNode *>(b->op1))->name);
@ -818,7 +819,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::dot) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1);
Register base = genExpr(lb->op1).reg;
Register 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);
@ -826,8 +827,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
else
if (b->op1->getKind() == ExprNode::index) {
BinaryExprNode *lb = static_cast<BinaryExprNode *>(b->op1);
Register base = genExpr(lb->op1);
Register index = genExpr(lb->op2);
Register base = genExpr(lb->op1).reg;
Register index = genExpr(lb->op2).reg;
Register v = getElement(base, index);
ret = op(mapExprNodeToICodeOp(p->getKind()), v, ret);
setElement(base, index, ret);
@ -842,8 +843,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::Instanceof:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -860,8 +861,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::greaterThanOrEqual:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r2, r1); // will return reverse case
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -879,8 +880,8 @@ Register ICodeGenerator::genExpr(ExprNode *p,
case ExprNode::notIdentical:
{
BinaryExprNode *b = static_cast<BinaryExprNode *>(p);
Register r1 = genExpr(b->op1);
Register r2 = genExpr(b->op2);
Register r1 = genExpr(b->op1).reg;
Register r2 = genExpr(b->op2).reg;
ret = op(mapExprNodeToICodeOp(p->getKind()), r1, r2);
if (trueBranch || falseBranch) {
if (trueBranch == NULL)
@ -906,12 +907,12 @@ Register ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *fBranch = getLabel();
Register r1 = genExpr(b->op1, true, NULL, fBranch);
Register r1 = genExpr(b->op1, true, NULL, fBranch).reg;
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchFalse(fBranch, r1);
}
Register r2 = genExpr(b->op2);
Register r2 = genExpr(b->op2).reg;
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -931,12 +932,12 @@ Register ICodeGenerator::genExpr(ExprNode *p,
}
else {
Label *tBranch = getLabel();
Register r1 = genExpr(b->op1, true, tBranch, NULL);
Register r1 = genExpr(b->op1, true, tBranch, NULL).reg;
if (!generatedBoolean(b->op1)) {
r1 = test(r1);
branchTrue(tBranch, r1);
}
Register r2 = genExpr(b->op2);
Register r2 = genExpr(b->op2).reg;
if (!generatedBoolean(b->op2)) {
r2 = test(r2);
}
@ -953,13 +954,13 @@ Register ICodeGenerator::genExpr(ExprNode *p,
TernaryExprNode *t = static_cast<TernaryExprNode *>(p);
Label *fBranch = getLabel();
Label *beyondBranch = getLabel();
Register c = genExpr(t->op1, false, NULL, fBranch);
Register c = genExpr(t->op1, false, NULL, fBranch).reg;
if (!generatedBoolean(t->op1))
branchFalse(fBranch, test(c));
Register r1 = genExpr(t->op2);
Register r1 = genExpr(t->op2).reg;
branch(beyondBranch);
setLabel(fBranch);
Register r2 = genExpr(t->op3);
Register r2 = genExpr(t->op3).reg;
if (r1 != r2) // FIXME, need a way to specify a dest???
move(r1, r2);
setLabel(beyondBranch);
@ -975,7 +976,7 @@ Register 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));
setProperty(ret, (static_cast<IdentifierExprNode *>(e->field))->name, genExpr(e->value).reg);
e = e->next;
}
}
@ -986,7 +987,7 @@ Register ICodeGenerator::genExpr(ExprNode *p,
NOT_REACHED("Unsupported ExprNode kind");
}
}
return ret;
return Result(ret, Any_Type);
}
/*
@ -1026,7 +1027,11 @@ void ICodeGenerator::preprocess(StmtNode *p)
VariableBinding *v = vs->bindings;
while (v) {
if (v->name && (v->name->getKind() == ExprNode::identifier))
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
if (v->type->getKind() == ExprNode::identifier)
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name,
(static_cast<IdentifierExprNode *>(v->type))->name);
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
}
@ -1141,12 +1146,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);
Register val = genExpr(v->initializer);
Register r = genExpr(v->name).reg;
Register val = genExpr(v->initializer).reg;
move(r, val);
}
else {
Register val = genExpr(v->initializer);
Register val = genExpr(v->initializer).reg;
saveName((static_cast<IdentifierExprNode *>(v->name))->name, val);
}
}
@ -1159,20 +1164,20 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::expression:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
ret = genExpr(e->expr);
ret = genExpr(e->expr).reg;
}
break;
case StmtNode::Throw:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
throwStmt(genExpr(e->expr));
throwStmt(genExpr(e->expr).reg);
}
break;
case StmtNode::Return:
{
ExprStmtNode *e = static_cast<ExprStmtNode *>(p);
if (e->expr)
returnStmt(ret = genExpr(e->expr));
returnStmt(ret = genExpr(e->expr).reg);
else
returnStmt(NotARegister);
}
@ -1181,7 +1186,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
{
Label *falseLabel = getLabel();
UnaryStmtNode *i = static_cast<UnaryStmtNode *>(p);
Register c = genExpr(i->expr, false, NULL, falseLabel);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1193,7 +1198,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);
Register c = genExpr(i->expr, false, NULL, falseLabel).reg;
if (!generatedBoolean(i->expr))
branchFalse(falseLabel, test(c));
genStmt(i->stmt);
@ -1206,7 +1211,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
case StmtNode::With:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
Register o = genExpr(w->expr);
Register o = genExpr(w->expr).reg;
bool withinWith = mWithinWith;
mWithinWith = true;
beginWith(o);
@ -1221,7 +1226,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);
Register sc = genExpr(sw->expr).reg;
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.
@ -1234,7 +1239,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
if (nextCaseLabel)
setLabel(nextCaseLabel);
nextCaseLabel = getLabel();
Register r = genExpr(c->expr);
Register r = genExpr(c->expr).reg;
Register eq = op(COMPARE_EQ, r, sc);
lastBranch = branchFalse(nextCaseLabel, eq);
}
@ -1265,7 +1270,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(doBodyTopLabel);
genStmt(d->stmt);
setLabel(e->continueLabel);
Register c = genExpr(d->expr, false, doBodyTopLabel, NULL);
Register c = genExpr(d->expr, false, doBodyTopLabel, NULL).reg;
if (!generatedBoolean(d->expr))
branchTrue(doBodyTopLabel, test(c));
setLabel(e->breakLabel);
@ -1285,7 +1290,7 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
genStmt(w->stmt);
setLabel(e->continueLabel);
Register c = genExpr(w->expr, false, whileBodyTopLabel, NULL);
Register c = genExpr(w->expr, false, whileBodyTopLabel, NULL).reg;
if (!generatedBoolean(w->expr))
branchTrue(whileBodyTopLabel, test(c));
@ -1310,11 +1315,11 @@ Register ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
setLabel(e->continueLabel);
if (f->expr3)
genExpr(f->expr3);
genExpr(f->expr3).reg;
setLabel(forTestLabel);
if (f->expr2) {
Register c = genExpr(f->expr2, false, forBlockTop, NULL);
Register c = genExpr(f->expr2, false, forBlockTop, NULL).reg;
if (!generatedBoolean(f->expr2))
branchTrue(forBlockTop, test(c));
}

View File

@ -105,6 +105,12 @@ 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;
@ -187,7 +193,7 @@ namespace ICG {
ICodeModule *complete();
Register genExpr(ExprNode *p,
Result genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
@ -201,6 +207,9 @@ namespace ICG {
{ iCode->push_back(new Throw(r)); }
Register allocateVariable(const StringAtom& name);
Register allocateVariable(const StringAtom& name, const StringAtom& /*type */)
{ return allocateVariable(name); }
Register findVariable(const StringAtom& name)
{ VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? NotARegister : (*i).second; }

View File

@ -349,11 +349,14 @@ public:
BinaryOperator(const JSType *t1, const JSType *t2, JSBinaryOperator *function) :
t1(t1), t2(t2), function(function) { }
BinaryOperator(const JSType *t1, const JSType *t2, JSFunction *function) :
t1(t1), t2(t2), function(function) { }
static BinaryOp mapICodeOp(ICodeOp op);
const JSType *t1;
const JSType *t2;
JSBinaryOperator *function;
JSFunction *function;
};
@ -389,28 +392,74 @@ typedef std::vector<BinaryOperator *> BinaryOperatorList;
BinaryOperatorList binaryOperators[15];
JSBinaryOperator::JSBinaryCode defaultFunction[] = {
add_Default,
subtract_Default,
multiply_Default,
divide_Default,
remainder_Default,
shiftLeft_Default,
shiftRight_Default,
UshiftRight_Default,
or_Default,
xor_Default,
and_Default,
less_Default,
lessEqual_Default,
equal_Default,
identical_Default
};
class InitBinaryOperators {
public:
InitBinaryOperators() {
binaryOperators[BinaryOperator::Add].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(add_Default)));
binaryOperators[BinaryOperator::Subtract].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(subtract_Default)));
binaryOperators[BinaryOperator::Multiply].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(multiply_Default)));
binaryOperators[BinaryOperator::Divide].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(divide_Default)));
binaryOperators[BinaryOperator::Remainder].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(remainder_Default)));
binaryOperators[BinaryOperator::LeftShift].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(shiftLeft_Default)));
binaryOperators[BinaryOperator::RightShift].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(shiftRight_Default)));
binaryOperators[BinaryOperator::LogicalRightShift].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(UshiftRight_Default)));
binaryOperators[BinaryOperator::BitwiseOr].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(or_Default)));
binaryOperators[BinaryOperator::BitwiseXor].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(xor_Default)));
binaryOperators[BinaryOperator::BitwiseAnd].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(and_Default)));
binaryOperators[BinaryOperator::Less].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(less_Default)));
binaryOperators[BinaryOperator::LessEqual].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(lessEqual_Default)));
binaryOperators[BinaryOperator::Equal].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(equal_Default)));
binaryOperators[BinaryOperator::Identical].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(identical_Default)));
}
for (int i = BinaryOperator::Add; i <= BinaryOperator::Identical; i++)
binaryOperators[i].push_back(new BinaryOperator(&Any_Type, &Any_Type, new JSBinaryOperator(defaultFunction[i])));
}
} initializer = InitBinaryOperators();
static JSValue defineAdd(const JSValues& argv)
{
// should be three args, first two are types, third is a function.
ASSERT(argv[0].isType());
ASSERT(argv[1].isType());
ASSERT(argv[2].isFunction());
// XXX need to prove that argv[2].function takes T1 and T2 as args and returns Boolean for the relational operators ?
// stdOut << *argv[2].function->getICode();
binaryOperators[BinaryOperator::Add].push_back(new BinaryOperator(argv[0].type, argv[1].type, argv[2].function));
return kUndefinedValue;
}
void Context::initContext()
{
// predefine the predefined types;
mGlobal->defineVariable(widenCString("any"), JSValue(&Any_Type));
mGlobal->defineVariable(widenCString("Integer"), JSValue(&Integer_Type));
mGlobal->defineVariable(widenCString("Number"), JSValue(&Number_Type));
mGlobal->defineVariable(widenCString("Character"), JSValue(&Character_Type));
mGlobal->defineVariable(widenCString("String"), JSValue(&String_Type));
mGlobal->defineVariable(widenCString("Function"), JSValue(&Function_Type));
mGlobal->defineVariable(widenCString("Array"), JSValue(&Array_Type));
mGlobal->defineVariable(widenCString("Type"), JSValue(&Type_Type));
mGlobal->defineVariable(widenCString("Boolean"), JSValue(&Boolean_Type));
mGlobal->defineVariable(widenCString("Null"), JSValue(&Null_Type));
mGlobal->defineVariable(widenCString("Void"), JSValue(&Void_Type));
mGlobal->defineVariable(widenCString("none"), JSValue(&None_Type));
// hack - the following should be available only after importing the 'Operators' package
// (hmm, how will that work - the import needs to connect the functions into this mechanism
// do we watch for the specific package name???)
StringAtom& name = mWorld.identifiers[widenCString("defineAdd")];
mGlobal->defineNativeFunction(name, defineAdd);
}
static const JSValue findBinaryOverride(JSValue &operand1, JSValue &operand2, BinaryOperator::BinaryOp op)
{

View File

@ -37,9 +37,10 @@ namespace Interpreter {
struct Linkage;
class Context : public gc_base {
void initContext();
public:
explicit Context(World& world, JSScope* aGlobal)
: mWorld(world), mGlobal(aGlobal), mLinkage(0), mActivation(0) {}
: mWorld(world), mGlobal(aGlobal), mLinkage(0), mActivation(0) { initContext(); }
World& getWorld() { return mWorld; }
JSScope* getGlobalObject() { return mGlobal; }

View File

@ -189,7 +189,7 @@ Formatter& operator<<(Formatter& f, const JSValue& value)
printFormat(f, "Function @ 0x%08X", value.object);
break;
case JSValue::string_tag:
f << "\"" << *value.string << "\"";
f << *value.string;
break;
case JSValue::boolean_tag:
f << ((value.boolean) ? "true" : "false");

View File

@ -77,7 +77,7 @@ namespace JSTypes {
JSArray* array;
JSFunction *function;
JSString *string;
JSType *type;
const JSType *type;
bool boolean;
};
@ -106,7 +106,7 @@ namespace JSTypes {
explicit JSValue(JSFunction* function) : function(function), tag(function_tag) {}
explicit JSValue(JSString* string) : string(string), tag(string_tag) {}
explicit JSValue(bool boolean) : boolean(boolean), tag(boolean_tag) {}
explicit JSValue(JSType* type) : type(type), tag(type_tag) {}
explicit JSValue(const JSType* type) : type(type), tag(type_tag) {}
int32& operator=(int32 i32) { return (tag = i32_tag, this->i32 = i32); }
uint32& operator=(uint32 u32) { return (tag = u32_tag, this->u32 = u32); }
@ -116,7 +116,7 @@ namespace JSTypes {
JSFunction*& operator=(JSFunction* function) { return (tag = function_tag, this->function = function); }
JSString*& operator=(JSString* string) { return (tag = string_tag, this->string = string); }
bool& operator=(bool boolean) { return (tag = boolean_tag, this->boolean = boolean); }
JSType*& operator=(JSType* type) { return (tag = type_tag, this->type = type); }
const JSType*& operator=(const JSType* type) { return (tag = type_tag, this->type = type); }
bool isFunction() const { return (tag == function_tag); }
bool isObject() const { return ((tag == object_tag) || (tag == function_tag) || (tag == array_tag)); }
@ -129,6 +129,7 @@ namespace JSTypes {
bool isUndefined() const { return (tag == undefined_tag); }
bool isNull() const { return ((tag == object_tag) && (this->object == NULL)); }
bool isNaN() const;
bool isType() const { return (tag == type_tag); }
JSValue toString() const { return (isString() ? *this : valueToString(*this)); }
JSValue toNumber() const { return (isNumber() ? *this : valueToNumber(*this)); }
@ -146,7 +147,7 @@ namespace JSTypes {
static JSValue valueToBoolean(const JSValue& value);
const JSType *getType() const;
const JSType *getType() const; // map from tag type to JS2 type
int operator==(const JSValue& value) const;
};