Removed preprocess step, consolidated identifier handling.

This commit is contained in:
rogerl%netscape.com 2000-07-06 18:26:26 +00:00
parent a5fcf7a3b9
commit 1375151969
12 changed files with 624 additions and 714 deletions

View File

@ -66,11 +66,9 @@ Formatter& operator<<(Formatter &f, ICodeModule &i)
ICodeGenerator::ICodeGenerator(World *world, JSScope *global, JSClass *aClass, ICodeGeneratorFlags flags)
: topRegister(0),
registerBase(0),
maxRegister(0),
parameterCount(0),
exceptionRegister(TypedRegister(NotARegister, &None_Type)),
: mTopRegister(0),
mParameterCount(0),
mExceptionRegister(TypedRegister(NotARegister, &None_Type)),
variableList(new VariableList()),
mWorld(world),
mGlobal(global),
@ -90,20 +88,39 @@ JSType *ICodeGenerator::findType(const StringAtom& typeName)
return &Any_Type;
}
TypedRegister ICodeGenerator::allocateRegister(const StringAtom& name, JSType *type)
{
Register r = mTopRegister;
while (r < mPermanentRegister.size())
if (!mPermanentRegister[r])
break;
else
++r;
if (r == mPermanentRegister.size())
mPermanentRegister.resize(r + 1);
mPermanentRegister[r] = true;
TypedRegister result(r, type);
(*variableList)[name] = result;
mTopRegister = ++r;
return result;
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name, const StringAtom& typeName)
{
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
if (mExceptionRegister.first == NotARegister) {
mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name, findType(typeName));
return allocateRegister(name, findType(typeName));
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name)
{
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
if (mExceptionRegister.first == NotARegister) {
mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name, &Any_Type);
return allocateRegister(name, &Any_Type);
}
ICodeModule *ICodeGenerator::complete()
@ -149,8 +166,7 @@ ICodeModule *ICodeGenerator::complete()
}
}
*/
markMaxRegister();
ICodeModule* module = new ICodeModule(iCode, variableList, maxRegister, 0, mInstructionMap);
ICodeModule* module = new ICodeModule(iCode, variableList, mPermanentRegister.size(), 0, mInstructionMap);
iCodeOwner = false; // give ownership to the module.
return module;
}
@ -160,7 +176,7 @@ ICodeModule *ICodeGenerator::complete()
TypedRegister ICodeGenerator::loadImmediate(double value)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
LoadImmediate *instr = new LoadImmediate(dest, value);
iCode->push_back(instr);
return dest;
@ -168,7 +184,7 @@ TypedRegister ICodeGenerator::loadImmediate(double value)
TypedRegister ICodeGenerator::loadString(String &value)
{
TypedRegister dest(getRegister(), &String_Type);
TypedRegister dest(getTempRegister(), &String_Type);
LoadString *instr = new LoadString(dest, new JSString(value));
iCode->push_back(instr);
return dest;
@ -176,7 +192,7 @@ TypedRegister ICodeGenerator::loadString(String &value)
TypedRegister ICodeGenerator::loadString(const StringAtom &value)
{
TypedRegister dest(getRegister(), &String_Type);
TypedRegister dest(getTempRegister(), &String_Type);
LoadString *instr = new LoadString(dest, new JSString(value));
iCode->push_back(instr);
return dest;
@ -184,7 +200,7 @@ TypedRegister ICodeGenerator::loadString(const StringAtom &value)
TypedRegister ICodeGenerator::loadBoolean(bool value)
{
TypedRegister dest(getRegister(), &Boolean_Type);
TypedRegister dest(getTempRegister(), &Boolean_Type);
LoadBoolean *instr = new LoadBoolean(dest, value);
iCode->push_back(instr);
return dest;
@ -192,7 +208,7 @@ TypedRegister ICodeGenerator::loadBoolean(bool value)
TypedRegister ICodeGenerator::newObject()
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
NewObject *instr = new NewObject(dest);
iCode->push_back(instr);
return dest;
@ -200,7 +216,7 @@ TypedRegister ICodeGenerator::newObject()
TypedRegister ICodeGenerator::newClass(const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
NewClass *instr = new NewClass(dest, &name);
iCode->push_back(instr);
return dest;
@ -208,7 +224,7 @@ TypedRegister ICodeGenerator::newClass(const StringAtom &name)
TypedRegister ICodeGenerator::newFunction(ICodeModule *icm)
{
TypedRegister dest(getRegister(), &Function_Type);
TypedRegister dest(getTempRegister(), &Function_Type);
NewFunction *instr = new NewFunction(dest, icm);
iCode->push_back(instr);
return dest;
@ -216,7 +232,7 @@ TypedRegister ICodeGenerator::newFunction(ICodeModule *icm)
TypedRegister ICodeGenerator::newArray()
{
TypedRegister dest(getRegister(), &Array_Type);
TypedRegister dest(getTempRegister(), &Array_Type);
NewArray *instr = new NewArray(dest);
iCode->push_back(instr);
return dest;
@ -226,7 +242,7 @@ TypedRegister ICodeGenerator::newArray()
TypedRegister ICodeGenerator::loadName(const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
LoadName *instr = new LoadName(dest, &name);
iCode->push_back(instr);
return dest;
@ -240,7 +256,7 @@ void ICodeGenerator::saveName(const StringAtom &name, TypedRegister value)
TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
NameXcr *instr = new NameXcr(dest, &name, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -250,7 +266,7 @@ TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op)
TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
VarXcr *instr = new VarXcr(dest, var, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -261,7 +277,7 @@ TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op)
TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
DeleteProp *instr = new DeleteProp(dest, base, &name);
iCode->push_back(instr);
return dest;
@ -269,7 +285,7 @@ TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAto
TypedRegister ICodeGenerator::getProperty(TypedRegister base, const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
GetProp *instr = new GetProp(dest, base, &name);
iCode->push_back(instr);
return dest;
@ -284,7 +300,7 @@ void ICodeGenerator::setProperty(TypedRegister base, const StringAtom &name,
TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom &name, ICodeOp op)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
PropXcr *instr = new PropXcr(dest, base, &name, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -296,7 +312,7 @@ TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom &
TypedRegister ICodeGenerator::getStatic(JSClass *base, const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
const JSSlot& slot = base->getStatic(name);
GetStatic *instr = new GetStatic(dest, base, slot.mIndex);
iCode->push_back(instr);
@ -313,7 +329,7 @@ void ICodeGenerator::setStatic(JSClass *base, const StringAtom &name,
TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, ICodeOp op)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
const JSSlot& slot = base->getStatic(name);
StaticXcr *instr = new StaticXcr(dest, base, slot.mIndex, 1.0);
iCode->push_back(instr);
@ -325,7 +341,7 @@ TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, I
TypedRegister ICodeGenerator::getSlot(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
GetSlot *instr = new GetSlot(dest, base, slot);
iCode->push_back(instr);
return dest;
@ -340,7 +356,7 @@ void ICodeGenerator::setSlot(TypedRegister base, uint32 slot,
TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp op)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
SlotXcr *instr = new SlotXcr(dest, base, slot, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -351,7 +367,7 @@ TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp o
TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
GetElement *instr = new GetElement(dest, base, index);
iCode->push_back(instr);
return dest;
@ -366,7 +382,7 @@ void ICodeGenerator::setElement(TypedRegister base, TypedRegister index,
TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index, ICodeOp op)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
ElemXcr *instr = new ElemXcr(dest, base, index, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -376,7 +392,7 @@ TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index
TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
ASSERT(source.first != NotARegister);
Unary *instr = new Unary (op, dest, source);
iCode->push_back(instr);
@ -394,7 +410,7 @@ void ICodeGenerator::move(TypedRegister destination, TypedRegister source)
TypedRegister ICodeGenerator::logicalNot(TypedRegister source)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Not *instr = new Not(dest, source);
iCode->push_back(instr);
return dest;
@ -402,7 +418,7 @@ TypedRegister ICodeGenerator::logicalNot(TypedRegister source)
TypedRegister ICodeGenerator::test(TypedRegister source)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Test *instr = new Test(dest, source);
iCode->push_back(instr);
return dest;
@ -413,7 +429,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1,
{
ASSERT(source1.first != NotARegister);
ASSERT(source2.first != NotARegister);
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Arithmetic *instr = new Arithmetic(op, dest, source1, source2);
iCode->push_back(instr);
return dest;
@ -421,7 +437,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1,
TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name, RegisterList args)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Call *instr = new Call(dest, target, &name, args);
iCode->push_back(instr);
return dest;
@ -429,7 +445,7 @@ TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name,
TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister targetValue, RegisterList args)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
MethodCall *instr = new MethodCall(dest, targetBase, targetValue, args);
iCode->push_back(instr);
return dest;
@ -437,7 +453,7 @@ TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister
TypedRegister ICodeGenerator::staticCall(JSClass *c, const StringAtom &name, RegisterList args)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
const JSSlot& slot = c->getStatic(name);
StaticCall *instr = new StaticCall(dest, c, slot.mIndex, args);
iCode->push_back(instr);
@ -618,46 +634,161 @@ static bool isSlotName(JSType *t, const StringAtom &name, uint32 &slotIndex, JST
return false;
}
TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args)
ICodeGenerator::LValueKind ICodeGenerator::resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex)
{
enum {Property, Slot, Static} lValueKind;
if (!isWithinWith()) {
v = findVariable(name);
if (v.first != NotARegister)
return Var;
else {
if (mClass) { // we're compiling a method of a class
if (!isStaticMethod()) {
if (isSlotName(mClass, name, slotIndex, v.second))
return Slot;
}
if (mClass->hasStatic(name, v.second)) {
return Static;
}
}
v.second = mGlobal->getType(name);
return Name;
}
}
v.second = &Any_Type;
return Name;
}
TypedRegister ICodeGenerator::handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args)
{
ASSERT(p->getKind() == ExprNode::identifier);
JSType *vType = &Any_Type;
uint32 slotIndex;
TypedRegister ret;
TypedRegister v;
const StringAtom &name = (static_cast<IdentifierExprNode *>(p))->name;
LValueKind lValueKind = resolveIdentifier(name, ret, slotIndex);
TypedRegister thisBase = TypedRegister(0, mClass ? mClass : &Any_Type);
switch (use) {
case ExprNode::identifier:
switch (lValueKind) {
case Var:
break;
case Name:
ret = loadName(name);
break;
case Slot:
ret = getSlot(thisBase, slotIndex);
break;
case Static:
ret = getStatic(mClass, name);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
case ExprNode::preDecrement:
case ExprNode::preIncrement:
switch (lValueKind) {
case Var:
ret = op(xcrementOp, ret, loadImmediate(1.0));
break;
case Name:
ret = loadName(name);
ret = op(xcrementOp, ret, loadImmediate(1.0));
saveName(name, ret);
break;
case Slot:
ret = op(xcrementOp, getSlot(thisBase, slotIndex), loadImmediate(1.0));
setSlot(thisBase, slotIndex, ret);
break;
case Static:
ret = op(xcrementOp, getStatic(mClass, name), loadImmediate(1.0));
setStatic(mClass, name, ret);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
case ExprNode::postDecrement:
case ExprNode::postIncrement:
switch (lValueKind) {
case Var:
ret = varXcr(ret, xcrementOp);
break;
case Name:
ret = nameXcr(name, xcrementOp);
break;
case Slot:
ret = slotXcr(thisBase, slotIndex, xcrementOp);
break;
case Static:
ret = staticXcr(mClass, name, xcrementOp);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
case ExprNode::call:
switch (lValueKind) {
case Var:
ret = call(ret, name, *args);
break;
case Name:
ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(name), *args);
break;
case Static:
ret = staticCall(mClass, name, *args);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
}
return ret;
}
TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args)
{
ASSERT(b->getKind() == ExprNode::dot);
LValueKind lValueKind;
if (b->op2->getKind() != ExprNode::identifier) {
NOT_REACHED("Implement me"); // turns into a getProperty (but not via any overloaded [] )
}
else {
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
const StringAtom &fieldName = static_cast<IdentifierExprNode *>(b->op2)->name;
TypedRegister base;
JSClass *c = NULL;
JSClass *clazz = NULL;
JSType *fieldType = &Any_Type;
uint32 slotIndex;
if ((b->op1->getKind() == ExprNode::identifier) && !isWithinWith()) {
const StringAtom &baseName = (static_cast<IdentifierExprNode *>(b->op1))->name;
JSType *baseType = &Any_Type;
base = findVariable(baseName);
if (base.first != NotARegister)
baseType = base.second;
else {
// implicit 'this' has a big impact here
baseType = mGlobal->getType(baseName);
}
resolveIdentifier(baseName, base, slotIndex);
lValueKind = Property;
if (baseType == &Type_Type) {
//
// handle <class name>.<static field>
//
if (base.second == &Type_Type) {
const JSValue &v = mGlobal->getVariable(baseName);
c = dynamic_cast<JSClass*>(v.type);
if (c && c->hasStatic(name, fieldType)) {
clazz = dynamic_cast<JSClass*>(v.type);
if (clazz && clazz->hasStatic(fieldName, fieldType)) {
lValueKind = Static;
}
}
if (lValueKind == Property) {
if (isSlotName(baseType, name, slotIndex, fieldType))
if (isSlotName(base.second, fieldName, slotIndex, fieldType))
lValueKind = Slot;
else {
c = dynamic_cast<JSClass*>(baseType);
if (c && c->hasStatic(name, fieldType))
clazz = dynamic_cast<JSClass*>(base.second);
if (clazz && clazz->hasStatic(fieldName, fieldType))
lValueKind = Static;
else
lValueKind = Property;
@ -668,11 +799,11 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
}
else {
base = genExpr(b->op1);
if (isSlotName(base.second, name, slotIndex, fieldType))
if (isSlotName(base.second, fieldName, slotIndex, fieldType))
lValueKind = Slot;
else {
c = dynamic_cast<JSClass*>(base.second);
if (c && c->hasStatic(name, fieldType))
clazz = dynamic_cast<JSClass*>(base.second);
if (clazz && clazz->hasStatic(fieldName, fieldType))
lValueKind = Static;
else
lValueKind = Property;
@ -683,10 +814,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::call:
switch (lValueKind) {
case Static:
ret = staticCall(c, name, *args);
ret = staticCall(clazz, fieldName, *args);
break;
case Property:
ret = methodCall(base, loadString(name), *args);
ret = methodCall(base, loadString(fieldName), *args);
break;
default:
NOT_REACHED("Bad lvalue kind");
@ -706,10 +837,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::bitwiseOrEquals:
switch (lValueKind) {
case Static:
v = getStatic(c, name);
v = getStatic(clazz, fieldName);
break;
case Property:
v = getProperty(base, name);
v = getProperty(base, fieldName);
break;
case Slot:
v = getSlot(base, slotIndex);
@ -726,10 +857,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::assignment:
switch (lValueKind) {
case Static:
setStatic(c, name, ret);
setStatic(clazz, fieldName, ret);
break;
case Property:
setProperty(base, name, ret);
setProperty(base, fieldName, ret);
break;
case Slot:
setSlot(base, slotIndex, ret);
@ -742,10 +873,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::postIncrement:
switch (lValueKind) {
case Static:
ret = staticXcr(c, name, xcrementOp);
ret = staticXcr(clazz, fieldName, xcrementOp);
break;
case Property:
ret = propertyXcr(base, name, xcrementOp);
ret = propertyXcr(base, fieldName, xcrementOp);
break;
case Slot:
ret = slotXcr(base, slotIndex, xcrementOp);
@ -757,12 +888,12 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::preIncrement:
switch (lValueKind) {
case Static:
ret = op(xcrementOp, getStatic(c, name), loadImmediate(1.0));
setStatic(c, name, ret);
ret = op(xcrementOp, getStatic(clazz, fieldName), loadImmediate(1.0));
setStatic(clazz, fieldName, ret);
break;
case Property:
ret = op(xcrementOp, getProperty(base, name), loadImmediate(1.0));
setProperty(base, name, ret);
ret = op(xcrementOp, getProperty(base, fieldName), loadImmediate(1.0));
setProperty(base, fieldName, ret);
break;
case Slot:
ret = op(xcrementOp, getSlot(base, slotIndex), loadImmediate(1.0));
@ -774,7 +905,7 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
break;
case ExprNode::Delete:
if (lValueKind == Property) {
ret = deleteProperty(base, name);
ret = deleteProperty(base, fieldName);
}
break;
default:
@ -857,34 +988,10 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (i->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(i->op);
ret = handleDot(b, ExprNode::call, xcrementOp, ret, &args);
/*
TypedRegister base = genExpr(b->op1);
// might be Class.<method>()
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
if ((base.second == &Type_Type)
&& (b->op1->getKind() == ExprNode::identifier)) {
const StringAtom &className = (static_cast<IdentifierExprNode *>(b->op1))->name;
const JSValue &v = mGlobal->getVariable(className);
JSClass* c = dynamic_cast<JSClass*>(v.type);
if (c && c->hasStatic(name)) {
ret = staticCall(c, name, args);
break;
}
}
ret = methodCall(base, loadString(name), args);
*/
}
else
if (i->op->getKind() == ExprNode::identifier) {
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(i->op))->name);
if (v.first != NotARegister)
ret = call(v, static_cast<IdentifierExprNode *>(i->op)->name, args);
else
ret = call(TypedRegister(NotARegister, &Null_Type), static_cast<IdentifierExprNode *>(i->op)->name, args);
}
else
ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(static_cast<IdentifierExprNode *>(i->op)->name), args);
ret = handleIdentifier(static_cast<IdentifierExprNode *>(i->op), ExprNode::call, xcrementOp, &args);
}
else
if (i->op->getKind() == ExprNode::index) {
@ -916,34 +1023,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
break;
case ExprNode::identifier :
{
const StringAtom &name = (static_cast<IdentifierExprNode *>(p))->name;
if (!isWithinWith()) {
TypedRegister v = findVariable(name);
if (v.first != NotARegister)
ret = v;
else {
if (mClass) { // we're compiling a method of a class
JSType *fieldType;
if (!isStaticMethod()) {
uint32 slotIndex;
if (isSlotName(mClass, name, slotIndex, fieldType)) {
ret = getSlot(TypedRegister(0, mClass), slotIndex);
ret.second = fieldType;
break;
}
}
if (mClass->hasStatic(name, fieldType)) {
ret = getStatic(mClass, name);
ret.second = fieldType;
break;
}
}
ret = loadName(name);
ret.second = mGlobal->getType(name);
}
}
else
ret = loadName(name);
ret = handleIdentifier(static_cast<IdentifierExprNode *>(p), ExprNode::identifier, xcrementOp, NULL);
}
break;
case ExprNode::number :
@ -958,26 +1038,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL);
ret = handleDot(static_cast<BinaryExprNode *>(u->op), p->getKind(), xcrementOp, ret, NULL);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = op(xcrementOp, ret, loadImmediate(1.0));
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
ret = op(xcrementOp, ret, loadImmediate(1.0));
saveName((static_cast<IdentifierExprNode *>(u->op))->name, ret);
}
}
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
ret = op(xcrementOp, ret, loadImmediate(1.0));
saveName((static_cast<IdentifierExprNode *>(u->op))->name, ret);
}
ret = handleIdentifier(static_cast<IdentifierExprNode *>(u->op), p->getKind(), xcrementOp, NULL);
}
else
if (u->op->getKind() == ExprNode::index) {
@ -998,20 +1063,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL);
ret = handleDot(static_cast<BinaryExprNode *>(u->op), p->getKind(), xcrementOp, ret, NULL);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = varXcr(v, xcrementOp);
else
ret = nameXcr((static_cast<IdentifierExprNode *>(u->op))->name, xcrementOp);
}
else
ret = nameXcr((static_cast<IdentifierExprNode *>(u->op))->name, xcrementOp);
ret = handleIdentifier(static_cast<IdentifierExprNode *>(u->op), p->getKind(), xcrementOp, NULL);
}
else
if (u->op->getKind() == ExprNode::index) {
@ -1291,7 +1347,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
icg.allocateParameter((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
icg.preprocess(f->function.body);
icg.genStmt(f->function.body);
//stdOut << icg;
ICodeModule *icm = icg.complete();
@ -1325,116 +1380,6 @@ bool LabelEntry::containsLabel(const StringAtom *label)
return false;
}
void ICodeGenerator::preprocess(StmtNode *p)
{
switch (p->getKind()) {
case StmtNode::block:
{
BlockStmtNode *b = static_cast<BlockStmtNode *>(p);
StmtNode *s = b->statements;
while (s) {
preprocess(s);
s = s->next;
}
}
break;
case StmtNode::Var:
{
VariableStmtNode *vs = static_cast<VariableStmtNode *>(p);
VariableBinding *v = vs->bindings;
while (v) {
if (v->name && (v->name->getKind() == ExprNode::identifier))
if (v->type && (v->type->getKind() == ExprNode::identifier))
if (isTopLevel())
mGlobal->defineVariable((static_cast<IdentifierExprNode *>(v->name))->name,
findType((static_cast<IdentifierExprNode *>(v->type))->name));
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name,
(static_cast<IdentifierExprNode *>(v->type))->name);
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
}
break;
case StmtNode::DoWhile:
{
UnaryStmtNode *d = static_cast<UnaryStmtNode *>(p);
preprocess(d->stmt);
}
break;
case StmtNode::While:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
preprocess(w->stmt);
}
break;
case StmtNode::For:
{
ForStmtNode *f = static_cast<ForStmtNode *>(p);
if (f->initializer)
preprocess(f->initializer);
preprocess(f->stmt);
}
break;
case StmtNode::If:
{
UnaryStmtNode *i = static_cast<UnaryStmtNode *>(p);
preprocess(i->stmt);
}
break;
case StmtNode::IfElse:
{
BinaryStmtNode *i = static_cast<BinaryStmtNode *>(p);
preprocess(i->stmt);
preprocess(i->stmt2);
}
break;
case StmtNode::With:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
preprocess(w->stmt);
}
break;
case StmtNode::Switch:
{
SwitchStmtNode *sw = static_cast<SwitchStmtNode *>(p);
StmtNode *s = sw->statements;
while (s) {
if (s->getKind() != StmtNode::Case)
preprocess(s);
s = s->next;
}
}
break;
case StmtNode::label:
{
LabelStmtNode *l = static_cast<LabelStmtNode *>(p);
preprocess(l->stmt);
}
break;
case StmtNode::Try:
{
TryStmtNode *t = static_cast<TryStmtNode *>(p);
genStmt(t->stmt);
if (t->catches) {
CatchClause *c = t->catches;
while (c) {
preprocess(c->stmt);
c = c->next;
}
}
if (t->finally)
genStmt(t->finally);
}
break;
default:
break;
}
}
static bool hasAttribute(const IdentifierList* identifiers, Token::Kind tokenKind)
{
while (identifiers) {
@ -1458,7 +1403,6 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f)
icg.allocateParameter((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
icg.preprocess(f->function.body);
icg.genStmt(f->function.body);
return icg.complete();
@ -1469,8 +1413,8 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
TypedRegister ret(NotARegister, &None_Type);
startStatement(p->pos);
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
if (mExceptionRegister.first == NotARegister) {
mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
switch (p->getKind()) {
@ -1565,7 +1509,7 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
// freeze the class.
thisClass->complete();
if (ccg.getICode()->size())
thisClass->setConstructor(ccg.complete());
thisClass->setInitializer(ccg.complete());
// REVISIT: using the scope of the class to store both methods and statics.
if (scg.getICode()->size()) {
Interpreter::Context cx(*mWorld, thisScope);
@ -1591,8 +1535,18 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
VariableStmtNode *vs = static_cast<VariableStmtNode *>(p);
VariableBinding *v = vs->bindings;
while (v) {
if (v->name && v->initializer) {
if (v->name->getKind() == ExprNode::identifier) {
if (v->name && (v->name->getKind() == ExprNode::identifier)) {
if (v->type && (v->type->getKind() == ExprNode::identifier)) {
if (isTopLevel())
mGlobal->defineVariable((static_cast<IdentifierExprNode *>(v->name))->name,
findType((static_cast<IdentifierExprNode *>(v->type))->name));
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name,
(static_cast<IdentifierExprNode *>(v->type))->name);
}
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
if (v->initializer) {
if (!isTopLevel() && !isWithinWith()) {
TypedRegister r = genExpr(v->name);
TypedRegister val = genExpr(v->initializer);
@ -1603,7 +1557,6 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
saveName((static_cast<IdentifierExprNode *>(v->name))->name, val);
}
}
// XXX what's the else case here, when does a VariableBinding NOT have an identifier child?
}
v = v->next;
}
@ -1889,19 +1842,19 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
CatchClause *c = t->catches;
while (c) {
// Bind the incoming exception ...
setRegisterForVariable(c->name, exceptionRegister);
setRegisterForVariable(c->name, mExceptionRegister);
genStmt(c->stmt);
if (finallyLabel)
jsr(finallyLabel);
throwStmt(exceptionRegister);
throwStmt(mExceptionRegister);
c = c->next;
}
}
if (finallyLabel) {
setLabel(finallyInvoker);
jsr(finallyLabel);
throwStmt(exceptionRegister);
throwStmt(mExceptionRegister);
setLabel(finallyLabel);
genStmt(t->finally);

View File

@ -118,69 +118,70 @@ namespace ICG {
bool iCodeOwner;
LabelList labels;
Register topRegister; // highest (currently) alloacated register
Register registerBase; // start of registers available for expression temps
uint32 maxRegister; // highest (ever) allocated register
uint32 parameterCount; // number of parameters declared for the function
// these must come before any variables declared.
TypedRegister exceptionRegister;// reserved to carry the exception object.
VariableList *variableList; // name|register pair for each variable
Register mTopRegister; // highest (currently) alloacated register
uint32 mParameterCount; // number of parameters declared for the function
// these must come before any variables declared.
TypedRegister mExceptionRegister; // reserved to carry the exception object.
VariableList *variableList; // name|register pair for each variable
World *mWorld; // used to register strings
JSScope *mGlobal; // the scope for compiling within
LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct
// maps source position to instruction index
World *mWorld; // used to register strings
JSScope *mGlobal; // the scope for compiling within
LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct
// maps source position to instruction index
InstructionMap *mInstructionMap;
JSClass *mClass; // enclosing class when generating code for methods
ICodeGeneratorFlags mFlags; // assorted flags
JSClass *mClass; // enclosing class when generating code for methods
ICodeGeneratorFlags mFlags; // assorted flags
std::vector<bool> mPermanentRegister;
Register getTempRegister()
{
while (mTopRegister < mPermanentRegister.size())
if (!mPermanentRegister[mTopRegister])
return mTopRegister++;
else
++mTopRegister;
mPermanentRegister.resize(mTopRegister + 1);
mPermanentRegister[mTopRegister] = false;
return mTopRegister++;
}
void resetTopRegister() { mTopRegister = mParameterCount; }
void resetStatement() { resetTopRegister(); }
TypedRegister allocateRegister(const StringAtom& name, JSType *type);
void setRegisterForVariable(const StringAtom& name, TypedRegister r) { (*variableList)[name] = r; }
JSType *findType(const StringAtom& typeName);
void markMaxRegister()
{ if (topRegister > maxRegister) maxRegister = topRegister; }
Register getRegister()
{ return topRegister++; }
void resetTopRegister()
{ markMaxRegister(); topRegister = registerBase; }
void setLabel(Label *label);
void jsr(Label *label) { iCode->push_back(new Jsr(label)); }
void rts() { iCode->push_back(new Rts()); }
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, 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()); }
{ iCode->push_back(new Tryin(catchLabel, finallyLabel)); }
void endTry() { iCode->push_back(new Tryout()); }
void beginWith(TypedRegister obj)
{ iCode->push_back(new Within(obj)); }
void endWith()
{ iCode->push_back(new Without()); }
void beginWith(TypedRegister obj) { iCode->push_back(new Within(obj)); }
void endWith() { iCode->push_back(new Without()); }
void resetStatement() { resetTopRegister(); }
void setRegisterForVariable(const StringAtom& name, TypedRegister r)
{ (*variableList)[name] = r; }
void startStatement(uint32 pos)
{ (*mInstructionMap)[iCode->size()] = pos; }
void startStatement(uint32 pos) { (*mInstructionMap)[iCode->size()] = pos; }
ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind);
TypedRegister grabRegister(const StringAtom& name, JSType *type)
{
TypedRegister result(getRegister(), type);
(*variableList)[name] = result;
registerBase = topRegister;
return result;
}
bool isTopLevel() { return (mFlags & kIsTopLevel) != 0; }
bool isWithinWith() { return (mFlags & kIsWithinWith) != 0; }
@ -188,7 +189,11 @@ namespace ICG {
void setFlag(uint32 flag, bool v) { mFlags = (ICodeGeneratorFlags)((v) ? mFlags | flag : mFlags & ~flag); }
JSType *findType(const StringAtom& typeName);
typedef enum {Var, Property, Slot, Static, Name} LValueKind;
LValueKind resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex);
TypedRegister handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args);
TypedRegister handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args);
ICodeModule *genFunction(FunctionStmtNode *f);
@ -207,32 +212,30 @@ namespace ICG {
ICodeModule *complete();
TypedRegister genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
void preprocess(StmtNode *p);
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
TypedRegister genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL);
void returnStmt(TypedRegister r);
void returnStmt();
void throwStmt(TypedRegister r)
{ iCode->push_back(new Throw(r)); }
void debuggerStmt()
{ iCode->push_back(new Debugger()); }
void throwStmt(TypedRegister r) { iCode->push_back(new Throw(r)); }
void debuggerStmt() { iCode->push_back(new Debugger()); }
TypedRegister allocateVariable(const StringAtom& name);
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName);
TypedRegister findVariable(const StringAtom& name)
{ VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; }
{
VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second;
}
TypedRegister allocateParameter(const StringAtom& name)
{ parameterCount++; return grabRegister(name, &Any_Type); }
TypedRegister allocateParameter(const StringAtom& name) { mParameterCount++; return allocateRegister(name, &Any_Type); }
TypedRegister allocateParameter(const StringAtom& name, const StringAtom& typeName)
{ parameterCount++; return grabRegister(name, findType(typeName)); }
{ mParameterCount++; return allocateRegister(name, findType(typeName)); }
TypedRegister allocateParameter(const StringAtom& name, JSType *type)
{ parameterCount++; return grabRegister(name, type); }
{ mParameterCount++; return allocateRegister(name, type); }
Formatter& print(Formatter& f);
@ -279,8 +282,7 @@ namespace ICG {
TypedRegister varXcr(TypedRegister var, ICodeOp op);
Register getRegisterBase() { return topRegister; }
InstructionStream *getICode() { return iCode; }
InstructionStream *getICode() { return iCode; }
Label *getLabel();

View File

@ -679,14 +679,14 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
InstructionIterator nextPC = ++mPC;
do {
// call the constructor(s), if any.
ICodeModule* ctor = thisClass->getConstructor();
if (ctor) {
ICodeModule* init = thisClass->getInitializer();
if (init) {
mLinkage = new Linkage(mLinkage, nextPC,
mActivation, mGlobal, voidRegister);
mActivation = new Activation(ctor, args);
mActivation = new Activation(init, args);
registers = &mActivation->mRegisters;
nextPC = ctor->its_iCode->begin();
endPC = ctor->its_iCode->end();
nextPC = init->its_iCode->begin();
endPC = init->its_iCode->end();
}
thisClass = thisClass->getSuperClass();
} while (thisClass);

View File

@ -147,7 +147,6 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName)
TypedRegister ret(NotARegister, &None_Type);
while (p) {
icg.preprocess(p);
ret = icg.genStmt(p);
p = p->next;
}
@ -155,7 +154,7 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName)
ICodeModule *icm = icg.complete();
//stdOut << icg;
stdOut << icg;
icm->setFileName (fileName);
return icm;
@ -344,7 +343,8 @@ 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;"
"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;"
};
static void testCompile()
@ -361,15 +361,11 @@ static void testCompile()
StmtNode *parsedStatements = p.parseProgram();
ICodeGenerator icg(&world, &glob);
StmtNode *s = parsedStatements;
while (s) {
icg.preprocess(s);
s = s->next;
}
s = parsedStatements;
while (s) {
icg.genStmt(s);
s = s->next;
}
// stdOut << icg;
cx.interpret(icg.complete(), JSValues());
}
}

View File

@ -79,7 +79,7 @@ namespace JSClasses {
uint32 mStaticCount;
JSSlots mStaticSlots;
JSValue* mStaticData;
ICodeModule* mConstructor;
ICodeModule* mInitializer;
// typedef std::vector<ICodeModule*, gc_allocator<ICodeModule*> > JSMethods;
// JSMethods mMethods;
public:
@ -89,7 +89,7 @@ namespace JSClasses {
mSlotCount(superClass ? superClass->mSlotCount : 0),
mStaticCount(0),
mStaticData(0),
mConstructor(0)
mInitializer(0)
{
// to "inherit" superClass methods.
if (superClass)
@ -106,14 +106,14 @@ namespace JSClasses {
return mScope;
}
void setConstructor(ICodeModule* ctor)
void setInitializer(ICodeModule* init)
{
mConstructor = ctor;
mInitializer = init;
}
ICodeModule* getConstructor()
ICodeModule* getInitializer()
{
return mConstructor;
return mInitializer;
}
const JSSlot& defineSlot(const String& name, JSType* type)

View File

@ -175,6 +175,10 @@ SOURCE=..\hash.h
# End Source File
# Begin Source File
SOURCE=..\icode.h
# End Source File
# Begin Source File
SOURCE=..\icodegenerator.h
# End Source File
# Begin Source File

View File

@ -66,11 +66,9 @@ Formatter& operator<<(Formatter &f, ICodeModule &i)
ICodeGenerator::ICodeGenerator(World *world, JSScope *global, JSClass *aClass, ICodeGeneratorFlags flags)
: topRegister(0),
registerBase(0),
maxRegister(0),
parameterCount(0),
exceptionRegister(TypedRegister(NotARegister, &None_Type)),
: mTopRegister(0),
mParameterCount(0),
mExceptionRegister(TypedRegister(NotARegister, &None_Type)),
variableList(new VariableList()),
mWorld(world),
mGlobal(global),
@ -90,20 +88,39 @@ JSType *ICodeGenerator::findType(const StringAtom& typeName)
return &Any_Type;
}
TypedRegister ICodeGenerator::allocateRegister(const StringAtom& name, JSType *type)
{
Register r = mTopRegister;
while (r < mPermanentRegister.size())
if (!mPermanentRegister[r])
break;
else
++r;
if (r == mPermanentRegister.size())
mPermanentRegister.resize(r + 1);
mPermanentRegister[r] = true;
TypedRegister result(r, type);
(*variableList)[name] = result;
mTopRegister = ++r;
return result;
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name, const StringAtom& typeName)
{
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
if (mExceptionRegister.first == NotARegister) {
mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name, findType(typeName));
return allocateRegister(name, findType(typeName));
}
TypedRegister ICodeGenerator::allocateVariable(const StringAtom& name)
{
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
if (mExceptionRegister.first == NotARegister) {
mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
return grabRegister(name, &Any_Type);
return allocateRegister(name, &Any_Type);
}
ICodeModule *ICodeGenerator::complete()
@ -149,8 +166,7 @@ ICodeModule *ICodeGenerator::complete()
}
}
*/
markMaxRegister();
ICodeModule* module = new ICodeModule(iCode, variableList, maxRegister, 0, mInstructionMap);
ICodeModule* module = new ICodeModule(iCode, variableList, mPermanentRegister.size(), 0, mInstructionMap);
iCodeOwner = false; // give ownership to the module.
return module;
}
@ -160,7 +176,7 @@ ICodeModule *ICodeGenerator::complete()
TypedRegister ICodeGenerator::loadImmediate(double value)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
LoadImmediate *instr = new LoadImmediate(dest, value);
iCode->push_back(instr);
return dest;
@ -168,7 +184,7 @@ TypedRegister ICodeGenerator::loadImmediate(double value)
TypedRegister ICodeGenerator::loadString(String &value)
{
TypedRegister dest(getRegister(), &String_Type);
TypedRegister dest(getTempRegister(), &String_Type);
LoadString *instr = new LoadString(dest, new JSString(value));
iCode->push_back(instr);
return dest;
@ -176,7 +192,7 @@ TypedRegister ICodeGenerator::loadString(String &value)
TypedRegister ICodeGenerator::loadString(const StringAtom &value)
{
TypedRegister dest(getRegister(), &String_Type);
TypedRegister dest(getTempRegister(), &String_Type);
LoadString *instr = new LoadString(dest, new JSString(value));
iCode->push_back(instr);
return dest;
@ -184,7 +200,7 @@ TypedRegister ICodeGenerator::loadString(const StringAtom &value)
TypedRegister ICodeGenerator::loadBoolean(bool value)
{
TypedRegister dest(getRegister(), &Boolean_Type);
TypedRegister dest(getTempRegister(), &Boolean_Type);
LoadBoolean *instr = new LoadBoolean(dest, value);
iCode->push_back(instr);
return dest;
@ -192,7 +208,7 @@ TypedRegister ICodeGenerator::loadBoolean(bool value)
TypedRegister ICodeGenerator::newObject()
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
NewObject *instr = new NewObject(dest);
iCode->push_back(instr);
return dest;
@ -200,7 +216,7 @@ TypedRegister ICodeGenerator::newObject()
TypedRegister ICodeGenerator::newClass(const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
NewClass *instr = new NewClass(dest, &name);
iCode->push_back(instr);
return dest;
@ -208,7 +224,7 @@ TypedRegister ICodeGenerator::newClass(const StringAtom &name)
TypedRegister ICodeGenerator::newFunction(ICodeModule *icm)
{
TypedRegister dest(getRegister(), &Function_Type);
TypedRegister dest(getTempRegister(), &Function_Type);
NewFunction *instr = new NewFunction(dest, icm);
iCode->push_back(instr);
return dest;
@ -216,7 +232,7 @@ TypedRegister ICodeGenerator::newFunction(ICodeModule *icm)
TypedRegister ICodeGenerator::newArray()
{
TypedRegister dest(getRegister(), &Array_Type);
TypedRegister dest(getTempRegister(), &Array_Type);
NewArray *instr = new NewArray(dest);
iCode->push_back(instr);
return dest;
@ -226,7 +242,7 @@ TypedRegister ICodeGenerator::newArray()
TypedRegister ICodeGenerator::loadName(const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
LoadName *instr = new LoadName(dest, &name);
iCode->push_back(instr);
return dest;
@ -240,7 +256,7 @@ void ICodeGenerator::saveName(const StringAtom &name, TypedRegister value)
TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
NameXcr *instr = new NameXcr(dest, &name, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -250,7 +266,7 @@ TypedRegister ICodeGenerator::nameXcr(const StringAtom &name, ICodeOp op)
TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
VarXcr *instr = new VarXcr(dest, var, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -261,7 +277,7 @@ TypedRegister ICodeGenerator::varXcr(TypedRegister var, ICodeOp op)
TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
DeleteProp *instr = new DeleteProp(dest, base, &name);
iCode->push_back(instr);
return dest;
@ -269,7 +285,7 @@ TypedRegister ICodeGenerator::deleteProperty(TypedRegister base, const StringAto
TypedRegister ICodeGenerator::getProperty(TypedRegister base, const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
GetProp *instr = new GetProp(dest, base, &name);
iCode->push_back(instr);
return dest;
@ -284,7 +300,7 @@ void ICodeGenerator::setProperty(TypedRegister base, const StringAtom &name,
TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom &name, ICodeOp op)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
PropXcr *instr = new PropXcr(dest, base, &name, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -296,7 +312,7 @@ TypedRegister ICodeGenerator::propertyXcr(TypedRegister base, const StringAtom &
TypedRegister ICodeGenerator::getStatic(JSClass *base, const StringAtom &name)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
const JSSlot& slot = base->getStatic(name);
GetStatic *instr = new GetStatic(dest, base, slot.mIndex);
iCode->push_back(instr);
@ -313,7 +329,7 @@ void ICodeGenerator::setStatic(JSClass *base, const StringAtom &name,
TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, ICodeOp op)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
const JSSlot& slot = base->getStatic(name);
StaticXcr *instr = new StaticXcr(dest, base, slot.mIndex, 1.0);
iCode->push_back(instr);
@ -325,7 +341,7 @@ TypedRegister ICodeGenerator::staticXcr(JSClass *base, const StringAtom &name, I
TypedRegister ICodeGenerator::getSlot(TypedRegister base, uint32 slot)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
GetSlot *instr = new GetSlot(dest, base, slot);
iCode->push_back(instr);
return dest;
@ -340,7 +356,7 @@ void ICodeGenerator::setSlot(TypedRegister base, uint32 slot,
TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp op)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
SlotXcr *instr = new SlotXcr(dest, base, slot, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -351,7 +367,7 @@ TypedRegister ICodeGenerator::slotXcr(TypedRegister base, uint32 slot, ICodeOp o
TypedRegister ICodeGenerator::getElement(TypedRegister base, TypedRegister index)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
GetElement *instr = new GetElement(dest, base, index);
iCode->push_back(instr);
return dest;
@ -366,7 +382,7 @@ void ICodeGenerator::setElement(TypedRegister base, TypedRegister index,
TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index, ICodeOp op)
{
TypedRegister dest(getRegister(), &Number_Type);
TypedRegister dest(getTempRegister(), &Number_Type);
ElemXcr *instr = new ElemXcr(dest, base, index, (op == ADD) ? 1.0 : -1.0);
iCode->push_back(instr);
return dest;
@ -376,7 +392,7 @@ TypedRegister ICodeGenerator::elementXcr(TypedRegister base, TypedRegister index
TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
ASSERT(source.first != NotARegister);
Unary *instr = new Unary (op, dest, source);
iCode->push_back(instr);
@ -394,7 +410,7 @@ void ICodeGenerator::move(TypedRegister destination, TypedRegister source)
TypedRegister ICodeGenerator::logicalNot(TypedRegister source)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Not *instr = new Not(dest, source);
iCode->push_back(instr);
return dest;
@ -402,7 +418,7 @@ TypedRegister ICodeGenerator::logicalNot(TypedRegister source)
TypedRegister ICodeGenerator::test(TypedRegister source)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Test *instr = new Test(dest, source);
iCode->push_back(instr);
return dest;
@ -413,7 +429,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1,
{
ASSERT(source1.first != NotARegister);
ASSERT(source2.first != NotARegister);
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Arithmetic *instr = new Arithmetic(op, dest, source1, source2);
iCode->push_back(instr);
return dest;
@ -421,7 +437,7 @@ TypedRegister ICodeGenerator::op(ICodeOp op, TypedRegister source1,
TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name, RegisterList args)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
Call *instr = new Call(dest, target, &name, args);
iCode->push_back(instr);
return dest;
@ -429,7 +445,7 @@ TypedRegister ICodeGenerator::call(TypedRegister target, const StringAtom &name,
TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister targetValue, RegisterList args)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
MethodCall *instr = new MethodCall(dest, targetBase, targetValue, args);
iCode->push_back(instr);
return dest;
@ -437,7 +453,7 @@ TypedRegister ICodeGenerator::methodCall(TypedRegister targetBase, TypedRegister
TypedRegister ICodeGenerator::staticCall(JSClass *c, const StringAtom &name, RegisterList args)
{
TypedRegister dest(getRegister(), &Any_Type);
TypedRegister dest(getTempRegister(), &Any_Type);
const JSSlot& slot = c->getStatic(name);
StaticCall *instr = new StaticCall(dest, c, slot.mIndex, args);
iCode->push_back(instr);
@ -618,46 +634,161 @@ static bool isSlotName(JSType *t, const StringAtom &name, uint32 &slotIndex, JST
return false;
}
TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args)
ICodeGenerator::LValueKind ICodeGenerator::resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex)
{
enum {Property, Slot, Static} lValueKind;
if (!isWithinWith()) {
v = findVariable(name);
if (v.first != NotARegister)
return Var;
else {
if (mClass) { // we're compiling a method of a class
if (!isStaticMethod()) {
if (isSlotName(mClass, name, slotIndex, v.second))
return Slot;
}
if (mClass->hasStatic(name, v.second)) {
return Static;
}
}
v.second = mGlobal->getType(name);
return Name;
}
}
v.second = &Any_Type;
return Name;
}
TypedRegister ICodeGenerator::handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args)
{
ASSERT(p->getKind() == ExprNode::identifier);
JSType *vType = &Any_Type;
uint32 slotIndex;
TypedRegister ret;
TypedRegister v;
const StringAtom &name = (static_cast<IdentifierExprNode *>(p))->name;
LValueKind lValueKind = resolveIdentifier(name, ret, slotIndex);
TypedRegister thisBase = TypedRegister(0, mClass ? mClass : &Any_Type);
switch (use) {
case ExprNode::identifier:
switch (lValueKind) {
case Var:
break;
case Name:
ret = loadName(name);
break;
case Slot:
ret = getSlot(thisBase, slotIndex);
break;
case Static:
ret = getStatic(mClass, name);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
case ExprNode::preDecrement:
case ExprNode::preIncrement:
switch (lValueKind) {
case Var:
ret = op(xcrementOp, ret, loadImmediate(1.0));
break;
case Name:
ret = loadName(name);
ret = op(xcrementOp, ret, loadImmediate(1.0));
saveName(name, ret);
break;
case Slot:
ret = op(xcrementOp, getSlot(thisBase, slotIndex), loadImmediate(1.0));
setSlot(thisBase, slotIndex, ret);
break;
case Static:
ret = op(xcrementOp, getStatic(mClass, name), loadImmediate(1.0));
setStatic(mClass, name, ret);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
case ExprNode::postDecrement:
case ExprNode::postIncrement:
switch (lValueKind) {
case Var:
ret = varXcr(ret, xcrementOp);
break;
case Name:
ret = nameXcr(name, xcrementOp);
break;
case Slot:
ret = slotXcr(thisBase, slotIndex, xcrementOp);
break;
case Static:
ret = staticXcr(mClass, name, xcrementOp);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
case ExprNode::call:
switch (lValueKind) {
case Var:
ret = call(ret, name, *args);
break;
case Name:
ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(name), *args);
break;
case Static:
ret = staticCall(mClass, name, *args);
break;
default:
NOT_REACHED("Bad lvalue kind");
}
break;
}
return ret;
}
TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args)
{
ASSERT(b->getKind() == ExprNode::dot);
LValueKind lValueKind;
if (b->op2->getKind() != ExprNode::identifier) {
NOT_REACHED("Implement me"); // turns into a getProperty (but not via any overloaded [] )
}
else {
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
const StringAtom &fieldName = static_cast<IdentifierExprNode *>(b->op2)->name;
TypedRegister base;
JSClass *c = NULL;
JSClass *clazz = NULL;
JSType *fieldType = &Any_Type;
uint32 slotIndex;
if ((b->op1->getKind() == ExprNode::identifier) && !isWithinWith()) {
const StringAtom &baseName = (static_cast<IdentifierExprNode *>(b->op1))->name;
JSType *baseType = &Any_Type;
base = findVariable(baseName);
if (base.first != NotARegister)
baseType = base.second;
else {
// implicit 'this' has a big impact here
baseType = mGlobal->getType(baseName);
}
resolveIdentifier(baseName, base, slotIndex);
lValueKind = Property;
if (baseType == &Type_Type) {
//
// handle <class name>.<static field>
//
if (base.second == &Type_Type) {
const JSValue &v = mGlobal->getVariable(baseName);
c = dynamic_cast<JSClass*>(v.type);
if (c && c->hasStatic(name, fieldType)) {
clazz = dynamic_cast<JSClass*>(v.type);
if (clazz && clazz->hasStatic(fieldName, fieldType)) {
lValueKind = Static;
}
}
if (lValueKind == Property) {
if (isSlotName(baseType, name, slotIndex, fieldType))
if (isSlotName(base.second, fieldName, slotIndex, fieldType))
lValueKind = Slot;
else {
c = dynamic_cast<JSClass*>(baseType);
if (c && c->hasStatic(name, fieldType))
clazz = dynamic_cast<JSClass*>(base.second);
if (clazz && clazz->hasStatic(fieldName, fieldType))
lValueKind = Static;
else
lValueKind = Property;
@ -668,11 +799,11 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
}
else {
base = genExpr(b->op1);
if (isSlotName(base.second, name, slotIndex, fieldType))
if (isSlotName(base.second, fieldName, slotIndex, fieldType))
lValueKind = Slot;
else {
c = dynamic_cast<JSClass*>(base.second);
if (c && c->hasStatic(name, fieldType))
clazz = dynamic_cast<JSClass*>(base.second);
if (clazz && clazz->hasStatic(fieldName, fieldType))
lValueKind = Static;
else
lValueKind = Property;
@ -683,10 +814,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::call:
switch (lValueKind) {
case Static:
ret = staticCall(c, name, *args);
ret = staticCall(clazz, fieldName, *args);
break;
case Property:
ret = methodCall(base, loadString(name), *args);
ret = methodCall(base, loadString(fieldName), *args);
break;
default:
NOT_REACHED("Bad lvalue kind");
@ -706,10 +837,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::bitwiseOrEquals:
switch (lValueKind) {
case Static:
v = getStatic(c, name);
v = getStatic(clazz, fieldName);
break;
case Property:
v = getProperty(base, name);
v = getProperty(base, fieldName);
break;
case Slot:
v = getSlot(base, slotIndex);
@ -726,10 +857,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::assignment:
switch (lValueKind) {
case Static:
setStatic(c, name, ret);
setStatic(clazz, fieldName, ret);
break;
case Property:
setProperty(base, name, ret);
setProperty(base, fieldName, ret);
break;
case Slot:
setSlot(base, slotIndex, ret);
@ -742,10 +873,10 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::postIncrement:
switch (lValueKind) {
case Static:
ret = staticXcr(c, name, xcrementOp);
ret = staticXcr(clazz, fieldName, xcrementOp);
break;
case Property:
ret = propertyXcr(base, name, xcrementOp);
ret = propertyXcr(base, fieldName, xcrementOp);
break;
case Slot:
ret = slotXcr(base, slotIndex, xcrementOp);
@ -757,12 +888,12 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
case ExprNode::preIncrement:
switch (lValueKind) {
case Static:
ret = op(xcrementOp, getStatic(c, name), loadImmediate(1.0));
setStatic(c, name, ret);
ret = op(xcrementOp, getStatic(clazz, fieldName), loadImmediate(1.0));
setStatic(clazz, fieldName, ret);
break;
case Property:
ret = op(xcrementOp, getProperty(base, name), loadImmediate(1.0));
setProperty(base, name, ret);
ret = op(xcrementOp, getProperty(base, fieldName), loadImmediate(1.0));
setProperty(base, fieldName, ret);
break;
case Slot:
ret = op(xcrementOp, getSlot(base, slotIndex), loadImmediate(1.0));
@ -774,7 +905,7 @@ TypedRegister ICodeGenerator::handleDot(BinaryExprNode *b, ExprNode::Kind use, I
break;
case ExprNode::Delete:
if (lValueKind == Property) {
ret = deleteProperty(base, name);
ret = deleteProperty(base, fieldName);
}
break;
default:
@ -857,34 +988,10 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
if (i->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(i->op);
ret = handleDot(b, ExprNode::call, xcrementOp, ret, &args);
/*
TypedRegister base = genExpr(b->op1);
// might be Class.<method>()
const StringAtom &name = static_cast<IdentifierExprNode *>(b->op2)->name;
if ((base.second == &Type_Type)
&& (b->op1->getKind() == ExprNode::identifier)) {
const StringAtom &className = (static_cast<IdentifierExprNode *>(b->op1))->name;
const JSValue &v = mGlobal->getVariable(className);
JSClass* c = dynamic_cast<JSClass*>(v.type);
if (c && c->hasStatic(name)) {
ret = staticCall(c, name, args);
break;
}
}
ret = methodCall(base, loadString(name), args);
*/
}
else
if (i->op->getKind() == ExprNode::identifier) {
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(i->op))->name);
if (v.first != NotARegister)
ret = call(v, static_cast<IdentifierExprNode *>(i->op)->name, args);
else
ret = call(TypedRegister(NotARegister, &Null_Type), static_cast<IdentifierExprNode *>(i->op)->name, args);
}
else
ret = methodCall(TypedRegister(NotARegister, &Null_Type), loadString(static_cast<IdentifierExprNode *>(i->op)->name), args);
ret = handleIdentifier(static_cast<IdentifierExprNode *>(i->op), ExprNode::call, xcrementOp, &args);
}
else
if (i->op->getKind() == ExprNode::index) {
@ -916,34 +1023,7 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
break;
case ExprNode::identifier :
{
const StringAtom &name = (static_cast<IdentifierExprNode *>(p))->name;
if (!isWithinWith()) {
TypedRegister v = findVariable(name);
if (v.first != NotARegister)
ret = v;
else {
if (mClass) { // we're compiling a method of a class
JSType *fieldType;
if (!isStaticMethod()) {
uint32 slotIndex;
if (isSlotName(mClass, name, slotIndex, fieldType)) {
ret = getSlot(TypedRegister(0, mClass), slotIndex);
ret.second = fieldType;
break;
}
}
if (mClass->hasStatic(name, fieldType)) {
ret = getStatic(mClass, name);
ret.second = fieldType;
break;
}
}
ret = loadName(name);
ret.second = mGlobal->getType(name);
}
}
else
ret = loadName(name);
ret = handleIdentifier(static_cast<IdentifierExprNode *>(p), ExprNode::identifier, xcrementOp, NULL);
}
break;
case ExprNode::number :
@ -958,26 +1038,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL);
ret = handleDot(static_cast<BinaryExprNode *>(u->op), p->getKind(), xcrementOp, ret, NULL);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = op(xcrementOp, ret, loadImmediate(1.0));
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
ret = op(xcrementOp, ret, loadImmediate(1.0));
saveName((static_cast<IdentifierExprNode *>(u->op))->name, ret);
}
}
else {
ret = loadName((static_cast<IdentifierExprNode *>(u->op))->name);
ret = op(xcrementOp, ret, loadImmediate(1.0));
saveName((static_cast<IdentifierExprNode *>(u->op))->name, ret);
}
ret = handleIdentifier(static_cast<IdentifierExprNode *>(u->op), p->getKind(), xcrementOp, NULL);
}
else
if (u->op->getKind() == ExprNode::index) {
@ -998,20 +1063,11 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
{
UnaryExprNode *u = static_cast<UnaryExprNode *>(p);
if (u->op->getKind() == ExprNode::dot) {
BinaryExprNode *b = static_cast<BinaryExprNode *>(u->op);
ret = handleDot(b, p->getKind(), xcrementOp, ret, NULL);
ret = handleDot(static_cast<BinaryExprNode *>(u->op), p->getKind(), xcrementOp, ret, NULL);
}
else
if (u->op->getKind() == ExprNode::identifier) {
if (!isWithinWith()) {
TypedRegister v = findVariable((static_cast<IdentifierExprNode *>(u->op))->name);
if (v.first != NotARegister)
ret = varXcr(v, xcrementOp);
else
ret = nameXcr((static_cast<IdentifierExprNode *>(u->op))->name, xcrementOp);
}
else
ret = nameXcr((static_cast<IdentifierExprNode *>(u->op))->name, xcrementOp);
ret = handleIdentifier(static_cast<IdentifierExprNode *>(u->op), p->getKind(), xcrementOp, NULL);
}
else
if (u->op->getKind() == ExprNode::index) {
@ -1291,7 +1347,6 @@ TypedRegister ICodeGenerator::genExpr(ExprNode *p,
icg.allocateParameter((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
icg.preprocess(f->function.body);
icg.genStmt(f->function.body);
//stdOut << icg;
ICodeModule *icm = icg.complete();
@ -1325,116 +1380,6 @@ bool LabelEntry::containsLabel(const StringAtom *label)
return false;
}
void ICodeGenerator::preprocess(StmtNode *p)
{
switch (p->getKind()) {
case StmtNode::block:
{
BlockStmtNode *b = static_cast<BlockStmtNode *>(p);
StmtNode *s = b->statements;
while (s) {
preprocess(s);
s = s->next;
}
}
break;
case StmtNode::Var:
{
VariableStmtNode *vs = static_cast<VariableStmtNode *>(p);
VariableBinding *v = vs->bindings;
while (v) {
if (v->name && (v->name->getKind() == ExprNode::identifier))
if (v->type && (v->type->getKind() == ExprNode::identifier))
if (isTopLevel())
mGlobal->defineVariable((static_cast<IdentifierExprNode *>(v->name))->name,
findType((static_cast<IdentifierExprNode *>(v->type))->name));
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name,
(static_cast<IdentifierExprNode *>(v->type))->name);
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
}
break;
case StmtNode::DoWhile:
{
UnaryStmtNode *d = static_cast<UnaryStmtNode *>(p);
preprocess(d->stmt);
}
break;
case StmtNode::While:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
preprocess(w->stmt);
}
break;
case StmtNode::For:
{
ForStmtNode *f = static_cast<ForStmtNode *>(p);
if (f->initializer)
preprocess(f->initializer);
preprocess(f->stmt);
}
break;
case StmtNode::If:
{
UnaryStmtNode *i = static_cast<UnaryStmtNode *>(p);
preprocess(i->stmt);
}
break;
case StmtNode::IfElse:
{
BinaryStmtNode *i = static_cast<BinaryStmtNode *>(p);
preprocess(i->stmt);
preprocess(i->stmt2);
}
break;
case StmtNode::With:
{
UnaryStmtNode *w = static_cast<UnaryStmtNode *>(p);
preprocess(w->stmt);
}
break;
case StmtNode::Switch:
{
SwitchStmtNode *sw = static_cast<SwitchStmtNode *>(p);
StmtNode *s = sw->statements;
while (s) {
if (s->getKind() != StmtNode::Case)
preprocess(s);
s = s->next;
}
}
break;
case StmtNode::label:
{
LabelStmtNode *l = static_cast<LabelStmtNode *>(p);
preprocess(l->stmt);
}
break;
case StmtNode::Try:
{
TryStmtNode *t = static_cast<TryStmtNode *>(p);
genStmt(t->stmt);
if (t->catches) {
CatchClause *c = t->catches;
while (c) {
preprocess(c->stmt);
c = c->next;
}
}
if (t->finally)
genStmt(t->finally);
}
break;
default:
break;
}
}
static bool hasAttribute(const IdentifierList* identifiers, Token::Kind tokenKind)
{
while (identifiers) {
@ -1458,7 +1403,6 @@ ICodeModule *ICodeGenerator::genFunction(FunctionStmtNode *f)
icg.allocateParameter((static_cast<IdentifierExprNode *>(v->name))->name);
v = v->next;
}
icg.preprocess(f->function.body);
icg.genStmt(f->function.body);
return icg.complete();
@ -1469,8 +1413,8 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
TypedRegister ret(NotARegister, &None_Type);
startStatement(p->pos);
if (exceptionRegister.first == NotARegister) {
exceptionRegister = grabRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
if (mExceptionRegister.first == NotARegister) {
mExceptionRegister = allocateRegister(mWorld->identifiers[widenCString("__exceptionObject__")], &Any_Type);
}
switch (p->getKind()) {
@ -1565,7 +1509,7 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
// freeze the class.
thisClass->complete();
if (ccg.getICode()->size())
thisClass->setConstructor(ccg.complete());
thisClass->setInitializer(ccg.complete());
// REVISIT: using the scope of the class to store both methods and statics.
if (scg.getICode()->size()) {
Interpreter::Context cx(*mWorld, thisScope);
@ -1591,8 +1535,18 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
VariableStmtNode *vs = static_cast<VariableStmtNode *>(p);
VariableBinding *v = vs->bindings;
while (v) {
if (v->name && v->initializer) {
if (v->name->getKind() == ExprNode::identifier) {
if (v->name && (v->name->getKind() == ExprNode::identifier)) {
if (v->type && (v->type->getKind() == ExprNode::identifier)) {
if (isTopLevel())
mGlobal->defineVariable((static_cast<IdentifierExprNode *>(v->name))->name,
findType((static_cast<IdentifierExprNode *>(v->type))->name));
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name,
(static_cast<IdentifierExprNode *>(v->type))->name);
}
else
allocateVariable((static_cast<IdentifierExprNode *>(v->name))->name);
if (v->initializer) {
if (!isTopLevel() && !isWithinWith()) {
TypedRegister r = genExpr(v->name);
TypedRegister val = genExpr(v->initializer);
@ -1603,7 +1557,6 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
saveName((static_cast<IdentifierExprNode *>(v->name))->name, val);
}
}
// XXX what's the else case here, when does a VariableBinding NOT have an identifier child?
}
v = v->next;
}
@ -1889,19 +1842,19 @@ TypedRegister ICodeGenerator::genStmt(StmtNode *p, LabelSet *currentLabelSet)
CatchClause *c = t->catches;
while (c) {
// Bind the incoming exception ...
setRegisterForVariable(c->name, exceptionRegister);
setRegisterForVariable(c->name, mExceptionRegister);
genStmt(c->stmt);
if (finallyLabel)
jsr(finallyLabel);
throwStmt(exceptionRegister);
throwStmt(mExceptionRegister);
c = c->next;
}
}
if (finallyLabel) {
setLabel(finallyInvoker);
jsr(finallyLabel);
throwStmt(exceptionRegister);
throwStmt(mExceptionRegister);
setLabel(finallyLabel);
genStmt(t->finally);

View File

@ -118,69 +118,70 @@ namespace ICG {
bool iCodeOwner;
LabelList labels;
Register topRegister; // highest (currently) alloacated register
Register registerBase; // start of registers available for expression temps
uint32 maxRegister; // highest (ever) allocated register
uint32 parameterCount; // number of parameters declared for the function
// these must come before any variables declared.
TypedRegister exceptionRegister;// reserved to carry the exception object.
VariableList *variableList; // name|register pair for each variable
Register mTopRegister; // highest (currently) alloacated register
uint32 mParameterCount; // number of parameters declared for the function
// these must come before any variables declared.
TypedRegister mExceptionRegister; // reserved to carry the exception object.
VariableList *variableList; // name|register pair for each variable
World *mWorld; // used to register strings
JSScope *mGlobal; // the scope for compiling within
LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct
// maps source position to instruction index
World *mWorld; // used to register strings
JSScope *mGlobal; // the scope for compiling within
LabelStack mLabelStack; // stack of LabelEntry objects, one per nested looping construct
// maps source position to instruction index
InstructionMap *mInstructionMap;
JSClass *mClass; // enclosing class when generating code for methods
ICodeGeneratorFlags mFlags; // assorted flags
JSClass *mClass; // enclosing class when generating code for methods
ICodeGeneratorFlags mFlags; // assorted flags
std::vector<bool> mPermanentRegister;
Register getTempRegister()
{
while (mTopRegister < mPermanentRegister.size())
if (!mPermanentRegister[mTopRegister])
return mTopRegister++;
else
++mTopRegister;
mPermanentRegister.resize(mTopRegister + 1);
mPermanentRegister[mTopRegister] = false;
return mTopRegister++;
}
void resetTopRegister() { mTopRegister = mParameterCount; }
void resetStatement() { resetTopRegister(); }
TypedRegister allocateRegister(const StringAtom& name, JSType *type);
void setRegisterForVariable(const StringAtom& name, TypedRegister r) { (*variableList)[name] = r; }
JSType *findType(const StringAtom& typeName);
void markMaxRegister()
{ if (topRegister > maxRegister) maxRegister = topRegister; }
Register getRegister()
{ return topRegister++; }
void resetTopRegister()
{ markMaxRegister(); topRegister = registerBase; }
void setLabel(Label *label);
void jsr(Label *label) { iCode->push_back(new Jsr(label)); }
void rts() { iCode->push_back(new Rts()); }
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, 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()); }
{ iCode->push_back(new Tryin(catchLabel, finallyLabel)); }
void endTry() { iCode->push_back(new Tryout()); }
void beginWith(TypedRegister obj)
{ iCode->push_back(new Within(obj)); }
void endWith()
{ iCode->push_back(new Without()); }
void beginWith(TypedRegister obj) { iCode->push_back(new Within(obj)); }
void endWith() { iCode->push_back(new Without()); }
void resetStatement() { resetTopRegister(); }
void setRegisterForVariable(const StringAtom& name, TypedRegister r)
{ (*variableList)[name] = r; }
void startStatement(uint32 pos)
{ (*mInstructionMap)[iCode->size()] = pos; }
void startStatement(uint32 pos) { (*mInstructionMap)[iCode->size()] = pos; }
ICodeOp mapExprNodeToICodeOp(ExprNode::Kind kind);
TypedRegister grabRegister(const StringAtom& name, JSType *type)
{
TypedRegister result(getRegister(), type);
(*variableList)[name] = result;
registerBase = topRegister;
return result;
}
bool isTopLevel() { return (mFlags & kIsTopLevel) != 0; }
bool isWithinWith() { return (mFlags & kIsWithinWith) != 0; }
@ -188,7 +189,11 @@ namespace ICG {
void setFlag(uint32 flag, bool v) { mFlags = (ICodeGeneratorFlags)((v) ? mFlags | flag : mFlags & ~flag); }
JSType *findType(const StringAtom& typeName);
typedef enum {Var, Property, Slot, Static, Name} LValueKind;
LValueKind resolveIdentifier(const StringAtom &name, TypedRegister &v, uint32 &slotIndex);
TypedRegister handleIdentifier(IdentifierExprNode *p, ExprNode::Kind use, ICodeOp xcrementOp, RegisterList *args);
TypedRegister handleDot(BinaryExprNode *b, ExprNode::Kind use, ICodeOp xcrementOp, TypedRegister ret, RegisterList *args);
ICodeModule *genFunction(FunctionStmtNode *f);
@ -207,32 +212,30 @@ namespace ICG {
ICodeModule *complete();
TypedRegister genExpr(ExprNode *p,
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
void preprocess(StmtNode *p);
bool needBoolValueInBranch = false,
Label *trueBranch = NULL,
Label *falseBranch = NULL);
TypedRegister genStmt(StmtNode *p, LabelSet *currentLabelSet = NULL);
void returnStmt(TypedRegister r);
void returnStmt();
void throwStmt(TypedRegister r)
{ iCode->push_back(new Throw(r)); }
void debuggerStmt()
{ iCode->push_back(new Debugger()); }
void throwStmt(TypedRegister r) { iCode->push_back(new Throw(r)); }
void debuggerStmt() { iCode->push_back(new Debugger()); }
TypedRegister allocateVariable(const StringAtom& name);
TypedRegister allocateVariable(const StringAtom& name, const StringAtom& typeName);
TypedRegister findVariable(const StringAtom& name)
{ VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second; }
{
VariableList::iterator i = variableList->find(name);
return (i == variableList->end()) ? TypedRegister(NotARegister, &None_Type) : (*i).second;
}
TypedRegister allocateParameter(const StringAtom& name)
{ parameterCount++; return grabRegister(name, &Any_Type); }
TypedRegister allocateParameter(const StringAtom& name) { mParameterCount++; return allocateRegister(name, &Any_Type); }
TypedRegister allocateParameter(const StringAtom& name, const StringAtom& typeName)
{ parameterCount++; return grabRegister(name, findType(typeName)); }
{ mParameterCount++; return allocateRegister(name, findType(typeName)); }
TypedRegister allocateParameter(const StringAtom& name, JSType *type)
{ parameterCount++; return grabRegister(name, type); }
{ mParameterCount++; return allocateRegister(name, type); }
Formatter& print(Formatter& f);
@ -279,8 +282,7 @@ namespace ICG {
TypedRegister varXcr(TypedRegister var, ICodeOp op);
Register getRegisterBase() { return topRegister; }
InstructionStream *getICode() { return iCode; }
InstructionStream *getICode() { return iCode; }
Label *getLabel();

View File

@ -679,14 +679,14 @@ JSValue Context::interpret(ICodeModule* iCode, const JSValues& args)
InstructionIterator nextPC = ++mPC;
do {
// call the constructor(s), if any.
ICodeModule* ctor = thisClass->getConstructor();
if (ctor) {
ICodeModule* init = thisClass->getInitializer();
if (init) {
mLinkage = new Linkage(mLinkage, nextPC,
mActivation, mGlobal, voidRegister);
mActivation = new Activation(ctor, args);
mActivation = new Activation(init, args);
registers = &mActivation->mRegisters;
nextPC = ctor->its_iCode->begin();
endPC = ctor->its_iCode->end();
nextPC = init->its_iCode->begin();
endPC = init->its_iCode->end();
}
thisClass = thisClass->getSuperClass();
} while (thisClass);

View File

@ -79,7 +79,7 @@ namespace JSClasses {
uint32 mStaticCount;
JSSlots mStaticSlots;
JSValue* mStaticData;
ICodeModule* mConstructor;
ICodeModule* mInitializer;
// typedef std::vector<ICodeModule*, gc_allocator<ICodeModule*> > JSMethods;
// JSMethods mMethods;
public:
@ -89,7 +89,7 @@ namespace JSClasses {
mSlotCount(superClass ? superClass->mSlotCount : 0),
mStaticCount(0),
mStaticData(0),
mConstructor(0)
mInitializer(0)
{
// to "inherit" superClass methods.
if (superClass)
@ -106,14 +106,14 @@ namespace JSClasses {
return mScope;
}
void setConstructor(ICodeModule* ctor)
void setInitializer(ICodeModule* init)
{
mConstructor = ctor;
mInitializer = init;
}
ICodeModule* getConstructor()
ICodeModule* getInitializer()
{
return mConstructor;
return mInitializer;
}
const JSSlot& defineSlot(const String& name, JSType* type)

View File

@ -175,6 +175,10 @@ SOURCE=..\hash.h
# End Source File
# Begin Source File
SOURCE=..\icode.h
# End Source File
# Begin Source File
SOURCE=..\icodegenerator.h
# End Source File
# Begin Source File

View File

@ -147,7 +147,6 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName)
TypedRegister ret(NotARegister, &None_Type);
while (p) {
icg.preprocess(p);
ret = icg.genStmt(p);
p = p->next;
}
@ -155,7 +154,7 @@ static ICodeModule* genCode(Context &cx, StmtNode *p, const String &fileName)
ICodeModule *icm = icg.complete();
//stdOut << icg;
stdOut << icg;
icm->setFileName (fileName);
return icm;
@ -344,7 +343,8 @@ 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;"
"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;"
};
static void testCompile()
@ -361,15 +361,11 @@ static void testCompile()
StmtNode *parsedStatements = p.parseProgram();
ICodeGenerator icg(&world, &glob);
StmtNode *s = parsedStatements;
while (s) {
icg.preprocess(s);
s = s->next;
}
s = parsedStatements;
while (s) {
icg.genStmt(s);
s = s->next;
}
// stdOut << icg;
cx.interpret(icg.complete(), JSValues());
}
}