+ return vm.getHostFunction(nativeFunction, nativeConstructor);
+}
+
+JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
+{
+ NativeExecutable* executable = getNativeExecutable(vm, nativeFunction, intrinsic, nativeConstructor);
+ JSFunction* function = new (NotNull, allocateCell<JSFunction>(vm.heap)) JSFunction(vm, globalObject, globalObject->functionStructure());
+ // Can't do this during initialization because getHostFunction might do a GC allocation.
+ function->finishCreation(vm, executable, length, name);
+ return function;
+}
+
+class JSStdFunction : public JSFunction {
+public:
+ JSStdFunction(VM& vm, JSGlobalObject* object, Structure* structure, NativeStdFunction&& function)
+ : JSFunction(vm, object, structure)
+ , stdFunction(WTF::move(function)) { }
+
+ NativeStdFunction stdFunction;
+};
+
+static EncodedJSValue JSC_HOST_CALL runStdFunction(ExecState* state)
+{
+ JSStdFunction* jsFunction = jsCast<JSStdFunction*>(state->callee());
+ ASSERT(jsFunction);
+ return jsFunction->stdFunction(state);
+}
+
+JSFunction* JSFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, NativeStdFunction&& nativeStdFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
+{
+ NativeExecutable* executable = getNativeExecutable(vm, runStdFunction, intrinsic, nativeConstructor);
+ JSStdFunction* function = new (NotNull, allocateCell<JSStdFunction>(vm.heap)) JSStdFunction(vm, globalObject, globalObject->functionStructure(), WTF::move(nativeStdFunction));
+ // Can't do this during initialization because getHostFunction might do a GC allocation.
+ function->finishCreation(vm, executable, length, name);
+ return function;
+}
+
+JSFunction::JSFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+ : Base(vm, globalObject, structure)
+ , m_executable()
+{
+}
+
+void JSFunction::finishCreation(VM& vm, NativeExecutable* executable, int length, const String& name)
+{
+ Base::finishCreation(vm);
+ ASSERT(inherits(info()));
+ m_executable.set(vm, this, executable);
+ putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
+ putDirect(vm, vm.propertyNames->length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
+}
+
+JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject)
+{
+ JSFunction* function = create(vm, executable, globalObject);
+ function->putDirect(vm, vm.propertyNames->name, jsString(&vm, executable->name().string()), DontDelete | ReadOnly | DontEnum);
+ function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), DontDelete | ReadOnly | DontEnum);
+ return function;
+}
+
+JSFunction* JSFunction::createBuiltinFunction(VM& vm, FunctionExecutable* executable, JSGlobalObject* globalObject, const String& name)
+{
+ JSFunction* function = create(vm, executable, globalObject);
+ function->putDirect(vm, vm.propertyNames->name, jsString(&vm, name), DontDelete | ReadOnly | DontEnum);
+ function->putDirect(vm, vm.propertyNames->length, jsNumber(executable->parameterCount()), DontDelete | ReadOnly | DontEnum);
+ return function;
+}
+
+FunctionRareData* JSFunction::allocateAndInitializeRareData(ExecState* exec, size_t inlineCapacity)
+{
+ ASSERT(!m_rareData);
+ VM& vm = exec->vm();
+ JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
+ if (!prototype)
+ prototype = globalObject()->objectPrototype();
+ FunctionRareData* rareData = FunctionRareData::create(vm, prototype, inlineCapacity);
+
+ // A DFG compilation thread may be trying to read the rare data
+ // We want to ensure that it sees it properly allocated
+ WTF::storeStoreFence();
+
+ m_rareData.set(vm, this, rareData);
+ return m_rareData.get();
+}
+
+FunctionRareData* JSFunction::initializeRareData(ExecState* exec, size_t inlineCapacity)
+{
+ ASSERT(!!m_rareData);
+ VM& vm = exec->vm();
+ JSObject* prototype = jsDynamicCast<JSObject*>(get(exec, vm.propertyNames->prototype));
+ if (!prototype)
+ prototype = globalObject()->objectPrototype();
+ m_rareData->initialize(globalObject()->vm(), prototype, inlineCapacity);
+ return m_rareData.get();
+}
+
+String JSFunction::name(ExecState* exec)
+{
+ return get(exec, exec->vm().propertyNames->name).toWTFString(exec);
+}
+
+String JSFunction::displayName(ExecState* exec)
+{
+ JSValue displayName = getDirect(exec->vm(), exec->vm().propertyNames->displayName);
+
+ if (displayName && isJSString(displayName))
+ return asString(displayName)->tryGetValue();
+
+ return String();