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:
rogerl%netscape.com 2003-03-05 23:12:01 +00:00
parent d210a2e3d4
commit 171cbc252d
12 changed files with 171 additions and 320 deletions

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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;

View File

@ -138,6 +138,8 @@ enum JS2Op {
ePopv,
ePop,
eDup,
eSwap,
eSwap2,
eVoid,
eLexicalPostInc, // <multiname index:u16>

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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.

View File

@ -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);
}