Added Function.call/apply. Fixed bug in exception handling clean-up of

activation stack.


git-svn-id: svn://10.0.0.236/trunk@107472 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
rogerl%netscape.com
2001-11-06 19:45:04 +00:00
parent ad253d37ca
commit 2fabd4ccad
2 changed files with 131 additions and 36 deletions

View File

@@ -1788,7 +1788,7 @@ static JSValue Object_Constructor(Context *cx, const JSValue& thisValue, JSValue
return thatValue;
}
static JSValue Object_toString(Context *, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/)
static JSValue Object_toString(Context * /* cx */, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/)
{
if (thisValue.isObject())
return JSValue(new String(widenCString("[object ") + *thisValue.object->getType()->mClassName + widenCString("]")));
@@ -1804,6 +1804,11 @@ static JSValue Object_toString(Context *, const JSValue& thisValue, JSValue * /*
}
}
static JSValue Object_valueOf(Context * /* cx */, const JSValue& thisValue, JSValue * /*argv*/, uint32 /*argc*/)
{
return thisValue;
}
struct IteratorDongle {
JSObject *obj;
PropertyIterator it;
@@ -1976,6 +1981,68 @@ static JSValue Function_hasInstance(Context *cx, const JSValue& thisValue, JSVal
return kFalseValue;
}
static JSValue Function_call(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc)
{
if (!thisValue.isFunction())
cx->reportError(Exception::typeError, "Non-callable object for Function.call");
JSValue thisArg;
if (argc == 0)
thisArg = JSValue(cx->getGlobalObject());
else {
if (argv[0].isUndefined() || argv[0].isNull())
thisArg = JSValue(cx->getGlobalObject());
else
thisArg = JSValue(argv[0].toObject(cx));
--argc;
++argv;
}
return cx->invokeFunction(thisValue.function, thisArg, argv, argc);
}
static JSValue Function_apply(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc)
{
if (!thisValue.isFunction())
cx->reportError(Exception::typeError, "Non-callable object for Function.call");
ContextStackReplacement csr(cx);
JSValue thisArg;
if (argc == 0)
thisArg = JSValue(cx->getGlobalObject());
else {
if (argv[0].isUndefined() || argv[0].isNull())
thisArg = JSValue(cx->getGlobalObject());
else
thisArg = JSValue(argv[0].toObject(cx));
}
if (argc <= 1) {
argv = NULL;
argc = 0;
}
else {
if (argv[1].getType() != Array_Type)
cx->reportError(Exception::typeError, "Function.apply must have Array type argument list");
ASSERT(argv[1].isObject());
JSObject *argsObj = argv[1].object;
argsObj->getProperty(cx, cx->Length_StringAtom, CURRENT_ATTR);
JSValue result = cx->popValue();
argc = (uint32)(result.toUInt32(cx).f64);
argv = new JSValue[argc];
for (uint32 i = 0; i < argc; i++) {
const String *id = numberToString(i);
argsObj->getProperty(cx, *id, CURRENT_ATTR);
argv[i] = cx->popValue();
delete id;
}
}
return cx->invokeFunction(thisValue.function, thisArg, argv, argc);
}
static JSValue Number_Constructor(Context *cx, const JSValue& thisValue, JSValue *argv, uint32 argc)
{
JSValue v = thisValue;
@@ -2609,6 +2676,7 @@ void Context::initBuiltins()
{ "forin", Object_Type, 0, Object_forin },
{ "next", Object_Type, 0, Object_next },
{ "done", Object_Type, 0, Object_done },
{ "valueOf", Object_Type, 0, Object_valueOf },
{ NULL }
};
ProtoFunDef functionProtos[] =
@@ -2616,6 +2684,8 @@ void Context::initBuiltins()
{ "toString", String_Type, 0, Function_toString },
{ "toSource", String_Type, 0, Function_toString },
{ "hasInstance", Boolean_Type, 1, Function_hasInstance },
{ "call", Object_Type, 1, Function_call },
{ "apply", Object_Type, 2, Function_apply },
{ NULL }
};
ProtoFunDef numberProtos[] =