EncodedJSValue JSC_HOST_CALL hasInstanceBoundFunction(ExecState* exec) { JSBoundFunction* boundObject = jsCast<JSBoundFunction*>(exec->uncheckedArgument(0)); JSValue value = exec->uncheckedArgument(1); return JSValue::encode(jsBoolean(boundObject->targetFunction()->hasInstance(exec, value))); }
JSBoundFunction* JSBoundFunction::create(ExecState* exec, JSGlobalObject* globalObject, JSObject* targetFunction, JSValue boundThis, JSValue boundArgs, int length, const String& name) { ConstructData constructData; ConstructType constructType = JSC::getConstructData(targetFunction, constructData); bool canConstruct = constructType != ConstructTypeNone; NativeExecutable* executable = exec->vm().getHostFunction(boundFunctionCall, canConstruct ? boundFunctionConstruct : callHostFunctionAsConstructor); JSBoundFunction* function = new (NotNull, allocateCell<JSBoundFunction>(*exec->heap())) JSBoundFunction(exec, globalObject, globalObject->boundFunctionStructure(), targetFunction, boundThis, boundArgs); function->finishCreation(exec, executable, length, name); return function; }
void JSBoundFunction::visitChildren(JSCell* cell, SlotVisitor& visitor) { JSBoundFunction* thisObject = jsCast<JSBoundFunction*>(cell); ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); Base::visitChildren(thisObject, visitor); visitor.append(&thisObject->m_targetFunction); visitor.append(&thisObject->m_boundThis); visitor.append(&thisObject->m_boundArgs); }
EncodedJSValue JSC_HOST_CALL boundThisNoArgsFunctionConstruct(ExecState* exec) { JSBoundFunction* boundFunction = jsCast<JSBoundFunction*>(exec->jsCallee()); MarkedArgumentBuffer args; for (unsigned i = 0; i < exec->argumentCount(); ++i) args.append(exec->uncheckedArgument(i)); JSFunction* targetFunction = jsCast<JSFunction*>(boundFunction->targetFunction()); ConstructData constructData; ConstructType constructType = getConstructData(targetFunction, constructData); ASSERT(constructType != ConstructType::None); return JSValue::encode(construct(exec, targetFunction, constructType, constructData, args)); }
EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState* exec) { JSBoundFunction* boundFunction = jsCast<JSBoundFunction*>(exec->callee()); ASSERT(isJSArray(boundFunction->boundArgs())); // Currently this is true! JSArray* boundArgs = asArray(boundFunction->boundArgs()); MarkedArgumentBuffer args; for (unsigned i = 0; i < boundArgs->length(); ++i) args.append(boundArgs->getIndexQuickly(i)); for (unsigned i = 0; i < exec->argumentCount(); ++i) args.append(exec->argument(i)); JSObject* targetFunction = boundFunction->targetFunction(); ConstructData constructData; ConstructType constructType = getConstructData(targetFunction, constructData); ASSERT(constructType != ConstructTypeNone); return JSValue::encode(construct(exec, targetFunction, constructType, constructData, args)); }
EncodedJSValue JSC_HOST_CALL boundThisNoArgsFunctionCall(ExecState* exec) { JSBoundFunction* boundFunction = jsCast<JSBoundFunction*>(exec->jsCallee()); MarkedArgumentBuffer args; for (unsigned i = 0; i < exec->argumentCount(); ++i) args.append(exec->uncheckedArgument(i)); JSFunction* targetFunction = jsCast<JSFunction*>(boundFunction->targetFunction()); ExecutableBase* executable = targetFunction->executable(); if (executable->hasJITCodeForCall()) { // Force the executable to cache its arity entrypoint. executable->entrypointFor(CodeForCall, MustCheckArity); } CallData callData; CallType callType = getCallData(targetFunction, callData); ASSERT(callType != CallType::None); return JSValue::encode(call(exec, targetFunction, callType, callData, boundFunction->boundThis(), args)); }
EncodedJSValue JSC_HOST_CALL boundFunctionCall(ExecState* exec) { JSBoundFunction* boundFunction = jsCast<JSBoundFunction*>(exec->jsCallee()); JSArray* boundArgs = boundFunction->boundArgs(); MarkedArgumentBuffer args; if (boundArgs) { for (unsigned i = 0; i < boundArgs->length(); ++i) args.append(boundArgs->getIndexQuickly(i)); } for (unsigned i = 0; i < exec->argumentCount(); ++i) args.append(exec->uncheckedArgument(i)); JSObject* targetFunction = boundFunction->targetFunction(); CallData callData; CallType callType = getCallData(targetFunction, callData); ASSERT(callType != CallType::None); return JSValue::encode(call(exec, targetFunction, callType, callData, boundFunction->boundThis(), args)); }
JSBoundFunction* JSBoundFunction::create(VM& vm, ExecState* exec, JSGlobalObject* globalObject, JSObject* targetFunction, JSValue boundThis, JSArray* boundArgs, int length, const String& name) { auto scope = DECLARE_THROW_SCOPE(vm); ConstructData constructData; ConstructType constructType = JSC::getConstructData(targetFunction, constructData); bool canConstruct = constructType != ConstructType::None; bool slowCase = boundArgs || !getJSFunction(targetFunction); NativeExecutable* executable = vm.getHostFunction( slowCase ? boundFunctionCall : boundThisNoArgsFunctionCall, slowCase ? NoIntrinsic : BoundThisNoArgsFunctionCallIntrinsic, canConstruct ? (slowCase ? boundFunctionConstruct : boundThisNoArgsFunctionConstruct) : callHostFunctionAsConstructor, nullptr, name); Structure* structure = getBoundFunctionStructure(vm, exec, globalObject, targetFunction); RETURN_IF_EXCEPTION(scope, nullptr); JSBoundFunction* function = new (NotNull, allocateCell<JSBoundFunction>(vm.heap)) JSBoundFunction(vm, globalObject, structure, targetFunction, boundThis, boundArgs); function->finishCreation(vm, executable, length); return function; }