Added 'arguments' property and global object resolution for 'this'.

This commit is contained in:
rogerl%netscape.com 2003-02-11 23:58:26 +00:00
parent be2365be95
commit 1f8d040166
6 changed files with 41 additions and 19 deletions

View File

@ -379,12 +379,12 @@ int main(int argc, char **argv)
#endif
metadata = new MetaData::JS2Metadata(world);
metadata->addGlobalObjectFunction("print", print);
metadata->addGlobalObjectFunction("load", load);
metadata->addGlobalObjectFunction("print", print, 1);
metadata->addGlobalObjectFunction("load", load, 1);
#ifdef DEBUG
metadata->addGlobalObjectFunction("dump", dump);
metadata->addGlobalObjectFunction("trees", trees);
metadata->addGlobalObjectFunction("trace", trace);
metadata->addGlobalObjectFunction("dump", dump, 1);
metadata->addGlobalObjectFunction("trees", trees, 0);
metadata->addGlobalObjectFunction("trace", trace, 0);
#endif
try {

View File

@ -89,7 +89,7 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *
}
else {
setLength(meta, arrInst, 1);
Multiname mn(meta->toString((int32)0), meta->publicNamespace);
Multiname mn(meta->engine->numberToString((int32)0), meta->publicNamespace);
meta->writeDynamicProperty(arrInst, &mn, true, argv[0], RunPhase);
}
}
@ -97,7 +97,7 @@ js2val Array_Constructor(JS2Metadata *meta, const js2val /*thisValue*/, js2val *
Multiname mn(NULL, meta->publicNamespace);
setLength(meta, arrInst, argc);
for (uint32 i = 0; i < argc; i++) {
mn.name = meta->toString(i);
mn.name = meta->engine->numberToString(i);
meta->writeDynamicProperty(arrInst, &mn, true, argv[i], RunPhase);
}
}

View File

@ -64,7 +64,7 @@ namespace MetaData {
js2val result = JS2VAL_VOID;
Arena a;
Pragma::Flags flags = Pragma::es4;
Pragma::Flags flags = Pragma::js1;
Parser p(world, a, flags, str, fileName);
CompilationData *oldData = NULL;
try {

View File

@ -2325,6 +2325,8 @@ doUnary:
&& !JS2VAL_IS_NULL(checked_cast<ParameterFrame *>(pf)->thisObject))
if (allowPrototypeThis || !checked_cast<ParameterFrame *>(pf)->prototype)
return checked_cast<ParameterFrame *>(pf)->thisObject;
if (pf->kind == GlobalObjectKind)
return OBJECT_TO_JS2VAL(pf);
fi++;
}
return JS2VAL_VOID;
@ -2917,6 +2919,11 @@ doUnary:
return BOOLEAN_TO_JS2VAL(JSDOUBLE_IS_NaN(d));
}
static js2val GlobalObject_toString(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint32 /* argc */)
{
return STRING_TO_JS2VAL(meta->engine->allocString("[object global]"));
}
static js2val GlobalObject_eval(JS2Metadata *meta, const js2val /* thisValue */, js2val argv[], uint32 argc)
{
if (!JS2VAL_IS_STRING(argv[0]))
@ -2924,12 +2931,12 @@ doUnary:
return meta->readEvalString(*meta->toString(argv[0]), widenCString("Eval Source"));
}
// XXX need length value
void JS2Metadata::addGlobalObjectFunction(char *name, NativeCode *code)
void JS2Metadata::addGlobalObjectFunction(char *name, NativeCode *code, uint32 length)
{
SimpleInstance *fInst = new SimpleInstance(functionClass);
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_VOID, true), code);
writeDynamicProperty(glob, new Multiname(&world.identifiers[name], publicNamespace), true, OBJECT_TO_JS2VAL(fInst), RunPhase);
writeDynamicProperty(fInst, new Multiname(engine->length_StringAtom, publicNamespace), true, length, RunPhase);
}
#define MAKEBUILTINCLASS(c, super, dynamic, allowNull, final, name, defaultVal) c = new JS2Class(super, NULL, new Namespace(engine->private_StringAtom), dynamic, allowNull, final, name); c->complete = true; c->defaultValue = defaultVal;
@ -2994,8 +3001,9 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
// XXX add 'version'
writeDynamicProperty(glob, new Multiname(&world.identifiers["version"], publicNamespace), true, INT_TO_JS2VAL(0), RunPhase);
// Function properties of the global object
addGlobalObjectFunction("isNaN", GlobalObject_isNaN);
addGlobalObjectFunction("eval", GlobalObject_eval);
addGlobalObjectFunction("isNaN", GlobalObject_isNaN, 1);
addGlobalObjectFunction("eval", GlobalObject_eval, 1);
addGlobalObjectFunction("toString", GlobalObject_toString, 0);
/*** ECMA 3 Object Class ***/
@ -4573,16 +4581,32 @@ deleteClassProperty:
// Assume that instantiate has been called, the plural frame will contain
// the cloned Variables assigned into this (singular) frame. Use the
// incoming values to initialize the positionals.
void ParameterFrame::assignArguments(js2val *argBase, uint32 argCount)
void ParameterFrame::assignArguments(JS2Metadata *meta, js2val *argBase, uint32 argCount)
{
Multiname mn(NULL, meta->publicNamespace);
ASSERT(pluralFrame->kind == ParameterKind);
ParameterFrame *plural = checked_cast<ParameterFrame *>(pluralFrame);
ASSERT((plural->positionalCount == 0) || (plural->positional != NULL));
js2val argumentsVal = OBJECT_TO_JS2VAL(new ArrayInstance(meta->arrayClass));
ArrayInstance *arrInst = checked_cast<ArrayInstance *>(JS2VAL_TO_OBJECT(argumentsVal));
for (uint32 i = 0; ((i < argCount) && (i < plural->positionalCount)); i++) {
ASSERT(plural->positional[i]->cloneContent);
ASSERT(plural->positional[i]->cloneContent->kind == Member::Variable);
(checked_cast<Variable *>(plural->positional[i]->cloneContent))->value = argBase[i];
mn.name = meta->engine->numberToString(i);
meta->writeDynamicProperty(arrInst, &mn, true, argBase[i], RunPhase);
}
setLength(meta, arrInst, i);
// Add the 'arguments' property
QualifiedName qn(meta->publicNamespace, &meta->world.identifiers["arguments"]);
LocalBinding *sb = new LocalBinding(qn, new Variable(meta->arrayClass, argumentsVal, true));
const LocalBindingMap::value_type e(*qn.id, sb);
localReadBindings.insert(e);
}

