Fixed for..in for generic lValue. Rationalized builtin class initialization
git-svn-id: svn://10.0.0.236/trunk@138987 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
d210a2e3d4
commit
171cbc252d
@ -117,17 +117,18 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *
|
||||
meta->reportError(Exception::rangeError, "Array length too large", meta->engine->errorPos());
|
||||
}
|
||||
else {
|
||||
setLength(meta, arrInst, 1);
|
||||
meta->mn1->name = meta->engine->numberToString((int32)0);
|
||||
meta->writeDynamicProperty(arrInst, meta->mn1, true, argv[0], RunPhase);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setLength(meta, arrInst, argc);
|
||||
for (uint32 i = 0; i < argc; i++) {
|
||||
meta->mn1->name = meta->engine->numberToString(i);
|
||||
meta->writeDynamicProperty(arrInst, meta->mn1, true, argv[i], RunPhase);
|
||||
uint32 i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
const DynamicPropertyMap::value_type e(*meta->engine->numberToString(i), DynamicPropertyValue(argv[i], DynamicPropertyValue::ENUMERATE));
|
||||
arrInst->dynamicProperties.insert(e);
|
||||
}
|
||||
const DynamicPropertyMap::value_type e(*meta->engine->length_StringAtom, DynamicPropertyValue(INT_TO_JS2VAL(i), DynamicPropertyValue::PERMANENT));
|
||||
arrInst->dynamicProperties.insert(e);
|
||||
}
|
||||
}
|
||||
JS2Object::removeRoot(ri);
|
||||
@ -794,14 +795,7 @@ js2val Array_SetElement(JS2Metadata *meta, const js2val thisValue, js2val *argv,
|
||||
|
||||
void initArrayObject(JS2Metadata *meta)
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction arrayProtos[] =
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "toString", 0, Array_toString },
|
||||
{ "toLocaleString", 0, Array_toString }, // XXX
|
||||
@ -819,38 +813,8 @@ void initArrayObject(JS2Metadata *meta)
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
||||
meta->arrayClass->construct = Array_Constructor;
|
||||
meta->arrayClass->call = Array_Constructor;
|
||||
meta->arrayClass->prototype = new ArrayInstance(meta, meta->objectClass->prototype, meta->arrayClass);
|
||||
|
||||
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
|
||||
meta->env->addFrame(meta->arrayClass);
|
||||
Variable *v = new Variable(meta->arrayClass, OBJECT_TO_JS2VAL(meta->arrayClass->prototype), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
v = new Variable(meta->numberClass, INT_TO_JS2VAL(1), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
PrototypeFunction *pf = &arrayProtos[0];
|
||||
while (pf->name) {
|
||||
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
InstanceMember *m = new InstanceMethod(callInst);
|
||||
meta->defineInstanceMember(meta->arrayClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
|
||||
/*
|
||||
Dynamic property of the prototype:
|
||||
*/
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
fInst->fWrap = callInst->fWrap;
|
||||
meta->writeDynamicProperty(meta->arrayClass->prototype, new Multiname(&meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
fInst->writeProperty(meta, meta->engine->length_StringAtom, INT_TO_JS2VAL(pf->length), DynamicPropertyValue::PERMANENT | DynamicPropertyValue::READONLY);
|
||||
|
||||
pf++;
|
||||
}
|
||||
meta->initBuiltinClass(meta->arrayClass, &prototypeFunctions[0], NULL, Array_Constructor, Array_Constructor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -99,67 +99,15 @@ namespace MetaData {
|
||||
|
||||
void initBooleanObject(JS2Metadata *meta)
|
||||
{
|
||||
meta->booleanClass->construct = Boolean_Constructor;
|
||||
meta->booleanClass->call = Boolean_Call;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction prototypeFunctions[] =
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "toString", 0, Boolean_toString },
|
||||
{ "valueOf", 0, Boolean_valueOf },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
||||
meta->booleanClass->prototype = new BooleanInstance(meta, meta->objectClass->prototype, meta->booleanClass);
|
||||
|
||||
|
||||
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
|
||||
meta->env->addFrame(meta->booleanClass);
|
||||
Variable *v = new Variable(meta->booleanClass, OBJECT_TO_JS2VAL(meta->booleanClass->prototype), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
v = new Variable(meta->numberClass, INT_TO_JS2VAL(1), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
// Add "constructor" as a dynamic property of the prototype
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
meta->writeDynamicProperty(fInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(1), RunPhase);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), Boolean_Constructor);
|
||||
meta->writeDynamicProperty(meta->booleanClass->prototype, new Multiname(&meta->world.identifiers["constructor"], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
|
||||
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not static members, since those can't be accessed from the instance
|
||||
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
meta->defineLocalMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
*/
|
||||
InstanceMember *m = new InstanceMethod(callInst);
|
||||
meta->defineInstanceMember(meta->booleanClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
|
||||
|
||||
/*
|
||||
Dynamic property of the prototype:
|
||||
*/
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
fInst->fWrap = callInst->fWrap;
|
||||
meta->writeDynamicProperty(meta->booleanClass->prototype, new Multiname(&meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
meta->writeDynamicProperty(fInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase);
|
||||
|
||||
pf++;
|
||||
}
|
||||
|
||||
meta->initBuiltinClass(meta->booleanClass, &prototypeFunctions[0], NULL, Boolean_Constructor, Boolean_Call);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1419,14 +1419,7 @@ static js2val Date_valueOf(JS2Metadata *meta, const js2val thisValue, js2val arg
|
||||
|
||||
void initDateObject(JS2Metadata *meta)
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction prototypeFunctions[] =
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "getTime", 0, Date_getTime },
|
||||
{ "getTimezoneOffset", 0, Date_getTimezoneOffset },
|
||||
@ -1479,61 +1472,17 @@ void initDateObject(JS2Metadata *meta)
|
||||
#endif
|
||||
{ NULL }
|
||||
};
|
||||
FunctionData staticFunctions[] =
|
||||
{
|
||||
{ "parse", 0, Date_parse },
|
||||
{ "UTC", 0, Date_UTC },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
LocalTZA = -(PRMJ_LocalGMTDifference() * msPerSecond);
|
||||
|
||||
meta->dateClass->construct = Date_Constructor;
|
||||
meta->dateClass->call = Date_Call;
|
||||
|
||||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
||||
|
||||
meta->dateClass->prototype = new DateInstance(meta, meta->objectClass->prototype, meta->booleanClass);
|
||||
|
||||
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
|
||||
meta->env->addFrame(meta->dateClass);
|
||||
Variable *v = new Variable(meta->dateClass, OBJECT_TO_JS2VAL(meta->dateClass->prototype), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
v = new Variable(meta->numberClass, INT_TO_JS2VAL(1), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
|
||||
// "parse" & "UTC" as static members:
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), Date_parse);
|
||||
v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
meta->defineLocalMember(meta->env, &meta->world.identifiers["parse"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), Date_UTC);
|
||||
v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
meta->defineLocalMember(meta->env, &meta->world.identifiers["UTC"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not prototype object function properties, like ECMA3
|
||||
meta->writeDynamicProperty(meta->dateClass->prototype, new Multiname(meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
*/
|
||||
/*
|
||||
XXX not static members, since those can't be accessed from the instance
|
||||
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(fInst), true);
|
||||
meta->defineLocalMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
*/
|
||||
InstanceMember *m = new InstanceMethod(callInst);
|
||||
meta->defineInstanceMember(meta->dateClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
|
||||
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
fInst->fWrap = callInst->fWrap;
|
||||
meta->writeDynamicProperty(meta->dateClass->prototype, new Multiname(&meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
meta->writeDynamicProperty(fInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase);
|
||||
pf++;
|
||||
|
||||
}
|
||||
|
||||
meta->dateClass->prototype = new DateInstance(meta, meta->objectClass->prototype, meta->booleanClass);
|
||||
meta->initBuiltinClass(meta->dateClass, &prototypeFunctions[0], &staticFunctions[0], Date_Constructor, Date_Call);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -517,6 +517,8 @@ namespace MetaData {
|
||||
{ ePopv, "Popv", 0 },
|
||||
{ ePop, "Pop", 0 },
|
||||
{ eDup, "Dup", 0 },
|
||||
{ eSwap, "Swap", 0 },
|
||||
{ eSwap2, "Swap2", 0 },
|
||||
{ eVoid, "Void", 0 },
|
||||
|
||||
{ eLexicalPostInc, "LexicalPostInc", NAME_INDEX }, // <multiname index:u16>
|
||||
@ -738,6 +740,10 @@ namespace MetaData {
|
||||
case eDup: // duplicate top item
|
||||
return 1;
|
||||
|
||||
case eSwap: // swap top two items
|
||||
case eSwap2: // or top three items
|
||||
return 0;
|
||||
|
||||
case ePop: // remove top item
|
||||
return -1;
|
||||
|
||||
|
||||
@ -138,6 +138,8 @@ enum JS2Op {
|
||||
ePopv,
|
||||
ePop,
|
||||
eDup,
|
||||
eSwap,
|
||||
eSwap2,
|
||||
eVoid,
|
||||
|
||||
eLexicalPostInc, // <multiname index:u16>
|
||||
|
||||
@ -114,63 +114,15 @@ namespace MetaData {
|
||||
|
||||
void initFunctionObject(JS2Metadata *meta)
|
||||
{
|
||||
meta->functionClass->construct = Function_Constructor;
|
||||
meta->functionClass->call = Function_Constructor;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction prototypeFunctions[] =
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "toString", 0, Function_toString },
|
||||
{ "valueOf", 0, Function_valueOf },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
||||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
||||
meta->functionClass->prototype = new FunctionInstance(meta, meta->objectClass->prototype, meta->functionClass);
|
||||
|
||||
// Adding "prototype" as a static member of the class - not a dynamic property
|
||||
meta->env->addFrame(meta->functionClass);
|
||||
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(meta->functionClass->prototype), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
// Add "constructor" as a dynamic property of the prototype
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
meta->writeDynamicProperty(fInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(1), RunPhase);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), Function_Constructor);
|
||||
meta->writeDynamicProperty(meta->functionClass->prototype, new Multiname(&meta->world.identifiers["constructor"], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not static members, since those can't be accessed from the instance
|
||||
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(fInst), true);
|
||||
meta->defineLocalMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
*/
|
||||
InstanceMember *m = new InstanceMethod(callInst);
|
||||
meta->defineInstanceMember(meta->functionClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
|
||||
|
||||
/*
|
||||
Dynamic property of the prototype:
|
||||
*/
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
fInst->fWrap = callInst->fWrap;
|
||||
meta->writeDynamicProperty(meta->functionClass->prototype, new Multiname(&meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
meta->writeDynamicProperty(fInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase);
|
||||
|
||||
pf++;
|
||||
}
|
||||
|
||||
meta->initBuiltinClass(meta->functionClass, &prototypeFunctions[0], NULL, Function_Constructor, Function_Constructor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -314,13 +314,7 @@ void initMathObject(JS2Metadata *meta)
|
||||
}
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction prototypeFunctions[] =
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "abs", 1, Math_abs },
|
||||
{ "acos", 1, Math_acos },
|
||||
@ -344,7 +338,7 @@ void initMathObject(JS2Metadata *meta)
|
||||
};
|
||||
|
||||
meta->env->addFrame(meta->mathClass);
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
FunctionData *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
|
||||
@ -336,14 +336,14 @@ namespace MetaData {
|
||||
case StmtNode::DoWhile:
|
||||
{
|
||||
UnaryStmtNode *w = checked_cast<UnaryStmtNode *>(*si);
|
||||
g->tgtID = w->breakLabelID;
|
||||
g->tgtID = w->continueLabelID;
|
||||
}
|
||||
break;
|
||||
case StmtNode::For:
|
||||
case StmtNode::ForIn:
|
||||
{
|
||||
ForStmtNode *f = checked_cast<ForStmtNode *>(*si);
|
||||
g->tgtID = f->breakLabelID;
|
||||
g->tgtID = f->continueLabelID;
|
||||
}
|
||||
}
|
||||
found = true;
|
||||
@ -771,6 +771,18 @@ namespace MetaData {
|
||||
*/
|
||||
{
|
||||
ForStmtNode *f = checked_cast<ForStmtNode *>(p);
|
||||
BytecodeContainer::LabelID loopTop = bCon->getLabel();
|
||||
|
||||
Reference *r = SetupExprNode(env, phase, f->expr2, &exprType);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eFirst, p->pos);
|
||||
bCon->emitBranch(eBranchFalse, f->breakLabelID, p->pos);
|
||||
|
||||
bCon->setLabel(loopTop);
|
||||
|
||||
targetList.push_back(p);
|
||||
bCon->emitOp(eForValue, p->pos);
|
||||
|
||||
Reference *v = NULL;
|
||||
if (f->initializer->getKind() == StmtNode::Var) {
|
||||
VariableStmtNode *vs = checked_cast<VariableStmtNode *>(f->initializer);
|
||||
@ -787,17 +799,14 @@ namespace MetaData {
|
||||
else
|
||||
NOT_REACHED("what else??");
|
||||
}
|
||||
|
||||
BytecodeContainer::LabelID loopTop = bCon->getLabel();
|
||||
|
||||
Reference *r = SetupExprNode(env, phase, f->expr2, &exprType);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(eFirst, p->pos);
|
||||
bCon->emitBranch(eBranchFalse, f->breakLabelID, p->pos);
|
||||
|
||||
bCon->setLabel(loopTop);
|
||||
targetList.push_back(p);
|
||||
bCon->emitOp(eForValue, p->pos);
|
||||
switch (v->hasStackEffect()) {
|
||||
case 1:
|
||||
bCon->emitOp(eSwap, p->pos);
|
||||
break;
|
||||
case 2:
|
||||
bCon->emitOp(eSwap2, p->pos);
|
||||
break;
|
||||
}
|
||||
v->emitWriteBytecode(bCon, p->pos);
|
||||
bCon->emitOp(ePop, p->pos); // clear iterator value from stack
|
||||
SetupStmt(env, phase, f->stmt);
|
||||
@ -2297,9 +2306,10 @@ doUnary:
|
||||
case ExprNode::comma:
|
||||
{
|
||||
BinaryExprNode *b = checked_cast<BinaryExprNode *>(p);
|
||||
SetupExprNode(env, phase, b->op1, exprType);
|
||||
Reference *r = SetupExprNode(env, phase, b->op1, exprType);
|
||||
if (r) r->emitReadBytecode(bCon, p->pos);
|
||||
bCon->emitOp(ePopv, p->pos);
|
||||
SetupExprNode(env, phase, b->op2, exprType);
|
||||
returnRef = SetupExprNode(env, phase, b->op2, exprType);
|
||||
}
|
||||
break;
|
||||
case ExprNode::Instanceof:
|
||||
@ -4297,6 +4307,72 @@ deleteClassProperty:
|
||||
reportError(kind, message, pos, str.c_str());
|
||||
}
|
||||
|
||||
|
||||
void JS2Metadata::initBuiltinClass(JS2Class *builtinClass, FunctionData *protoFunctions, FunctionData *staticFunctions, NativeCode *construct, NativeCode *call)
|
||||
{
|
||||
FunctionData *pf;
|
||||
|
||||
builtinClass->construct = construct;
|
||||
builtinClass->call = call;
|
||||
|
||||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(publicNamespace);
|
||||
|
||||
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
|
||||
env->addFrame(builtinClass);
|
||||
{
|
||||
Variable *v = new Variable(builtinClass, OBJECT_TO_JS2VAL(builtinClass->prototype), true);
|
||||
defineLocalMember(env, engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
v = new Variable(builtinClass, INT_TO_JS2VAL(1), true);
|
||||
defineLocalMember(env, engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
|
||||
pf = staticFunctions;
|
||||
if (pf) {
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
v = new Variable(functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
defineLocalMember(env, &world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
pf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
env->removeTopFrame();
|
||||
|
||||
// Add "constructor" as a dynamic property of the prototype
|
||||
FunctionInstance *fInst = new FunctionInstance(this, functionClass->prototype, functionClass);
|
||||
writeDynamicProperty(fInst, new Multiname(engine->length_StringAtom, publicNamespace), true, INT_TO_JS2VAL(1), RunPhase);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), construct);
|
||||
writeDynamicProperty(builtinClass->prototype, new Multiname(&world.identifiers["constructor"], publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
|
||||
pf = protoFunctions;
|
||||
if (pf) {
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not prototype object function properties, like ECMA3
|
||||
writeDynamicProperty(dateClass->prototype, new Multiname(world.identifiers[pf->name], publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
*/
|
||||
/*
|
||||
XXX not static members, since those can't be accessed from the instance
|
||||
Variable *v = new Variable(functionClass, OBJECT_TO_JS2VAL(fInst), true);
|
||||
defineLocalMember(&env, &world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
*/
|
||||
InstanceMember *m = new InstanceMethod(callInst);
|
||||
defineInstanceMember(builtinClass, &cxt, &world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
|
||||
|
||||
FunctionInstance *fInst = new FunctionInstance(this, functionClass->prototype, functionClass);
|
||||
fInst->fWrap = callInst->fWrap;
|
||||
writeDynamicProperty(builtinClass->prototype, new Multiname(&world.identifiers[pf->name], publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
writeDynamicProperty(fInst, new Multiname(engine->length_StringAtom, publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase);
|
||||
pf++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************************************
|
||||
*
|
||||
* JS2Class
|
||||
|
||||
@ -56,6 +56,8 @@ class SimpleInstance;
|
||||
typedef void (Invokable)();
|
||||
typedef js2val (Callor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
|
||||
typedef js2val (Constructor)(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
|
||||
typedef js2val (NativeCode)(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc);
|
||||
|
||||
|
||||
extern void initDateObject(JS2Metadata *meta);
|
||||
extern void initStringObject(JS2Metadata *meta);
|
||||
@ -80,6 +82,13 @@ extern js2val RegExp_exec(JS2Metadata *meta, const js2val thisValue, js2val *arg
|
||||
extern js2val Boolean_Constructor(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
|
||||
extern js2val Number_Constructor(JS2Metadata *meta, const js2val thisValue, js2val *argv, uint32 argc);
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} FunctionData;
|
||||
|
||||
|
||||
extern uint32 getLength(JS2Metadata *meta, JS2Object *obj);
|
||||
extern js2val setLength(JS2Metadata *meta, JS2Object *obj, uint32 length);
|
||||
|
||||
@ -571,8 +580,6 @@ public:
|
||||
js2val value; // This fixed property's current value; uninitialised if the fixed property is an uninitialised constant
|
||||
};
|
||||
|
||||
typedef js2val (NativeCode)(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc);
|
||||
|
||||
class ParameterFrame;
|
||||
|
||||
class FunctionWrapper {
|
||||
@ -779,7 +786,10 @@ public:
|
||||
virtual void emitPreIncBytecode(BytecodeContainer *, size_t) { ASSERT(false); }
|
||||
virtual void emitPreDecBytecode(BytecodeContainer *, size_t) { ASSERT(false); }
|
||||
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *, size_t) { ASSERT(false); }
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *, size_t) { ASSERT(false); }
|
||||
|
||||
// indicate whether building the reference generate any stack deposits
|
||||
virtual int hasStackEffect() { ASSERT(false); return 0; }
|
||||
};
|
||||
|
||||
class LexicalReference : public Reference {
|
||||
@ -810,6 +820,8 @@ public:
|
||||
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalPreDec, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
|
||||
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eLexicalDelete, pos); bCon->addMultiname(new Multiname(variableMultiname)); }
|
||||
|
||||
virtual int hasStackEffect() { return 0; }
|
||||
};
|
||||
|
||||
class DotReference : public Reference {
|
||||
@ -842,6 +854,8 @@ public:
|
||||
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotPreDec, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
|
||||
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eDotDelete, pos); bCon->addMultiname(new Multiname(propertyMultiname)); }
|
||||
|
||||
virtual int hasStackEffect() { return 1; }
|
||||
};
|
||||
|
||||
class SlotReference : public Reference {
|
||||
@ -864,6 +878,7 @@ public:
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eFalse, pos); /* bCon->emitOp(eSlotDelete, pos); bCon->addShort((uint16)slotIndex); */ }
|
||||
|
||||
uint32 slotIndex;
|
||||
virtual int hasStackEffect() { return 1; }
|
||||
};
|
||||
|
||||
|
||||
@ -904,6 +919,7 @@ public:
|
||||
virtual void emitPreDecBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eBracketPreDec, pos); }
|
||||
|
||||
virtual void emitDeleteBytecode(BytecodeContainer *bCon, size_t pos) { bCon->emitOp(eBracketDelete, pos); }
|
||||
virtual int hasStackEffect() { return 2; }
|
||||
};
|
||||
|
||||
|
||||
@ -1138,6 +1154,7 @@ public:
|
||||
bool deleteInstanceMember(JS2Class *c, QualifiedName *qname, bool *result);
|
||||
|
||||
void addGlobalObjectFunction(char *name, NativeCode *code, uint32 length);
|
||||
void initBuiltinClass(JS2Class *builtinClass, FunctionData *protoFunctions, FunctionData *staticFunctions, NativeCode *construct, NativeCode *call);
|
||||
|
||||
void reportError(Exception::Kind kind, const char *message, size_t pos, const char *arg = NULL);
|
||||
void reportError(Exception::Kind kind, const char *message, size_t pos, const String &name);
|
||||
@ -1231,7 +1248,6 @@ public:
|
||||
|
||||
inline char narrow(char16 ch) { return char(ch); }
|
||||
|
||||
|
||||
}; // namespace MetaData
|
||||
}; // namespace Javascript
|
||||
|
||||
|
||||
@ -126,13 +126,7 @@ namespace MetaData {
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction prototypeFunctions[] =
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "toString", 0, Number_toString },
|
||||
{ "valueOf", 0, Number_valueOf },
|
||||
@ -140,38 +134,7 @@ namespace MetaData {
|
||||
};
|
||||
|
||||
meta->numberClass->prototype = new NumberInstance(meta, meta->objectClass->prototype, meta->numberClass);
|
||||
|
||||
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
|
||||
meta->env->addFrame(meta->numberClass);
|
||||
Variable *v = new Variable(meta->numberClass, OBJECT_TO_JS2VAL(meta->numberClass->prototype), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
v = new Variable(meta->numberClass, INT_TO_JS2VAL(1), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not static members, since those can't be accessed from the instance
|
||||
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
meta->defineLocalMember(&meta->env, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
*/
|
||||
InstanceMember *m = new InstanceMethod(callInst);
|
||||
meta->defineInstanceMember(meta->numberClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
|
||||
|
||||
/*
|
||||
Dynamic property of the prototype:
|
||||
*/
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
fInst->fWrap = callInst->fWrap;
|
||||
meta->writeDynamicProperty(meta->numberClass->prototype, new Multiname(&meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
meta->writeDynamicProperty(fInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase);
|
||||
|
||||
pf++;
|
||||
}
|
||||
meta->initBuiltinClass(meta->numberClass, &prototypeFunctions[0], NULL, Number_Constructor, Number_Call);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -76,6 +76,25 @@
|
||||
}
|
||||
break;
|
||||
|
||||
case eSwap: // go from [x][y] --> [y][x]
|
||||
{
|
||||
ASSERT((sp - execStack) > 2);
|
||||
a = sp[-2];
|
||||
sp[-2] = sp[-1];
|
||||
sp[-1] = a;
|
||||
}
|
||||
break;
|
||||
case eSwap2: // go from [x][y][z] --> [y][z][x]
|
||||
{
|
||||
ASSERT((sp - execStack) > 3);
|
||||
a = sp[-3];
|
||||
sp[-3] = sp[-2];
|
||||
sp[-2] = sp[-1];
|
||||
sp[-1] = a;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
// Get the first enumerable property from the object
|
||||
// and save it's 'state' on the stack. Push true/false
|
||||
// for whether that was succesful.
|
||||
|
||||
@ -761,14 +761,7 @@ static js2val String_substring(JS2Metadata *meta, const js2val thisValue, js2val
|
||||
|
||||
void initStringObject(JS2Metadata *meta)
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction prototypeFunctions[] =
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
{ "toString", 0, String_toString },
|
||||
{ "valueOf", 0, String_valueOf },
|
||||
@ -792,45 +785,14 @@ void initStringObject(JS2Metadata *meta)
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
||||
meta->stringClass->construct = String_Constructor;
|
||||
meta->stringClass->call = String_Call;
|
||||
|
||||
meta->stringClass->prototype = new StringInstance(meta, meta->objectClass->prototype, meta->booleanClass);
|
||||
|
||||
// Adding "prototype" & "length" as static members of the class - not dynamic properties; XXX
|
||||
meta->env->addFrame(meta->stringClass);
|
||||
Variable *v = new Variable(meta->stringClass, OBJECT_TO_JS2VAL(meta->stringClass->prototype), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->prototype_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
v = new Variable(meta->numberClass, INT_TO_JS2VAL(1), true);
|
||||
meta->defineLocalMember(meta->env, meta->engine->length_StringAtom, &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), String_fromCharCode);
|
||||
v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
meta->defineLocalMember(meta->env, &meta->world.identifiers["fromCharCode"], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, v, 0);
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
PrototypeFunction *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
SimpleInstance *callInst = new SimpleInstance(meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code);
|
||||
/*
|
||||
XXX not prototype object function properties, like ECMA3, but members of the String class
|
||||
meta->writeDynamicProperty(meta->stringClass->prototype, new Multiname(meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
*/
|
||||
InstanceMember *m = new InstanceMethod(callInst);
|
||||
meta->defineInstanceMember(meta->stringClass, &meta->cxt, &meta->world.identifiers[pf->name], &publicNamespaceList, Attribute::NoOverride, false, ReadWriteAccess, m, 0);
|
||||
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
fInst->fWrap = callInst->fWrap;
|
||||
meta->writeDynamicProperty(meta->stringClass->prototype, new Multiname(&meta->world.identifiers[pf->name], meta->publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
|
||||
meta->writeDynamicProperty(fInst, new Multiname(meta->engine->length_StringAtom, meta->publicNamespace), true, INT_TO_JS2VAL(pf->length), RunPhase);
|
||||
pf++;
|
||||
}
|
||||
FunctionData staticFunctions[] =
|
||||
{
|
||||
{ "fromCharCode", 1, String_fromCharCode },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
meta->stringClass->prototype = new StringInstance(meta, meta->objectClass->prototype, meta->stringClass);
|
||||
meta->initBuiltinClass(meta->stringClass, &prototypeFunctions[0], &staticFunctions[0], String_Constructor, String_Call);
|
||||
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user