ExecutionContext *ctx = needsActivation ? context->engine->newContext() : &k;
ctx->initCallContext(context, thisObject, this, args, argc);
- Value result = call(ctx);
- ctx->leaveCallContext();
- return result;
-}
-
-Value FunctionObject::callDirect(ExecutionContext *context, Value thisObject, Value *args, int argc)
-{
- ExecutionContext k;
- ExecutionContext *ctx = needsActivation ? context->engine->newContext() : &k;
-
- ctx->initCallContext(context, thisObject, this, args, argc);
- maybeAdjustThisObjectForDirectCall(ctx, thisObject);
+ if (isBuiltinFunction) {
+ // Built-in functions allow for the this object to be null or undefined. This overrides
+ // the behaviour of changing thisObject to the global object if null/undefined and allows
+ // the built-in functions for example to throw a type error if null is passed.
+ if (thisObject.isNull() || thisObject.isUndefined())
+ ctx->thisObject = thisObject;
+ }
Value result = call(ctx);
ctx->leaveCallContext();
return result;
if (!o)
ctx->throwTypeError();
- return o->callDirect(ctx, thisArg, args.data(), args.size());
+ return o->call(ctx, thisArg, args.data(), args.size());
}
Value FunctionPrototype::method_call(ExecutionContext *ctx)
if (!o)
ctx->throwTypeError();
- return o->callDirect(ctx, thisArg, args.data(), args.size());
+ return o->call(ctx, thisArg, args.data(), args.size());
}
Value FunctionPrototype::method_bind(ExecutionContext *ctx)
, code(code)
{
this->name = name;
+ isBuiltinFunction = true;
}
Value BuiltinFunction::construct(ExecutionContext *ctx)
return Value::undefinedValue();
}
-void BuiltinFunction::maybeAdjustThisObjectForDirectCall(ExecutionContext *context, Value thisArg)
-{
- // Built-in functions allow for the this object to be null or undefined. This overrides
- // the behaviour of changing thisObject to the global object if null/undefined and allows
- // the built-in functions for example to throw a type error if null is passed.
- if (thisArg.isNull() || thisArg.isUndefined())
- context->thisObject = thisArg;
-}
-
-
BoundFunction::BoundFunction(ExecutionContext *scope, FunctionObject *target, Value boundThis, const QVector<Value> &boundArgs)
: FunctionObject(scope)
, target(target)
virtual Value construct(ExecutionContext *context, Value *args, int argc);
virtual Value call(ExecutionContext *context, Value thisObject, Value *args, int argc);
- // Nothing to do in the default implementation, only _native_ functions might change context->thisObject.
- virtual void maybeAdjustThisObjectForDirectCall(ExecutionContext* /*context*/, Value /*thisArg*/) { }
- Value callDirect(ExecutionContext *context, Value thisObject, Value *args, int argc);
virtual struct ScriptFunction *asScriptFunction() { return 0; }
BuiltinFunction(ExecutionContext *scope, String *name, Value (*code)(ExecutionContext *));
virtual Value call(ExecutionContext *ctx) { return code(ctx); }
virtual Value construct(ExecutionContext *ctx);
- virtual void maybeAdjustThisObjectForDirectCall(ExecutionContext *context, Value thisArg);
};
struct ScriptFunction: FunctionObject {
void operator = (const Managed &other);
protected:
- Managed() : markBit(0), inUse(1), extensible(true), isArray(false), isString(false), unused(0) { }
+ Managed() : markBit(0), inUse(1), extensible(true), isArray(false), isString(false), isBuiltinFunction(false), unused(0) { }
virtual ~Managed();
public:
quintptr extensible : 1; // used by Object
quintptr isArray : 1; // used by Object & Array
quintptr isString : 1; // used by Object & StringObject
+ quintptr isBuiltinFunction : 1; // used by FunctionObject
quintptr needsActivation : 1; // used by FunctionObject
quintptr usesArgumentsObject : 1; // used by FunctionObject
quintptr strictMode : 1; // used by FunctionObject
#if CPU(X86_64)
- quintptr unused : 56;
+ quintptr unused : 55;
#elif CPU(X86)
- quintptr unused : 24;
+ quintptr unused : 23;
#else
#error "implement me"
#endif