View File

@ -887,7 +887,7 @@ public:
uint32 positionalCount;
virtual void instantiate(Environment *env);
void assignArguments(js2val *argBase, uint32 argCount);
void assignArguments(JS2Metadata *meta, js2val *argBase, uint32 argCount);
virtual void markChildren();
virtual ~ParameterFrame() { }
};
@ -1090,7 +1090,7 @@ public:
bool deleteLocalMember(LocalMember *m, bool *result);
bool deleteInstanceMember(JS2Class *c, QualifiedName *qname, bool *result);
void addGlobalObjectFunction(char *name, NativeCode *code);
void addGlobalObjectFunction(char *name, NativeCode *code, uint32 length);
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);

View File

@ -90,7 +90,7 @@
PrototypeInstance *pInst = new PrototypeInstance(protoObj, meta->objectClass);
baseVal = OBJECT_TO_JS2VAL(pInst);
runtimeFrame->thisObject = baseVal;
runtimeFrame->assignArguments(base(argCount), argCount);
runtimeFrame->assignArguments(meta, base(argCount), argCount);
jsr(phase, fWrap->bCon, base(argCount + 1), baseVal); // seems out of order, but we need to catch the current top frame
meta->env->addFrame(runtimeFrame);
}
@ -126,7 +126,6 @@
fWrap = (checked_cast<FunctionInstance *>(fObj))->fWrap;
}
if (fWrap) {
if (fWrap->compileFrame->prototype) {
if (JS2VAL_IS_VOID(a) || JS2VAL_IS_NULL(a)) {
Frame *g = meta->env->getPackageOrGlobalFrame();
@ -134,7 +133,6 @@
a = OBJECT_TO_JS2VAL(g);
}
}
if (fWrap->code) { // native code
a = fWrap->code(meta, a, base(argCount), argCount);
pop(argCount + 2);
@ -146,7 +144,7 @@
runtimeFrame->thisObject = a;
// assignArguments(runtimeFrame, fWrap->compileFrame->signature);
// XXX
runtimeFrame->assignArguments(base(argCount), argCount);
runtimeFrame->assignArguments(meta, base(argCount), argCount);
jsr(phase, fWrap->bCon, base(argCount + 2), JS2VAL_VOID); // seems out of order, but we need to catch the current top frame
meta->env->addFrame(runtimeFrame);
}