[ES6] Support Reflect.construct
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Mar 2016 17:01:04 +0000 (17:01 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 5 Mar 2016 17:01:04 +0000 (17:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147330

Reviewed by Saam Barati.

Source/JavaScriptCore:

Based on Saam's r196868, this patch adds support for Reflect.construct.
This patch implements OrdinaryCreateFromConstructor[1] for fallback cases.
This path is rarely taken. For example,

    Reflect.construct(function () { }, [], Map);

In this case, the `new.target` becomes `Map`.
So we should create an object that `__proto__` is `Map.prototype`.

And to allow forward declaration (and encouraging strong type checking), we change
ConstructType, CallType to C++11 enum class.

[1]: http://ecma-international.org/ecma-262/6.0/#sec-ordinarycreatefromconstructor

* API/JSCallbackConstructor.cpp:
(JSC::JSCallbackConstructor::getConstructData):
* API/JSCallbackFunction.cpp:
(JSC::JSCallbackFunction::getCallData):
* API/JSCallbackObjectFunctions.h:
(JSC::JSCallbackObject<Parent>::getConstructData):
(JSC::JSCallbackObject<Parent>::getCallData):
* API/JSObjectRef.cpp:
(JSObjectIsFunction):
(JSObjectCallAsFunction):
(JSObjectIsConstructor):
(JSObjectCallAsConstructor):
* API/ObjCCallbackFunction.mm:
(JSC::ObjCCallbackFunction::getCallData):
(JSC::ObjCCallbackFunction::getConstructData):
* bindings/ScriptFunctionCall.cpp:
(Deprecated::ScriptFunctionCall::call):
* bindings/ScriptValue.cpp:
(Deprecated::ScriptValue::isFunction):
* builtins/ReflectObject.js:
* dfg/DFGOperations.cpp:
* inspector/InjectedScriptManager.cpp:
(Inspector::InjectedScriptManager::createInjectedScript):
* interpreter/Interpreter.cpp:
(JSC::sizeOfVarargs):
(JSC::Interpreter::execute):
(JSC::Interpreter::executeCall):
(JSC::Interpreter::executeConstruct):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::handleHostCall):
* runtime/ArrayConstructor.cpp:
(JSC::ArrayConstructor::getConstructData):
(JSC::ArrayConstructor::getCallData):
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncToString):
(JSC::arrayProtoFuncToLocaleString):
(JSC::getLength): Deleted.
* runtime/BooleanConstructor.cpp:
(JSC::BooleanConstructor::getConstructData):
(JSC::BooleanConstructor::getCallData):
* runtime/CallData.cpp:
(JSC::call):
* runtime/CallData.h:
* runtime/CommonSlowPaths.cpp:
(JSC::SLOW_PATH_DECL):
* runtime/ConstructData.cpp:
(JSC::construct):
* runtime/ConstructData.h:
* runtime/DateConstructor.cpp:
(JSC::DateConstructor::getConstructData):
(JSC::DateConstructor::getCallData):
* runtime/DatePrototype.cpp:
(JSC::dateProtoFuncToJSON):
* runtime/Error.h:
(JSC::StrictModeTypeErrorFunction::getConstructData):
(JSC::StrictModeTypeErrorFunction::getCallData):
* runtime/ErrorConstructor.cpp:
(JSC::ErrorConstructor::getConstructData):
(JSC::ErrorConstructor::getCallData):
* runtime/ExceptionHelpers.cpp:
(JSC::errorDescriptionForValue):
* runtime/FunctionConstructor.cpp:
(JSC::FunctionConstructor::getConstructData):
(JSC::FunctionConstructor::getCallData):
* runtime/FunctionPrototype.cpp:
(JSC::FunctionPrototype::getCallData):
(JSC::functionProtoFuncToString):
(JSC::functionProtoFuncBind):
* runtime/GeneratorFunctionConstructor.cpp:
(JSC::GeneratorFunctionConstructor::getCallData):
(JSC::GeneratorFunctionConstructor::getConstructData):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::getCallData):
* runtime/IntlCollatorConstructor.cpp:
(JSC::IntlCollatorConstructor::getConstructData):
(JSC::IntlCollatorConstructor::getCallData):
* runtime/IntlDateTimeFormatConstructor.cpp:
(JSC::IntlDateTimeFormatConstructor::getConstructData):
(JSC::IntlDateTimeFormatConstructor::getCallData):
* runtime/IntlNumberFormatConstructor.cpp:
(JSC::IntlNumberFormatConstructor::getConstructData):
(JSC::IntlNumberFormatConstructor::getCallData):
* runtime/IteratorOperations.cpp:
(JSC::iteratorNext):
(JSC::iteratorClose):
* runtime/JSArray.h:
(JSC::getLength):
* runtime/JSArrayBufferConstructor.cpp:
(JSC::JSArrayBufferConstructor::getConstructData):
(JSC::JSArrayBufferConstructor::getCallData):
* runtime/JSBoundFunction.cpp:
(JSC::boundFunctionCall):
(JSC::boundFunctionConstruct):
(JSC::JSBoundFunction::create):
* runtime/JSCJSValue.h:
* runtime/JSCJSValueInlines.h:
(JSC::JSValue::isFunction):
(JSC::JSValue::isConstructor):
* runtime/JSCell.cpp:
(JSC::JSCell::getCallData):
(JSC::JSCell::getConstructData):
* runtime/JSFunction.cpp:
(JSC::JSFunction::getCallData):
(JSC::JSFunction::getConstructData):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewWithArguments):
(JSC::JSGenericTypedArrayViewConstructor<ViewClass>::getConstructData):
(JSC::JSGenericTypedArrayViewConstructor<ViewClass>::getCallData):
* runtime/JSInternalPromise.cpp:
(JSC::JSInternalPromise::then):
* runtime/JSInternalPromiseConstructor.cpp:
(JSC::JSInternalPromiseConstructor::getConstructData):
(JSC::JSInternalPromiseConstructor::getCallData):
* runtime/JSJob.cpp:
(JSC::JSJobMicrotask::run):
* runtime/JSONObject.cpp:
(JSC::Stringifier::Stringifier):
(JSC::Stringifier::toJSONImpl):
(JSC::Stringifier::appendStringifiedValue):
(JSC::JSONProtoFuncParse):
* runtime/JSObject.cpp:
(JSC::callToPrimitiveFunction):
(JSC::JSObject::hasInstance):
(JSC::JSObject::getMethod):
* runtime/JSObject.h:
(JSC::getCallData):
(JSC::getConstructData):
* runtime/JSPromise.cpp:
(JSC::JSPromise::initialize):
* runtime/JSPromiseConstructor.cpp:
(JSC::JSPromiseConstructor::getConstructData):
(JSC::JSPromiseConstructor::getCallData):
* runtime/JSPromiseDeferred.cpp:
(JSC::newPromiseCapability):
(JSC::callFunction):
* runtime/JSTypedArrayViewConstructor.cpp:
(JSC::constructTypedArrayView):
(JSC::JSTypedArrayViewConstructor::getConstructData):
(JSC::JSTypedArrayViewConstructor::getCallData):
* runtime/MapConstructor.cpp:
(JSC::constructMap):
(JSC::MapConstructor::getConstructData):
(JSC::MapConstructor::getCallData):
* runtime/ModuleLoaderObject.cpp:
(JSC::ModuleLoaderObject::provide):
(JSC::ModuleLoaderObject::loadAndEvaluateModule):
(JSC::ModuleLoaderObject::loadModule):
(JSC::ModuleLoaderObject::linkAndEvaluateModule):
* runtime/NativeErrorConstructor.cpp:
(JSC::NativeErrorConstructor::getConstructData):
(JSC::NativeErrorConstructor::getCallData):
* runtime/NullGetterFunction.cpp:
(JSC::NullGetterFunction::getCallData):
(JSC::NullGetterFunction::getConstructData):
* runtime/NullSetterFunction.cpp:
(JSC::NullSetterFunction::getCallData):
(JSC::NullSetterFunction::getConstructData):
* runtime/NumberConstructor.cpp:
(JSC::NumberConstructor::getConstructData):
(JSC::NumberConstructor::getCallData):
* runtime/ObjectConstructor.cpp:
(JSC::ObjectConstructor::getConstructData):
(JSC::ObjectConstructor::getCallData):
(JSC::toPropertyDescriptor):
* runtime/ObjectPrototype.cpp:
(JSC::objectProtoFuncDefineGetter):
(JSC::objectProtoFuncDefineSetter):
(JSC::objectProtoFuncToLocaleString):
* runtime/Operations.cpp:
(JSC::jsTypeStringForValue):
(JSC::jsIsObjectTypeOrNull):
(JSC::jsIsFunctionType):
* runtime/ProxyConstructor.cpp:
(JSC::ProxyConstructor::getConstructData):
(JSC::ProxyConstructor::getCallData):
* runtime/ProxyObject.cpp:
(JSC::ProxyObject::finishCreation):
(JSC::performProxyCall):
(JSC::ProxyObject::getCallData):
(JSC::performProxyConstruct):
(JSC::ProxyObject::getConstructData):
* runtime/ReflectObject.cpp:
(JSC::reflectObjectConstruct):
* runtime/RegExpConstructor.cpp:
(JSC::RegExpConstructor::getConstructData):
(JSC::RegExpConstructor::getCallData):
* runtime/RuntimeType.h:
* runtime/SamplingProfiler.cpp:
(JSC::SamplingProfiler::processUnverifiedStackTraces):
* runtime/SetConstructor.cpp:
(JSC::constructSet):
(JSC::SetConstructor::getConstructData):
(JSC::SetConstructor::getCallData):
* runtime/StringConstructor.cpp:
(JSC::StringConstructor::getConstructData):
(JSC::StringConstructor::getCallData):
* runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):
(JSC::operationStringProtoFuncReplaceRegExpEmptyStr):
(JSC::operationStringProtoFuncReplaceRegExpString):
(JSC::replaceUsingStringSearch):
* runtime/SymbolConstructor.cpp:
(JSC::SymbolConstructor::getConstructData):
(JSC::SymbolConstructor::getCallData):
* runtime/WeakMapConstructor.cpp:
(JSC::constructWeakMap):
(JSC::WeakMapConstructor::getConstructData):
(JSC::WeakMapConstructor::getCallData):
* runtime/WeakSetConstructor.cpp:
(JSC::constructWeakSet):
(JSC::WeakSetConstructor::getConstructData):
(JSC::WeakSetConstructor::getCallData):
* tests/es6.yaml:
* tests/stress/reflect-construct.js: Added.
(shouldBe):
(shouldThrow):
(shouldThrow.array.get length):
(shouldThrow.array.get 0):
(array.get length):
(array.get 0):
(shouldBe.Reflect.construct):
(shouldBe.Reflect.construct.Hello):
(3.shouldBe.Reflect.construct.Hello):
(3.newTarget):
(0.shouldBe.Reflect.construct):
(shouldBe.A):
(shouldBe.B):
(nativeConstructorTest.DerivedMap):
(nativeConstructorTest.FailedMap):
(set noInline):

Source/WebCore:

* Modules/plugins/QuickTimePluginReplacement.mm:
(WebCore::QuickTimePluginReplacement::installReplacement):
* bindings/js/CallbackFunction.cpp:
(WebCore::checkFunctionOnlyCallback):
* bindings/js/JSCallbackData.cpp:
(WebCore::JSCallbackData::invokeCallback):
* bindings/js/JSCustomElementInterface.cpp:
(WebCore::JSCustomElementInterface::constructElement):
(WebCore::JSCustomElementInterface::attributeChanged):
* bindings/js/JSCustomXPathNSResolver.cpp:
(WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
* bindings/js/JSDOMBinding.cpp:
(WebCore::callFunctionWithCurrentArguments):
(WebCore::DOMConstructorObject::getCallData):
* bindings/js/JSDOMConstructor.h:
(WebCore::JSDOMConstructorNotConstructable::getCallData):
(WebCore::JSDOMConstructor<JSClass>::getConstructData):
(WebCore::JSDOMNamedConstructor<JSClass>::getConstructData):
(WebCore::JSBuiltinConstructor<JSClass>::getConstructData):
* bindings/js/JSDOMPromise.cpp:
(WebCore::DeferredWrapper::callFunction):
* bindings/js/JSDocumentCustom.cpp:
(WebCore::JSDocument::defineElement):
* bindings/js/JSErrorHandler.cpp:
(WebCore::JSErrorHandler::handleEvent):
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
* bindings/js/JSHTMLAllCollectionCustom.cpp:
(WebCore::JSHTMLAllCollection::getCallData):
* bindings/js/JSHTMLDocumentCustom.cpp:
(WebCore::JSHTMLDocument::open):
* bindings/js/JSKeyValueIterator.h:
(WebCore::keyValueIteratorForEach):
* bindings/js/JSMainThreadExecStateInstrumentation.h:
(WebCore::JSMainThreadExecState::instrumentFunctionCall):
(WebCore::JSMainThreadExecState::instrumentFunctionConstruct):
* bindings/js/JSMutationCallback.cpp:
(WebCore::JSMutationCallback::call):
* bindings/js/JSMutationObserverCustom.cpp:
(WebCore::constructJSMutationObserver):
* bindings/js/JSPluginElementFunctions.cpp:
(WebCore::callPlugin):
(WebCore::pluginElementGetCallData):
* bindings/js/ScheduledAction.cpp:
(WebCore::ScheduledAction::create):
(WebCore::ScheduledAction::executeFunctionInContext):
* bindings/objc/WebScriptObject.mm:
(-[WebScriptObject callWebScriptMethod:withArguments:]):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateConstructorHelperMethods):
* bindings/scripts/test/JS/JSFloat64Array.cpp:
(WebCore::JSFloat64ArrayConstructor::getConstructData):
* bindings/scripts/test/JS/JSTestInterface.cpp:
(WebCore::JSTestInterfaceConstructor::getConstructData):
* bridge/NP_jsobject.cpp:
(_NPN_InvokeDefault):
(_NPN_Invoke):
(_NPN_Construct):
* bridge/objc/objc_runtime.mm:
(JSC::Bindings::ObjcFallbackObjectImp::getCallData):
* bridge/runtime_method.cpp:
(JSC::RuntimeMethod::getCallData):
* bridge/runtime_object.cpp:
(JSC::Bindings::RuntimeObject::getCallData):
(JSC::Bindings::RuntimeObject::getConstructData):
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::updateCaptionContainer):
(WebCore::HTMLMediaElement::didAddUserAgentShadowRoot):
(WebCore::HTMLMediaElement::getCurrentMediaControlsStatus):
* html/HTMLPlugInImageElement.cpp:
(WebCore::HTMLPlugInImageElement::didAddUserAgentShadowRoot):
* testing/Internals.cpp:
(WebCore::Internals::isReadableStreamDisturbed):

Source/WebKit/mac:

* Plugins/Hosted/NetscapePluginInstanceProxy.mm:
(WebKit::NetscapePluginInstanceProxy::invoke):
(WebKit::NetscapePluginInstanceProxy::invokeDefault):
(WebKit::NetscapePluginInstanceProxy::construct):

Source/WebKit/win:

* Plugins/PluginPackage.cpp:
(WebCore::NPN_Invoke):

Source/WebKit2:

* WebProcess/Plugins/Netscape/JSNPMethod.cpp:
(WebKit::JSNPMethod::getCallData):
* WebProcess/Plugins/Netscape/JSNPObject.cpp:
(WebKit::JSNPObject::getCallData):
(WebKit::JSNPObject::getConstructData):
* WebProcess/Plugins/Netscape/NPJSObject.cpp:
(WebKit::NPJSObject::hasMethod):
(WebKit::NPJSObject::construct):
(WebKit::NPJSObject::invoke):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@197614 268f45cc-cd09-0410-ab3c-d52691b4dbfc

115 files changed:
Source/JavaScriptCore/API/JSCallbackConstructor.cpp
Source/JavaScriptCore/API/JSCallbackFunction.cpp
Source/JavaScriptCore/API/JSCallbackObjectFunctions.h
Source/JavaScriptCore/API/JSObjectRef.cpp
Source/JavaScriptCore/API/ObjCCallbackFunction.mm
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/bindings/ScriptFunctionCall.cpp
Source/JavaScriptCore/bindings/ScriptValue.cpp
Source/JavaScriptCore/builtins/ReflectObject.js
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/inspector/InjectedScriptManager.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/JITOperations.cpp
Source/JavaScriptCore/llint/LLIntSlowPaths.cpp
Source/JavaScriptCore/runtime/ArrayConstructor.cpp
Source/JavaScriptCore/runtime/ArrayPrototype.cpp
Source/JavaScriptCore/runtime/BooleanConstructor.cpp
Source/JavaScriptCore/runtime/CallData.cpp
Source/JavaScriptCore/runtime/CallData.h
Source/JavaScriptCore/runtime/CommonSlowPaths.cpp
Source/JavaScriptCore/runtime/ConstructData.cpp
Source/JavaScriptCore/runtime/ConstructData.h
Source/JavaScriptCore/runtime/DateConstructor.cpp
Source/JavaScriptCore/runtime/DatePrototype.cpp
Source/JavaScriptCore/runtime/Error.h
Source/JavaScriptCore/runtime/ErrorConstructor.cpp
Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
Source/JavaScriptCore/runtime/FunctionConstructor.cpp
Source/JavaScriptCore/runtime/FunctionPrototype.cpp
Source/JavaScriptCore/runtime/GeneratorFunctionConstructor.cpp
Source/JavaScriptCore/runtime/InternalFunction.cpp
Source/JavaScriptCore/runtime/IntlCollatorConstructor.cpp
Source/JavaScriptCore/runtime/IntlDateTimeFormatConstructor.cpp
Source/JavaScriptCore/runtime/IntlNumberFormatConstructor.cpp
Source/JavaScriptCore/runtime/IteratorOperations.cpp
Source/JavaScriptCore/runtime/JSArray.h
Source/JavaScriptCore/runtime/JSArrayBufferConstructor.cpp
Source/JavaScriptCore/runtime/JSBoundFunction.cpp
Source/JavaScriptCore/runtime/JSCJSValue.h
Source/JavaScriptCore/runtime/JSCJSValueInlines.h
Source/JavaScriptCore/runtime/JSCell.cpp
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewConstructorInlines.h
Source/JavaScriptCore/runtime/JSInternalPromise.cpp
Source/JavaScriptCore/runtime/JSInternalPromiseConstructor.cpp
Source/JavaScriptCore/runtime/JSJob.cpp
Source/JavaScriptCore/runtime/JSONObject.cpp
Source/JavaScriptCore/runtime/JSObject.cpp
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSPromise.cpp
Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
Source/JavaScriptCore/runtime/JSPromiseDeferred.cpp
Source/JavaScriptCore/runtime/JSTypedArrayViewConstructor.cpp
Source/JavaScriptCore/runtime/MapConstructor.cpp
Source/JavaScriptCore/runtime/ModuleLoaderObject.cpp
Source/JavaScriptCore/runtime/NativeErrorConstructor.cpp
Source/JavaScriptCore/runtime/NullGetterFunction.cpp
Source/JavaScriptCore/runtime/NullSetterFunction.cpp
Source/JavaScriptCore/runtime/NumberConstructor.cpp
Source/JavaScriptCore/runtime/ObjectConstructor.cpp
Source/JavaScriptCore/runtime/ObjectPrototype.cpp
Source/JavaScriptCore/runtime/Operations.cpp
Source/JavaScriptCore/runtime/ProxyConstructor.cpp
Source/JavaScriptCore/runtime/ProxyObject.cpp
Source/JavaScriptCore/runtime/ReflectObject.cpp
Source/JavaScriptCore/runtime/RegExpConstructor.cpp
Source/JavaScriptCore/runtime/RuntimeType.h
Source/JavaScriptCore/runtime/SamplingProfiler.cpp
Source/JavaScriptCore/runtime/SetConstructor.cpp
Source/JavaScriptCore/runtime/StringConstructor.cpp
Source/JavaScriptCore/runtime/StringPrototype.cpp
Source/JavaScriptCore/runtime/SymbolConstructor.cpp
Source/JavaScriptCore/runtime/WeakMapConstructor.cpp
Source/JavaScriptCore/runtime/WeakSetConstructor.cpp
Source/JavaScriptCore/tests/es6.yaml
Source/JavaScriptCore/tests/stress/reflect-construct.js [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
Source/WebCore/bindings/js/CallbackFunction.cpp
Source/WebCore/bindings/js/JSCallbackData.cpp
Source/WebCore/bindings/js/JSCustomElementInterface.cpp
Source/WebCore/bindings/js/JSCustomXPathNSResolver.cpp
Source/WebCore/bindings/js/JSDOMBinding.cpp
Source/WebCore/bindings/js/JSDOMConstructor.h
Source/WebCore/bindings/js/JSDOMPromise.cpp
Source/WebCore/bindings/js/JSDocumentCustom.cpp
Source/WebCore/bindings/js/JSErrorHandler.cpp
Source/WebCore/bindings/js/JSEventListener.cpp
Source/WebCore/bindings/js/JSHTMLAllCollectionCustom.cpp
Source/WebCore/bindings/js/JSHTMLDocumentCustom.cpp
Source/WebCore/bindings/js/JSKeyValueIterator.h
Source/WebCore/bindings/js/JSMainThreadExecStateInstrumentation.h
Source/WebCore/bindings/js/JSMutationCallback.cpp
Source/WebCore/bindings/js/JSMutationObserverCustom.cpp
Source/WebCore/bindings/js/JSPluginElementFunctions.cpp
Source/WebCore/bindings/js/ScheduledAction.cpp
Source/WebCore/bindings/objc/WebScriptObject.mm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSFloat64Array.cpp
Source/WebCore/bindings/scripts/test/JS/JSTestInterface.cpp
Source/WebCore/bridge/NP_jsobject.cpp
Source/WebCore/bridge/objc/objc_runtime.mm
Source/WebCore/bridge/runtime_method.cpp
Source/WebCore/bridge/runtime_object.cpp
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLPlugInImageElement.cpp
Source/WebCore/testing/Internals.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Plugins/Hosted/NetscapePluginInstanceProxy.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/Plugins/PluginPackage.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPMethod.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/JSNPObject.cpp
Source/WebKit2/WebProcess/Plugins/Netscape/NPJSObject.cpp

index 65e66dc..4fa6eca 100644 (file)
@@ -68,7 +68,7 @@ void JSCallbackConstructor::destroy(JSCell* cell)
 ConstructType JSCallbackConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = APICallbackFunction::construct<JSCallbackConstructor>;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 } // namespace JSC
index 047fcd0..62ea951 100644 (file)
@@ -66,7 +66,7 @@ JSCallbackFunction* JSCallbackFunction::create(VM& vm, JSGlobalObject* globalObj
 CallType JSCallbackFunction::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = APICallbackFunction::call<JSCallbackFunction>;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace JSC
index 6e0a6ce..952039d 100644 (file)
@@ -400,10 +400,10 @@ ConstructType JSCallbackObject<Parent>::getConstructData(JSCell* cell, Construct
     for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
         if (jsClass->callAsConstructor) {
             constructData.native.function = construct;
-            return ConstructTypeHost;
+            return ConstructType::Host;
         }
     }
-    return ConstructTypeNone;
+    return ConstructType::None;
 }
 
 template <class Parent>
@@ -467,10 +467,10 @@ CallType JSCallbackObject<Parent>::getCallData(JSCell* cell, CallData& callData)
     for (JSClassRef jsClass = thisObject->classRef(); jsClass; jsClass = jsClass->parentClass) {
         if (jsClass->callAsFunction) {
             callData.native.function = call;
-            return CallTypeHost;
+            return CallType::Host;
         }
     }
-    return CallTypeNone;
+    return CallType::None;
 }
 
 template <class Parent>
index 0044ccd..1534bdc 100644 (file)
@@ -530,7 +530,7 @@ bool JSObjectIsFunction(JSContextRef ctx, JSObjectRef object)
     JSLockHolder locker(toJS(ctx));
     CallData callData;
     JSCell* cell = toJS(object);
-    return cell->methodTable()->getCallData(cell, callData) != CallTypeNone;
+    return cell->methodTable()->getCallData(cell, callData) != CallType::None;
 }
 
 JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -553,7 +553,7 @@ JSValueRef JSObjectCallAsFunction(JSContextRef ctx, JSObjectRef object, JSObject
 
     CallData callData;
     CallType callType = jsObject->methodTable()->getCallData(jsObject, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return 0;
 
     JSValueRef result = toRef(exec, profiledCall(exec, ProfilingReason::API, jsObject, callType, callData, jsThisObject, argList));
@@ -568,7 +568,7 @@ bool JSObjectIsConstructor(JSContextRef, JSObjectRef object)
         return false;
     JSObject* jsObject = toJS(object);
     ConstructData constructData;
-    return jsObject->methodTable()->getConstructData(jsObject, constructData) != ConstructTypeNone;
+    return jsObject->methodTable()->getConstructData(jsObject, constructData) != ConstructType::None;
 }
 
 JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
@@ -583,7 +583,7 @@ JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size
 
     ConstructData constructData;
     ConstructType constructType = jsObject->methodTable()->getConstructData(jsObject, constructData);
-    if (constructType == ConstructTypeNone)
+    if (constructType == ConstructType::None)
         return 0;
 
     MarkedArgumentBuffer argList;
index 6199c79..ea98806 100644 (file)
@@ -524,7 +524,7 @@ void ObjCCallbackFunction::destroy(JSCell* cell)
 CallType ObjCCallbackFunction::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = APICallbackFunction::call<ObjCCallbackFunction>;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 ConstructType ObjCCallbackFunction::getConstructData(JSCell* cell, ConstructData& constructData)
@@ -533,7 +533,7 @@ ConstructType ObjCCallbackFunction::getConstructData(JSCell* cell, ConstructData
     if (!callback->impl()->isConstructible())
         return Base::getConstructData(cell, constructData);
     constructData.native.function = APICallbackFunction::construct<ObjCCallbackFunction>;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 String ObjCCallbackFunctionImpl::name()
index 497b7ca..8ba611f 100644 (file)
@@ -1,3 +1,256 @@
+2016-03-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Support Reflect.construct
+        https://bugs.webkit.org/show_bug.cgi?id=147330
+
+        Reviewed by Saam Barati.
+
+        Based on Saam's r196868, this patch adds support for Reflect.construct.
+        This patch implements OrdinaryCreateFromConstructor[1] for fallback cases.
+        This path is rarely taken. For example,
+
+            Reflect.construct(function () { }, [], Map);
+
+        In this case, the `new.target` becomes `Map`.
+        So we should create an object that `__proto__` is `Map.prototype`.
+
+        And to allow forward declaration (and encouraging strong type checking), we change
+        ConstructType, CallType to C++11 enum class.
+
+        [1]: http://ecma-international.org/ecma-262/6.0/#sec-ordinarycreatefromconstructor
+
+        * API/JSCallbackConstructor.cpp:
+        (JSC::JSCallbackConstructor::getConstructData):
+        * API/JSCallbackFunction.cpp:
+        (JSC::JSCallbackFunction::getCallData):
+        * API/JSCallbackObjectFunctions.h:
+        (JSC::JSCallbackObject<Parent>::getConstructData):
+        (JSC::JSCallbackObject<Parent>::getCallData):
+        * API/JSObjectRef.cpp:
+        (JSObjectIsFunction):
+        (JSObjectCallAsFunction):
+        (JSObjectIsConstructor):
+        (JSObjectCallAsConstructor):
+        * API/ObjCCallbackFunction.mm:
+        (JSC::ObjCCallbackFunction::getCallData):
+        (JSC::ObjCCallbackFunction::getConstructData):
+        * bindings/ScriptFunctionCall.cpp:
+        (Deprecated::ScriptFunctionCall::call):
+        * bindings/ScriptValue.cpp:
+        (Deprecated::ScriptValue::isFunction):
+        * builtins/ReflectObject.js:
+        * dfg/DFGOperations.cpp:
+        * inspector/InjectedScriptManager.cpp:
+        (Inspector::InjectedScriptManager::createInjectedScript):
+        * interpreter/Interpreter.cpp:
+        (JSC::sizeOfVarargs):
+        (JSC::Interpreter::execute):
+        (JSC::Interpreter::executeCall):
+        (JSC::Interpreter::executeConstruct):
+        * jit/JITOperations.cpp:
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::handleHostCall):
+        * runtime/ArrayConstructor.cpp:
+        (JSC::ArrayConstructor::getConstructData):
+        (JSC::ArrayConstructor::getCallData):
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncToString):
+        (JSC::arrayProtoFuncToLocaleString):
+        (JSC::getLength): Deleted.
+        * runtime/BooleanConstructor.cpp:
+        (JSC::BooleanConstructor::getConstructData):
+        (JSC::BooleanConstructor::getCallData):
+        * runtime/CallData.cpp:
+        (JSC::call):
+        * runtime/CallData.h:
+        * runtime/CommonSlowPaths.cpp:
+        (JSC::SLOW_PATH_DECL):
+        * runtime/ConstructData.cpp:
+        (JSC::construct):
+        * runtime/ConstructData.h:
+        * runtime/DateConstructor.cpp:
+        (JSC::DateConstructor::getConstructData):
+        (JSC::DateConstructor::getCallData):
+        * runtime/DatePrototype.cpp:
+        (JSC::dateProtoFuncToJSON):
+        * runtime/Error.h:
+        (JSC::StrictModeTypeErrorFunction::getConstructData):
+        (JSC::StrictModeTypeErrorFunction::getCallData):
+        * runtime/ErrorConstructor.cpp:
+        (JSC::ErrorConstructor::getConstructData):
+        (JSC::ErrorConstructor::getCallData):
+        * runtime/ExceptionHelpers.cpp:
+        (JSC::errorDescriptionForValue):
+        * runtime/FunctionConstructor.cpp:
+        (JSC::FunctionConstructor::getConstructData):
+        (JSC::FunctionConstructor::getCallData):
+        * runtime/FunctionPrototype.cpp:
+        (JSC::FunctionPrototype::getCallData):
+        (JSC::functionProtoFuncToString):
+        (JSC::functionProtoFuncBind):
+        * runtime/GeneratorFunctionConstructor.cpp:
+        (JSC::GeneratorFunctionConstructor::getCallData):
+        (JSC::GeneratorFunctionConstructor::getConstructData):
+        * runtime/InternalFunction.cpp:
+        (JSC::InternalFunction::getCallData):
+        * runtime/IntlCollatorConstructor.cpp:
+        (JSC::IntlCollatorConstructor::getConstructData):
+        (JSC::IntlCollatorConstructor::getCallData):
+        * runtime/IntlDateTimeFormatConstructor.cpp:
+        (JSC::IntlDateTimeFormatConstructor::getConstructData):
+        (JSC::IntlDateTimeFormatConstructor::getCallData):
+        * runtime/IntlNumberFormatConstructor.cpp:
+        (JSC::IntlNumberFormatConstructor::getConstructData):
+        (JSC::IntlNumberFormatConstructor::getCallData):
+        * runtime/IteratorOperations.cpp:
+        (JSC::iteratorNext):
+        (JSC::iteratorClose):
+        * runtime/JSArray.h:
+        (JSC::getLength):
+        * runtime/JSArrayBufferConstructor.cpp:
+        (JSC::JSArrayBufferConstructor::getConstructData):
+        (JSC::JSArrayBufferConstructor::getCallData):
+        * runtime/JSBoundFunction.cpp:
+        (JSC::boundFunctionCall):
+        (JSC::boundFunctionConstruct):
+        (JSC::JSBoundFunction::create):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCJSValueInlines.h:
+        (JSC::JSValue::isFunction):
+        (JSC::JSValue::isConstructor):
+        * runtime/JSCell.cpp:
+        (JSC::JSCell::getCallData):
+        (JSC::JSCell::getConstructData):
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::getCallData):
+        (JSC::JSFunction::getConstructData):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::constructGenericTypedArrayViewWithArguments):
+        (JSC::JSGenericTypedArrayViewConstructor<ViewClass>::getConstructData):
+        (JSC::JSGenericTypedArrayViewConstructor<ViewClass>::getCallData):
+        * runtime/JSInternalPromise.cpp:
+        (JSC::JSInternalPromise::then):
+        * runtime/JSInternalPromiseConstructor.cpp:
+        (JSC::JSInternalPromiseConstructor::getConstructData):
+        (JSC::JSInternalPromiseConstructor::getCallData):
+        * runtime/JSJob.cpp:
+        (JSC::JSJobMicrotask::run):
+        * runtime/JSONObject.cpp:
+        (JSC::Stringifier::Stringifier):
+        (JSC::Stringifier::toJSONImpl):
+        (JSC::Stringifier::appendStringifiedValue):
+        (JSC::JSONProtoFuncParse):
+        * runtime/JSObject.cpp:
+        (JSC::callToPrimitiveFunction):
+        (JSC::JSObject::hasInstance):
+        (JSC::JSObject::getMethod):
+        * runtime/JSObject.h:
+        (JSC::getCallData):
+        (JSC::getConstructData):
+        * runtime/JSPromise.cpp:
+        (JSC::JSPromise::initialize):
+        * runtime/JSPromiseConstructor.cpp:
+        (JSC::JSPromiseConstructor::getConstructData):
+        (JSC::JSPromiseConstructor::getCallData):
+        * runtime/JSPromiseDeferred.cpp:
+        (JSC::newPromiseCapability):
+        (JSC::callFunction):
+        * runtime/JSTypedArrayViewConstructor.cpp:
+        (JSC::constructTypedArrayView):
+        (JSC::JSTypedArrayViewConstructor::getConstructData):
+        (JSC::JSTypedArrayViewConstructor::getCallData):
+        * runtime/MapConstructor.cpp:
+        (JSC::constructMap):
+        (JSC::MapConstructor::getConstructData):
+        (JSC::MapConstructor::getCallData):
+        * runtime/ModuleLoaderObject.cpp:
+        (JSC::ModuleLoaderObject::provide):
+        (JSC::ModuleLoaderObject::loadAndEvaluateModule):
+        (JSC::ModuleLoaderObject::loadModule):
+        (JSC::ModuleLoaderObject::linkAndEvaluateModule):
+        * runtime/NativeErrorConstructor.cpp:
+        (JSC::NativeErrorConstructor::getConstructData):
+        (JSC::NativeErrorConstructor::getCallData):
+        * runtime/NullGetterFunction.cpp:
+        (JSC::NullGetterFunction::getCallData):
+        (JSC::NullGetterFunction::getConstructData):
+        * runtime/NullSetterFunction.cpp:
+        (JSC::NullSetterFunction::getCallData):
+        (JSC::NullSetterFunction::getConstructData):
+        * runtime/NumberConstructor.cpp:
+        (JSC::NumberConstructor::getConstructData):
+        (JSC::NumberConstructor::getCallData):
+        * runtime/ObjectConstructor.cpp:
+        (JSC::ObjectConstructor::getConstructData):
+        (JSC::ObjectConstructor::getCallData):
+        (JSC::toPropertyDescriptor):
+        * runtime/ObjectPrototype.cpp:
+        (JSC::objectProtoFuncDefineGetter):
+        (JSC::objectProtoFuncDefineSetter):
+        (JSC::objectProtoFuncToLocaleString):
+        * runtime/Operations.cpp:
+        (JSC::jsTypeStringForValue):
+        (JSC::jsIsObjectTypeOrNull):
+        (JSC::jsIsFunctionType):
+        * runtime/ProxyConstructor.cpp:
+        (JSC::ProxyConstructor::getConstructData):
+        (JSC::ProxyConstructor::getCallData):
+        * runtime/ProxyObject.cpp:
+        (JSC::ProxyObject::finishCreation):
+        (JSC::performProxyCall):
+        (JSC::ProxyObject::getCallData):
+        (JSC::performProxyConstruct):
+        (JSC::ProxyObject::getConstructData):
+        * runtime/ReflectObject.cpp:
+        (JSC::reflectObjectConstruct):
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpConstructor::getConstructData):
+        (JSC::RegExpConstructor::getCallData):
+        * runtime/RuntimeType.h:
+        * runtime/SamplingProfiler.cpp:
+        (JSC::SamplingProfiler::processUnverifiedStackTraces):
+        * runtime/SetConstructor.cpp:
+        (JSC::constructSet):
+        (JSC::SetConstructor::getConstructData):
+        (JSC::SetConstructor::getCallData):
+        * runtime/StringConstructor.cpp:
+        (JSC::StringConstructor::getConstructData):
+        (JSC::StringConstructor::getCallData):
+        * runtime/StringPrototype.cpp:
+        (JSC::replaceUsingRegExpSearch):
+        (JSC::operationStringProtoFuncReplaceRegExpEmptyStr):
+        (JSC::operationStringProtoFuncReplaceRegExpString):
+        (JSC::replaceUsingStringSearch):
+        * runtime/SymbolConstructor.cpp:
+        (JSC::SymbolConstructor::getConstructData):
+        (JSC::SymbolConstructor::getCallData):
+        * runtime/WeakMapConstructor.cpp:
+        (JSC::constructWeakMap):
+        (JSC::WeakMapConstructor::getConstructData):
+        (JSC::WeakMapConstructor::getCallData):
+        * runtime/WeakSetConstructor.cpp:
+        (JSC::constructWeakSet):
+        (JSC::WeakSetConstructor::getConstructData):
+        (JSC::WeakSetConstructor::getCallData):
+        * tests/es6.yaml:
+        * tests/stress/reflect-construct.js: Added.
+        (shouldBe):
+        (shouldThrow):
+        (shouldThrow.array.get length):
+        (shouldThrow.array.get 0):
+        (array.get length):
+        (array.get 0):
+        (shouldBe.Reflect.construct):
+        (shouldBe.Reflect.construct.Hello):
+        (3.shouldBe.Reflect.construct.Hello):
+        (3.newTarget):
+        (0.shouldBe.Reflect.construct):
+        (shouldBe.A):
+        (shouldBe.B):
+        (nativeConstructorTest.DerivedMap):
+        (nativeConstructorTest.FailedMap):
+        (set noInline):
+
 2016-03-04  Andreas Kling  <akling@apple.com>
 
         [iOS] Throw away compiled RegExp code when navigating to a new page.
index d6745be..6f01f2d 100644 (file)
@@ -129,7 +129,7 @@ Deprecated::ScriptValue ScriptFunctionCall::call(bool& hadException)
 
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return Deprecated::ScriptValue();
 
     JSValue result;
index 3e560dc..7ac7561 100644 (file)
@@ -94,7 +94,7 @@ bool ScriptValue::isObject() const
 bool ScriptValue::isFunction() const
 {
     CallData callData;
-    return getCallData(m_value.get(), callData) != CallTypeNone;
+    return getCallData(m_value.get(), callData) != CallType::None;
 }
 
 static RefPtr<InspectorValue> jsToInspectorValue(ExecState* scriptState, JSValue value, int maxDepth)
index 69c9828..46b752b 100644 (file)
@@ -23,7 +23,7 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.apply
+// https://tc39.github.io/ecma262/#sec-reflect.apply
 function apply(target, thisArgument, argumentsList)
 {
     "use strict";
@@ -37,7 +37,7 @@ function apply(target, thisArgument, argumentsList)
     return target.@apply(thisArgument, argumentsList);
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.deleteproperty
+// https://tc39.github.io/ecma262/#sec-reflect.deleteproperty
 function deleteProperty(target, propertyKey)
 {
     // Intentionally keep the code the sloppy mode to suppress the TypeError
@@ -49,7 +49,7 @@ function deleteProperty(target, propertyKey)
     return delete target[propertyKey];
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.has
+// https://tc39.github.io/ecma262/#sec-reflect.has
 function has(target, propertyKey)
 {
     "use strict";
index d863a7e..c8fa2d5 100644 (file)
@@ -167,6 +167,11 @@ JSCell* JIT_OPERATION operationCreateThis(ExecState* exec, JSObject* constructor
     if (constructor->type() == JSFunctionType)
         return constructEmptyObject(exec, jsCast<JSFunction*>(constructor)->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure());
 
+    JSValue proto = constructor->get(exec, exec->propertyNames().prototype);
+    if (vm.exception())
+        return nullptr;
+    if (proto.isObject())
+        return constructEmptyObject(exec, asObject(proto));
     return constructEmptyObject(exec);
 }
 
@@ -990,7 +995,7 @@ size_t JIT_OPERATION operationObjectIsObject(ExecState* exec, JSGlobalObject* gl
         return false;
     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
         CallData callData;
-        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+        if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
             return false;
     }
     
@@ -1010,7 +1015,7 @@ size_t JIT_OPERATION operationObjectIsFunction(ExecState* exec, JSGlobalObject*
         return true;
     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
         CallData callData;
-        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+        if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
             return true;
     }
     
@@ -1030,7 +1035,7 @@ JSCell* JIT_OPERATION operationTypeOfObject(ExecState* exec, JSGlobalObject* glo
         return vm.smallStrings.functionString();
     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
         CallData callData;
-        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+        if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
             return vm.smallStrings.functionString();
     }
     
@@ -1050,7 +1055,7 @@ int32_t JIT_OPERATION operationTypeOfObjectAsTypeofType(ExecState* exec, JSGloba
         return static_cast<int32_t>(TypeofType::Function);
     if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
         CallData callData;
-        if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+        if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
             return static_cast<int32_t>(TypeofType::Function);
     }
     
index 812ad3d..fcbf814 100644 (file)
@@ -147,7 +147,7 @@ Deprecated::ScriptObject InjectedScriptManager::createInjectedScript(const Strin
 
     CallData callData;
     CallType callType = getCallData(functionValue, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return Deprecated::ScriptObject();
 
     MarkedArgumentBuffer args;
index 2bd9893..a6bbe8b 100644 (file)
@@ -217,10 +217,7 @@ unsigned sizeOfVarargs(CallFrame* callFrame, JSValue arguments, uint32_t firstVa
         return 0;
     default:
         ASSERT(arguments.isObject());
-        if (isJSArray(cell))
-            length = jsCast<JSArray*>(cell)->length();
-        else
-            length = jsCast<JSObject*>(cell)->get(callFrame, callFrame->propertyNames().length).toUInt32(callFrame);
+        length = getLength(callFrame, jsCast<JSObject*>(cell));
         break;
     }
     
@@ -909,7 +906,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, J
                     return jsUndefined();
                 CallData callData;
                 CallType callType = getCallData(function, callData);
-                if (callType == CallTypeNone)
+                if (callType == CallType::None)
                     return callFrame->vm().throwException(callFrame, createNotAFunctionError(callFrame, function));
                 MarkedArgumentBuffer jsonArg;
                 jsonArg.append(JSONPValue);
@@ -986,7 +983,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
     if (vm.isCollectorBusy())
         return jsNull();
 
-    bool isJSCall = (callType == CallTypeJS);
+    bool isJSCall = (callType == CallType::JS);
     JSScope* scope = nullptr;
     CodeBlock* newCodeBlock;
     size_t argsCount = 1 + args.size(); // implicit "this" parameter
@@ -997,7 +994,7 @@ JSValue Interpreter::executeCall(CallFrame* callFrame, JSObject* function, CallT
         scope = callData.js.scope;
         globalObject = scope->globalObject();
     } else {
-        ASSERT(callType == CallTypeHost);
+        ASSERT(callType == CallType::Host);
         globalObject = function->globalObject();
     }
 
@@ -1056,7 +1053,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
     if (vm.isCollectorBusy())
         return checkedReturn(throwStackOverflowError(callFrame));
 
-    bool isJSConstruct = (constructType == ConstructTypeJS);
+    bool isJSConstruct = (constructType == ConstructType::JS);
     JSScope* scope = nullptr;
     CodeBlock* newCodeBlock;
     size_t argsCount = 1 + args.size(); // implicit "this" parameter
@@ -1067,7 +1064,7 @@ JSObject* Interpreter::executeConstruct(CallFrame* callFrame, JSObject* construc
         scope = constructData.js.scope;
         globalObject = scope->globalObject();
     } else {
-        ASSERT(constructType == ConstructTypeHost);
+        ASSERT(constructType == ConstructType::Host);
         globalObject = constructor->globalObject();
     }
 
index 80f09f0..7a88ca4 100644 (file)
@@ -700,9 +700,9 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, JSValue callee,
         CallData callData;
         CallType callType = getCallData(callee, callData);
     
-        ASSERT(callType != CallTypeJS);
+        ASSERT(callType != CallType::JS);
     
-        if (callType == CallTypeHost) {
+        if (callType == CallType::Host) {
             NativeCallFrameTracer tracer(vm, execCallee);
             execCallee->setCallee(asObject(callee));
             vm->hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
@@ -717,7 +717,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, JSValue callee,
                 reinterpret_cast<void*>(callLinkInfo->callMode() == CallMode::Tail ? ReuseTheFrame : KeepTheFrame));
         }
     
-        ASSERT(callType == CallTypeNone);
+        ASSERT(callType == CallType::None);
         exec->vm().throwException(exec, createNotAFunctionError(exec, callee));
         return encodeResult(
             vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(),
@@ -729,9 +729,9 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, JSValue callee,
     ConstructData constructData;
     ConstructType constructType = getConstructData(callee, constructData);
     
-    ASSERT(constructType != ConstructTypeJS);
+    ASSERT(constructType != ConstructType::JS);
     
-    if (constructType == ConstructTypeHost) {
+    if (constructType == ConstructType::Host) {
         NativeCallFrameTracer tracer(vm, execCallee);
         execCallee->setCallee(asObject(callee));
         vm->hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
@@ -744,7 +744,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, JSValue callee,
         return encodeResult(bitwise_cast<void*>(getHostCallReturnValue), reinterpret_cast<void*>(KeepTheFrame));
     }
     
-    ASSERT(constructType == ConstructTypeNone);
+    ASSERT(constructType == ConstructType::None);
     exec->vm().throwException(exec, createNotAConstructorError(exec, callee));
     return encodeResult(
         vm->getCTIStub(throwExceptionFromCallSlowPathGenerator).code().executableAddress(),
index 700af9c..7658779 100644 (file)
@@ -1100,9 +1100,9 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
         CallData callData;
         CallType callType = getCallData(callee, callData);
     
-        ASSERT(callType != CallTypeJS);
+        ASSERT(callType != CallType::JS);
     
-        if (callType == CallTypeHost) {
+        if (callType == CallType::Host) {
             NativeCallFrameTracer tracer(&vm, execCallee);
             execCallee->setCallee(asObject(callee));
             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
@@ -1114,7 +1114,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
         dataLog("Call callee is not a function: ", callee, "\n");
 #endif
 
-        ASSERT(callType == CallTypeNone);
+        ASSERT(callType == CallType::None);
         LLINT_CALL_THROW(exec, createNotAFunctionError(exec, callee));
     }
 
@@ -1123,9 +1123,9 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
     ConstructData constructData;
     ConstructType constructType = getConstructData(callee, constructData);
     
-    ASSERT(constructType != ConstructTypeJS);
+    ASSERT(constructType != ConstructType::JS);
     
-    if (constructType == ConstructTypeHost) {
+    if (constructType == ConstructType::Host) {
         NativeCallFrameTracer tracer(&vm, execCallee);
         execCallee->setCallee(asObject(callee));
         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
@@ -1137,7 +1137,7 @@ static SlowPathReturnType handleHostCall(ExecState* execCallee, Instruction* pc,
     dataLog("Constructor callee is not a function: ", callee, "\n");
 #endif
 
-    ASSERT(constructType == ConstructTypeNone);
+    ASSERT(constructType == ConstructType::None);
     LLINT_CALL_THROW(exec, createNotAConstructorError(exec, callee));
 }
 
index 73e61ff..0ec0548 100644 (file)
@@ -109,7 +109,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithArrayConstructor(ExecState* exe
 ConstructType ArrayConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithArrayConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 static EncodedJSValue JSC_HOST_CALL callArrayConstructor(ExecState* exec)
@@ -122,7 +122,7 @@ CallType ArrayConstructor::getCallData(JSCell*, CallData& callData)
 {
     // equivalent to 'new Array(....)'
     callData.native.function = callArrayConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 EncodedJSValue JSC_HOST_CALL arrayConstructorIsArray(ExecState* exec)
index 0c0e516..cf24cf6 100644 (file)
@@ -157,13 +157,6 @@ static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* object, unsi
     return slot.getValue(exec, index);
 }
 
-static ALWAYS_INLINE unsigned getLength(ExecState* exec, JSObject* obj)
-{
-    if (isJSArray(obj))
-        return jsCast<JSArray*>(obj)->length();
-    return obj->get(exec, exec->propertyNames().length).toUInt32(exec);
-}
-
 static ALWAYS_INLINE void putLength(ExecState* exec, JSObject* obj, JSValue value)
 {
     PutPropertySlot slot(obj);
@@ -342,11 +335,11 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToString(ExecState* exec)
         return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]"));
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return JSValue::encode(jsMakeNontrivialString(exec, "[object ", thisObject->methodTable(exec->vm())->className(thisObject), "]"));
 
     // 4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.
-    if (!isJSArray(thisObject) || callType != CallTypeHost || callData.native.function != arrayProtoFuncJoin)
+    if (!isJSArray(thisObject) || callType != CallType::Host || callData.native.function != arrayProtoFuncJoin)
         return JSValue::encode(call(exec, function, callType, callData, thisObject, exec->emptyList()));
 
     ASSERT(isJSArray(thisValue));
@@ -411,7 +404,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
                 return JSValue::encode(jsUndefined());
             CallData callData;
             CallType callType = getCallData(conversionFunction, callData);
-            if (callType != CallTypeNone) {
+            if (callType != CallType::None) {
                 element = call(exec, conversionFunction, callType, callData, element, arguments);
                 if (exec->hadException())
                 return JSValue::encode(jsUndefined());
@@ -433,7 +426,7 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncToLocaleString(ExecState* exec)
             return JSValue::encode(jsUndefined());
         CallData callData;
         CallType callType = getCallData(conversionFunction, callData);
-        if (callType != CallTypeNone) {
+        if (callType != CallType::None) {
             element = call(exec, conversionFunction, callType, callData, element, exec->emptyList());
             if (exec->hadException())
                 return JSValue::encode(jsUndefined());
index fd6671d..b3215e7 100644 (file)
@@ -60,7 +60,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithBooleanConstructor(ExecState* e
 ConstructType BooleanConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithBooleanConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 // ECMA 15.6.1
@@ -72,7 +72,7 @@ static EncodedJSValue JSC_HOST_CALL callBooleanConstructor(ExecState* exec)
 CallType BooleanConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callBooleanConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 JSObject* constructBooleanFromImmediateBoolean(ExecState* exec, JSGlobalObject* globalObject, JSValue immediateBooleanValue)
index 42c80dd..6d0f812 100644 (file)
@@ -36,7 +36,7 @@ namespace JSC {
 
 JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args)
 {
-    ASSERT(callType == CallTypeJS || callType == CallTypeHost);
+    ASSERT(callType == CallType::JS || callType == CallType::Host);
     return exec->interpreter()->executeCall(exec, asObject(functionObject), callType, callData, thisValue, args);
 }
 
index 45dbfbc..e90f702 100644 (file)
@@ -41,22 +41,24 @@ class FunctionExecutable;
 class JSObject;
 class JSScope;
 
-enum CallType {
-    CallTypeNone,
-    CallTypeHost,
-    CallTypeJS
+enum class CallType : unsigned {
+    None,
+    Host,
+    JS
 };
 
 typedef EncodedJSValue (JSC_HOST_CALL *NativeFunction)(ExecState*);
 
-union CallData {
-    struct {
-        NativeFunction function;
-    } native;
-    struct {
-        FunctionExecutable* functionExecutable;
-        JSScope* scope;
-    } js;
+struct CallData {
+    union {
+        struct {
+            NativeFunction function;
+        } native;
+        struct {
+            FunctionExecutable* functionExecutable;
+            JSScope* scope;
+        } js;
+    };
 };
 
 enum class ProfilingReason {
index 167c287..f78a182 100644 (file)
@@ -222,9 +222,9 @@ SLOW_PATH_DECL(slow_path_create_this)
 {
     BEGIN();
     JSObject* result;
-    JSCell* constructorAsCell = OP(2).jsValue().asCell();
-    if (constructorAsCell->type() == JSFunctionType) {
-        JSFunction* constructor = jsCast<JSFunction*>(constructorAsCell);
+    JSObject* constructorAsObject = asObject(OP(2).jsValue());
+    if (constructorAsObject->type() == JSFunctionType) {
+        JSFunction* constructor = jsCast<JSFunction*>(constructorAsObject);
         auto& cacheWriteBarrier = pc[4].u.jsCell;
         if (!cacheWriteBarrier)
             cacheWriteBarrier.set(exec->vm(), exec->codeBlock(), constructor);
@@ -234,8 +234,15 @@ SLOW_PATH_DECL(slow_path_create_this)
         size_t inlineCapacity = pc[3].u.operand;
         Structure* structure = constructor->rareData(exec, inlineCapacity)->objectAllocationProfile()->structure();
         result = constructEmptyObject(exec, structure);
-    } else
-        result = constructEmptyObject(exec);
+    } else {
+        // http://ecma-international.org/ecma-262/6.0/#sec-ordinarycreatefromconstructor
+        JSValue proto = constructorAsObject->get(exec, exec->propertyNames().prototype);
+        CHECK_EXCEPTION();
+        if (proto.isObject())
+            result = constructEmptyObject(exec, asObject(proto));
+        else
+            result = constructEmptyObject(exec);
+    }
     RETURN(result);
 }
 
index 0a4eecb..889aae8 100644 (file)
@@ -39,7 +39,7 @@ JSObject* construct(ExecState* exec, JSValue constructorObject, const ArgList& a
 {
     ConstructData constructData;
     ConstructType constructType = getConstructData(constructorObject, constructData);
-    if (constructType == ConstructTypeNone)
+    if (constructType == ConstructType::None)
         return throwTypeError(exec, errorMessage);
 
     return construct(exec, constructorObject, constructType, constructData, args, constructorObject);
@@ -48,7 +48,7 @@ JSObject* construct(ExecState* exec, JSValue constructorObject, const ArgList& a
 
 JSObject* construct(ExecState* exec, JSValue constructorObject, ConstructType constructType, const ConstructData& constructData, const ArgList& args, JSValue newTarget)
 {
-    ASSERT(constructType == ConstructTypeJS || constructType == ConstructTypeHost);
+    ASSERT(constructType == ConstructType::JS || constructType == ConstructType::Host);
     return exec->interpreter()->executeConstruct(exec, asObject(constructorObject), constructType, constructData, args, newTarget);
 }
 
index 7e9d55d..c644cd1 100644 (file)
@@ -40,20 +40,22 @@ class FunctionExecutable;
 class JSObject;
 class JSScope;
 
-enum ConstructType {
-    ConstructTypeNone,
-    ConstructTypeHost,
-    ConstructTypeJS
+enum class ConstructType : unsigned {
+    None,
+    Host,
+    JS
 };
 
-union ConstructData {
-    struct {
-        NativeFunction function;
-    } native;
-    struct {
-        FunctionExecutable* functionExecutable;
-        JSScope* scope;
-    } js;
+struct ConstructData {
+    union {
+        struct {
+            NativeFunction function;
+        } native;
+        struct {
+            FunctionExecutable* functionExecutable;
+            JSScope* scope;
+        } js;
+    };
 };
 
 // Convenience wrapper so you don't need to deal with CallData and CallType unless you are going to use them.
index cf00d21..fe1ee40 100644 (file)
@@ -187,7 +187,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithDateConstructor(ExecState* exec
 ConstructType DateConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithDateConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 // ECMA 15.9.2
@@ -202,7 +202,7 @@ static EncodedJSValue JSC_HOST_CALL callDate(ExecState* exec)
 CallType DateConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callDate;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 EncodedJSValue JSC_HOST_CALL dateParse(ExecState* exec)
index 4166124..a645eb3 100644 (file)
@@ -1117,7 +1117,7 @@ EncodedJSValue JSC_HOST_CALL dateProtoFuncToJSON(ExecState* exec)
 
     CallData callData;
     CallType callType = getCallData(toISOValue, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return throwVMError(exec, createTypeError(exec, ASCIILiteral("toISOString is not a function")));
 
     JSValue result = call(exec, asObject(toISOValue), callType, callData, object, exec->emptyList());
index a30c998..c511d69 100644 (file)
@@ -115,7 +115,7 @@ public:
     static ConstructType getConstructData(JSCell*, ConstructData& constructData)
     {
         constructData.native.function = constructThrowTypeError;
-        return ConstructTypeHost;
+        return ConstructType::Host;
     }
 
     static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
@@ -127,7 +127,7 @@ public:
     static CallType getCallData(JSCell*, CallData& callData)
     {
         callData.native.function = callThrowTypeError;
-        return CallTypeHost;
+        return CallType::Host;
     }
 
     DECLARE_INFO;
index e26dc12..57fd828 100644 (file)
@@ -60,7 +60,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::constructWithErrorConstructor(ExecStat
 ConstructType ErrorConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = Interpreter::constructWithErrorConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 EncodedJSValue JSC_HOST_CALL Interpreter::callErrorConstructor(ExecState* exec)
@@ -73,7 +73,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::callErrorConstructor(ExecState* exec)
 CallType ErrorConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = Interpreter::callErrorConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace JSC
index f9a5bb4..bbcd388 100644 (file)
@@ -90,7 +90,7 @@ JSString* errorDescriptionForValue(ExecState* exec, JSValue v)
     if (v.isObject()) {
         CallData callData;
         JSObject* object = asObject(v);
-        if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
+        if (object->methodTable()->getCallData(object, callData) != CallType::None)
             return exec->vm().smallStrings.functionString();
         return jsString(exec, JSObject::calculatedClassName(object));
     }
index 81f7562..d439066 100644 (file)
@@ -62,7 +62,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithFunctionConstructor(ExecState*
 ConstructType FunctionConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithFunctionConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 static EncodedJSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec)
@@ -75,7 +75,7 @@ static EncodedJSValue JSC_HOST_CALL callFunctionConstructor(ExecState* exec)
 CallType FunctionConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callFunctionConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 // ECMA 15.3.2 The Function Constructor
index 4ca55f9..2679af7 100644 (file)
@@ -77,7 +77,7 @@ static EncodedJSValue JSC_HOST_CALL callFunctionPrototype(ExecState*)
 CallType FunctionPrototype::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callFunctionPrototype;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec)
@@ -113,7 +113,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncToString(ExecState* exec)
         JSObject* object = asObject(thisValue);
         if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
             CallData callData;
-            if (object->methodTable(exec->vm())->getCallData(object, callData) != CallTypeNone) {
+            if (object->methodTable(exec->vm())->getCallData(object, callData) != CallType::None) {
                 if (auto* classInfo = object->classInfo())
                     return JSValue::encode(jsMakeNontrivialString(exec, "function ", classInfo->className, "() {\n    [native code]\n}"));
             }
@@ -134,7 +134,7 @@ EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
     // If IsCallable(Target) is false, throw a TypeError exception.
     CallData callData;
     CallType callType = getCallData(target, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return throwVMTypeError(exec);
     // Primitive values are not callable.
     ASSERT(target.isObject());
index 28f5893..f380326 100644 (file)
@@ -65,13 +65,13 @@ static EncodedJSValue JSC_HOST_CALL constructGeneratorFunctionConstructor(ExecSt
 CallType GeneratorFunctionConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callGeneratorFunctionConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 ConstructType GeneratorFunctionConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructGeneratorFunctionConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 } // namespace JSC
index f07a988..5538ec0 100644 (file)
@@ -65,7 +65,7 @@ const String InternalFunction::displayName(ExecState* exec)
 CallType InternalFunction::getCallData(JSCell*, CallData&)
 {
     RELEASE_ASSERT_NOT_REACHED();
-    return CallTypeNone;
+    return CallType::None;
 }
 
 const String InternalFunction::calculatedDisplayName(ExecState* exec)
index b635bc5..6438d6d 100644 (file)
@@ -135,13 +135,13 @@ static EncodedJSValue JSC_HOST_CALL callIntlCollator(ExecState* state)
 ConstructType IntlCollatorConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructIntlCollator;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType IntlCollatorConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callIntlCollator;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 bool IntlCollatorConstructor::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
index 4e13712..e917ee2 100644 (file)
@@ -134,13 +134,13 @@ static EncodedJSValue JSC_HOST_CALL callIntlDateTimeFormat(ExecState* state)
 ConstructType IntlDateTimeFormatConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructIntlDateTimeFormat;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType IntlDateTimeFormatConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callIntlDateTimeFormat;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 bool IntlDateTimeFormatConstructor::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
index deac95c..26c6d46 100644 (file)
@@ -134,13 +134,13 @@ static EncodedJSValue JSC_HOST_CALL callIntlNumberFormat(ExecState* state)
 ConstructType IntlNumberFormatConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructIntlNumberFormat;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType IntlNumberFormatConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callIntlNumberFormat;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 bool IntlNumberFormatConstructor::getOwnPropertySlot(JSObject* object, ExecState* state, PropertyName propertyName, PropertySlot& slot)
index 7dcd07b..6f7e14f 100644 (file)
@@ -42,7 +42,7 @@ JSValue iteratorNext(ExecState* exec, JSValue iterator, JSValue value)
 
     CallData nextFunctionCallData;
     CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData);
-    if (nextFunctionCallType == CallTypeNone)
+    if (nextFunctionCallType == CallType::None)
         return throwTypeError(exec);
 
     MarkedArgumentBuffer nextFunctionArguments;
@@ -106,7 +106,7 @@ void iteratorClose(ExecState* exec, JSValue iterator)
 
     CallData returnFunctionCallData;
     CallType returnFunctionCallType = getCallData(returnFunction, returnFunctionCallData);
-    if (returnFunctionCallType == CallTypeNone) {
+    if (returnFunctionCallType == CallType::None) {
         if (exception)
             exec->vm().throwException(exec, exception);
         else
index 45b558b..9f27382 100644 (file)
@@ -342,6 +342,13 @@ inline JSArray* constructArrayNegativeIndexed(ExecState* exec, Structure* arrayS
     return array;
 }
 
+ALWAYS_INLINE unsigned getLength(ExecState* exec, JSObject* obj)
+{
+    if (isJSArray(obj))
+        return jsCast<JSArray*>(obj)->length();
+    return obj->get(exec, exec->propertyNames().length).toUInt32(exec);
+}
+
 } // namespace JSC
 
 #endif // JSArray_h
index 9757da2..cf456f3 100644 (file)
@@ -113,13 +113,13 @@ ConstructType JSArrayBufferConstructor::getConstructData(
     JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructArrayBuffer;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType JSArrayBufferConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callArrayBuffer;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 // ------------------------------ Functions --------------------------------
index ea39618..690cb91 100644 (file)
@@ -50,7 +50,7 @@ EncodedJSValue JSC_HOST_CALL boundFunctionCall(ExecState* exec)
     JSObject* targetFunction = boundFunction->targetFunction();
     CallData callData;
     CallType callType = getCallData(targetFunction, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
     return JSValue::encode(call(exec, targetFunction, callType, callData, boundFunction->boundThis(), args));
 }
 
@@ -70,7 +70,7 @@ EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState* exec)
     JSObject* targetFunction = boundFunction->targetFunction();
     ConstructData constructData;
     ConstructType constructType = getConstructData(targetFunction, constructData);
-    ASSERT(constructType != ConstructTypeNone);
+    ASSERT(constructType != ConstructType::None);
     return JSValue::encode(construct(exec, targetFunction, constructType, constructData, args));
 }
 
@@ -121,7 +121,7 @@ JSBoundFunction* JSBoundFunction::create(VM& vm, JSGlobalObject* globalObject, J
 {
     ConstructData constructData;
     ConstructType constructType = JSC::getConstructData(targetFunction, constructData);
-    bool canConstruct = constructType != ConstructTypeNone;
+    bool canConstruct = constructType != ConstructType::None;
     NativeExecutable* executable = vm.getHostFunction(boundFunctionCall, canConstruct ? boundFunctionConstruct : callHostFunctionAsConstructor, ASCIILiteral("Function.prototype.bind result"));
     Structure* structure = getBoundFunctionStructure(vm, globalObject, targetFunction);
     JSBoundFunction* function = new (NotNull, allocateCell<JSBoundFunction>(vm.heap)) JSBoundFunction(vm, globalObject, structure, targetFunction, boundThis, boundArgs);
index 6903be1..cbbf261 100644 (file)
@@ -76,6 +76,11 @@ template <class T> class WriteBarrierBase;
 enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
 enum ECMAMode { StrictMode, NotStrictMode };
 
+enum class CallType : unsigned;
+struct CallData;
+enum class ConstructType : unsigned;
+struct ConstructData;
+
 typedef int64_t EncodedJSValue;
     
 union EncodedValueDescriptor {
@@ -219,7 +224,9 @@ public:
     // Querying the type.
     bool isEmpty() const;
     bool isFunction() const;
+    bool isFunction(CallType&, CallData&) const;
     bool isConstructor() const;
+    bool isConstructor(ConstructType&, ConstructData&) const;
     bool isUndefined() const;
     bool isNull() const;
     bool isUndefinedOrNull() const;
index 76db356..cc7cb8d 100644 (file)
@@ -705,7 +705,16 @@ inline bool JSValue::isFunction() const
         return false;
     JSCell* cell = asCell();
     CallData ignored;
-    return cell->methodTable()->getCallData(cell, ignored) != CallTypeNone;
+    return cell->methodTable()->getCallData(cell, ignored) != CallType::None;
+}
+
+inline bool JSValue::isFunction(CallType& callType, CallData& callData) const
+{
+    if (!isCell())
+        return false;
+    JSCell* cell = asCell();
+    callType = cell->methodTable()->getCallData(cell, callData);
+    return callType != CallType::None;
 }
 
 inline bool JSValue::isConstructor() const
@@ -714,7 +723,16 @@ inline bool JSValue::isConstructor() const
         return false;
     JSCell* cell = asCell();
     ConstructData ignored;
-    return cell->methodTable()->getConstructData(cell, ignored) != ConstructTypeNone;
+    return cell->methodTable()->getConstructData(cell, ignored) != ConstructType::None;
+}
+
+inline bool JSValue::isConstructor(ConstructType& constructType, ConstructData& constructData) const
+{
+    if (!isCell())
+        return false;
+    JSCell* cell = asCell();
+    constructType = cell->methodTable()->getConstructData(cell, constructData);
+    return constructType != ConstructType::None;
 }
 
 // this method is here to be after the inline declaration of JSCell::inherits
index 536c819..48f5a1a 100644 (file)
@@ -93,7 +93,7 @@ CallType JSCell::getCallData(JSCell*, CallData& callData)
     callData.js.functionExecutable = 0;
     callData.js.scope = 0;
     callData.native.function = 0;
-    return CallTypeNone;
+    return CallType::None;
 }
 
 ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
@@ -101,7 +101,7 @@ ConstructType JSCell::getConstructData(JSCell*, ConstructData& constructData)
     constructData.js.functionExecutable = 0;
     constructData.js.scope = 0;
     constructData.native.function = 0;
-    return ConstructTypeNone;
+    return ConstructType::None;
 }
 
 void JSCell::put(JSCell* cell, ExecState* exec, PropertyName identifier, JSValue value, PutPropertySlot& slot)
index 6512d4f..fb85059 100644 (file)
@@ -230,11 +230,11 @@ CallType JSFunction::getCallData(JSCell* cell, CallData& callData)
     JSFunction* thisObject = jsCast<JSFunction*>(cell);
     if (thisObject->isHostFunction()) {
         callData.native.function = thisObject->nativeFunction();
-        return CallTypeHost;
+        return CallType::Host;
     }
     callData.js.functionExecutable = thisObject->jsExecutable();
     callData.js.scope = thisObject->scope();
-    return CallTypeJS;
+    return CallType::JS;
 }
 
 class RetrieveArgumentsFunctor {
@@ -546,16 +546,16 @@ ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& construc
 
     if (thisObject->isHostFunction()) {
         constructData.native.function = thisObject->nativeConstructor();
-        return ConstructTypeHost;
+        return ConstructType::Host;
     }
 
     FunctionExecutable* functionExecutable = thisObject->jsExecutable();
     if (functionExecutable->constructAbility() == ConstructAbility::CannotConstruct)
-        return ConstructTypeNone;
+        return ConstructType::None;
 
     constructData.js.functionExecutable = functionExecutable;
     constructData.js.scope = thisObject->scope();
-    return ConstructTypeJS;
+    return ConstructType::JS;
 }
 
 String getCalculatedDisplayName(CallFrame* callFrame, JSObject* object)
index 897bc8c..a2b4cb7 100644 (file)
@@ -170,7 +170,7 @@ inline JSObject* constructGenericTypedArrayViewWithArguments(ExecState* exec, St
 
                     CallData callData;
                     CallType callType = getCallData(iteratorFunc, callData);
-                    if (callType == CallTypeNone)
+                    if (callType == CallType::None)
                         return throwTypeError(exec, "Symbol.Iterator for the first argument cannot be called.");
 
                     ArgList arguments;
@@ -257,7 +257,7 @@ template<typename ViewClass>
 ConstructType JSGenericTypedArrayViewConstructor<ViewClass>::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructGenericTypedArrayView<ViewClass>;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 template<typename ViewClass>
@@ -270,7 +270,7 @@ template<typename ViewClass>
 CallType JSGenericTypedArrayViewConstructor<ViewClass>::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callGenericTypedArrayView<ViewClass>;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace JSC
index 093596b..a324055 100644 (file)
@@ -57,7 +57,7 @@ JSInternalPromise* JSInternalPromise::then(ExecState* exec, JSFunction* onFulfil
     JSObject* function = jsCast<JSObject*>(get(exec, exec->propertyNames().builtinNames().thenPublicName()));
     CallData callData;
     CallType callType = JSC::getCallData(function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(onFulfilled ? onFulfilled : jsUndefined());
index b8c2984..cff1915 100644 (file)
@@ -76,13 +76,13 @@ static EncodedJSValue JSC_HOST_CALL constructPromise(ExecState* exec)
 ConstructType JSInternalPromiseConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructPromise;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType JSInternalPromiseConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = constructPromise;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 bool JSInternalPromiseConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
index ebc6b13..7660ce8 100644 (file)
@@ -65,7 +65,7 @@ void JSJobMicrotask::run(ExecState* exec)
 {
     CallData handlerCallData;
     CallType handlerCallType = getCallData(m_job.get(), handlerCallData);
-    ASSERT(handlerCallType != CallTypeNone);
+    ASSERT(handlerCallType != CallType::None);
 
     MarkedArgumentBuffer handlerArguments;
     for (unsigned index = 0, length = m_arguments->length(); index < length; ++index)
index 7a1f849..d889e1c 100644 (file)
@@ -212,7 +212,7 @@ Stringifier::Stringifier(ExecState* exec, const Local<Unknown>& replacer, const
     , m_replacer(replacer)
     , m_usingArrayReplacer(false)
     , m_arrayReplacerPropertyNames(exec, PropertyNameMode::Strings)
-    , m_replacerCallType(CallTypeNone)
+    , m_replacerCallType(CallType::None)
     , m_gap(gap(exec, space.get()))
 {
     if (!m_replacer.isObject())
@@ -279,7 +279,7 @@ JSValue Stringifier::toJSONImpl(JSValue value, const PropertyNameForFunctionCall
     JSObject* object = asObject(toJSONFunction);
     CallData callData;
     CallType callType = object->methodTable()->getCallData(object, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return value;
 
     MarkedArgumentBuffer args;
@@ -295,7 +295,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
         return StringifyFailed;
 
     // Call the replacer function.
-    if (m_replacerCallType != CallTypeNone) {
+    if (m_replacerCallType != CallType::None) {
         MarkedArgumentBuffer args;
         args.append(propertyName.value(m_exec));
         args.append(value);
@@ -349,7 +349,7 @@ Stringifier::StringifyResult Stringifier::appendStringifiedValue(StringBuilder&
     JSObject* object = asObject(value);
 
     CallData callData;
-    if (object->methodTable()->getCallData(object, callData) != CallTypeNone) {
+    if (object->methodTable()->getCallData(object, callData) != CallType::None) {
         if (holder->inherits(JSArray::info())) {
             builder.appendLiteral("null");
             return StringifySucceeded;
@@ -757,7 +757,7 @@ EncodedJSValue JSC_HOST_CALL JSONProtoFuncParse(ExecState* exec)
     JSValue function = exec->uncheckedArgument(1);
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return JSValue::encode(unfiltered);
     return JSValue::encode(Walker(exec, Local<JSObject>(exec->vm(), asObject(function)), callType, callData).walk(unfiltered));
 }
index 107999d..2f52a1f 100644 (file)
@@ -1438,7 +1438,7 @@ static ALWAYS_INLINE JSValue callToPrimitiveFunction(ExecState* exec, const JSOb
         return JSValue();
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return exec->exception();
 
     MarkedArgumentBuffer callArgs;
@@ -1535,7 +1535,7 @@ bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue hasInstanceVa
     if (!hasInstanceValue.isUndefinedOrNull() && hasInstanceValue != exec->lexicalGlobalObject()->functionProtoHasInstanceSymbolFunction()) {
         CallData callData;
         CallType callType = JSC::getCallData(hasInstanceValue, callData);
-        if (callType == CallTypeNone) {
+        if (callType == CallType::None) {
             vm.throwException(exec, createInvalidInstanceofParameterErrorhasInstanceValueNotFunction(exec, this));
             return false;
         }
@@ -3068,7 +3068,7 @@ JSValue JSObject::getMethod(ExecState* exec, CallData& callData, CallType& callT
     }
 
     callType = method.asCell()->methodTable()->getCallData(method.asCell(), callData);
-    if (callType == CallTypeNone) {
+    if (callType == CallType::None) {
         throwVMTypeError(exec, errorMessage);
         return jsUndefined();
     }
index 3338723..d606278 100644 (file)
@@ -1094,15 +1094,15 @@ inline void JSObject::setButterflyWithoutChangingStructure(VM& vm, Butterfly* bu
 
 inline CallType getCallData(JSValue value, CallData& callData)
 {
-    CallType result = value.isCell() ? value.asCell()->methodTable()->getCallData(value.asCell(), callData) : CallTypeNone;
-    ASSERT(result == CallTypeNone || value.isValidCallee());
+    CallType result = value.isCell() ? value.asCell()->methodTable()->getCallData(value.asCell(), callData) : CallType::None;
+    ASSERT(result == CallType::None || value.isValidCallee());
     return result;
 }
 
 inline ConstructType getConstructData(JSValue value, ConstructData& constructData)
 {
-    ConstructType result = value.isCell() ? value.asCell()->methodTable()->getConstructData(value.asCell(), constructData) : ConstructTypeNone;
-    ASSERT(result == ConstructTypeNone || value.isValidCallee());
+    ConstructType result = value.isCell() ? value.asCell()->methodTable()->getConstructData(value.asCell(), constructData) : ConstructType::None;
+    ASSERT(result == ConstructType::None || value.isValidCallee());
     return result;
 }
 
index 22f40f0..56e2f5a 100644 (file)
@@ -69,7 +69,7 @@ void JSPromise::initialize(ExecState* exec, JSGlobalObject* globalObject, JSValu
     JSFunction* initializePromise = globalObject->initializePromiseFunction();
     CallData callData;
     CallType callType = JSC::getCallData(initializePromise, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(executor);
index 614bac7..ede5aca 100644 (file)
@@ -120,7 +120,7 @@ static EncodedJSValue JSC_HOST_CALL callPromise(ExecState* exec)
 ConstructType JSPromiseConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructPromise;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType JSPromiseConstructor::getCallData(JSCell*, CallData& callData)
@@ -130,7 +130,7 @@ CallType JSPromiseConstructor::getCallData(JSCell*, CallData& callData)
     // returns "object", we need to define [[Call]] for now.
     // https://bugs.webkit.org/show_bug.cgi?id=144093
     callData.native.function = callPromise;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 bool JSPromiseConstructor::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
index ba76973..0aad370 100644 (file)
@@ -45,7 +45,7 @@ JSValue newPromiseCapability(ExecState* exec, JSGlobalObject* globalObject, JSPr
     JSFunction* newPromiseCapabilityFunction = globalObject->newPromiseCapabilityFunction();
     CallData callData;
     CallType callType = JSC::getCallData(newPromiseCapabilityFunction, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(promiseConstructor);
@@ -88,7 +88,7 @@ static inline void callFunction(ExecState* exec, JSValue function, JSValue value
 {
     CallData callData;
     CallType callType = getCallData(function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(value);
index bf99dbc..843e437 100644 (file)
@@ -74,7 +74,7 @@ static EncodedJSValue JSC_HOST_CALL constructTypedArrayView(ExecState* exec)
         return JSValue::encode(throwTypeError(exec, "new.target passed to TypedArray is not an object."));
 
     ConstructData data;
-    if (object->methodTable()->getConstructData(object, data) == ConstructTypeNone)
+    if (object->methodTable()->getConstructData(object, data) == ConstructType::None)
         return JSValue::encode(throwTypeError(exec, "new.target passed to TypedArray is not a valid constructor."));
 
     for (; !value.isNull(); value = jsCast<JSObject*>(value)->prototype()) {
@@ -106,13 +106,13 @@ static EncodedJSValue JSC_HOST_CALL constructTypedArrayView(ExecState* exec)
 ConstructType JSTypedArrayViewConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructTypedArrayView;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType JSTypedArrayViewConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = nullptr;
-    return CallTypeNone;
+    return CallType::None;
 }
 
 } // namespace JSC
index 6228e98..bd257cd 100644 (file)
@@ -70,7 +70,7 @@ static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
 
     CallData adderFunctionCallData;
     CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
-    if (adderFunctionCallType == CallTypeNone)
+    if (adderFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
@@ -79,7 +79,7 @@ static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
 
     CallData iteratorFunctionCallData;
     CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
-    if (iteratorFunctionCallType == CallTypeNone)
+    if (iteratorFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     ArgList iteratorFunctionArguments;
@@ -136,13 +136,13 @@ static EncodedJSValue JSC_HOST_CALL constructMap(ExecState* exec)
 ConstructType MapConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructMap;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType MapConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callMap;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 }
index 37b8afc..b94b865 100644 (file)
@@ -138,7 +138,7 @@ JSValue ModuleLoaderObject::provide(ExecState* exec, JSValue key, Status status,
     JSObject* function = jsCast<JSObject*>(get(exec, exec->propertyNames().builtinNames().providePublicName()));
     CallData callData;
     CallType callType = JSC::getCallData(function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(key);
@@ -153,7 +153,7 @@ JSInternalPromise* ModuleLoaderObject::loadAndEvaluateModule(ExecState* exec, JS
     JSObject* function = jsCast<JSObject*>(get(exec, exec->propertyNames().builtinNames().loadAndEvaluateModulePublicName()));
     CallData callData;
     CallType callType = JSC::getCallData(function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(moduleName);
@@ -167,7 +167,7 @@ JSInternalPromise* ModuleLoaderObject::loadModule(ExecState* exec, JSValue modul
     JSObject* function = jsCast<JSObject*>(get(exec, exec->propertyNames().builtinNames().loadModulePublicName()));
     CallData callData;
     CallType callType = JSC::getCallData(function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(moduleName);
@@ -181,7 +181,7 @@ JSInternalPromise* ModuleLoaderObject::linkAndEvaluateModule(ExecState* exec, JS
     JSObject* function = jsCast<JSObject*>(get(exec, exec->propertyNames().builtinNames().linkAndEvaluateModulePublicName()));
     CallData callData;
     CallType callType = JSC::getCallData(function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(moduleKey);
index 61ad9c3..e78e7e7 100644 (file)
@@ -73,7 +73,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::constructWithNativeErrorConstructor(Ex
 ConstructType NativeErrorConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = Interpreter::constructWithNativeErrorConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
     
 EncodedJSValue JSC_HOST_CALL Interpreter::callNativeErrorConstructor(ExecState* exec)
@@ -86,7 +86,7 @@ EncodedJSValue JSC_HOST_CALL Interpreter::callNativeErrorConstructor(ExecState*
 CallType NativeErrorConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = Interpreter::callNativeErrorConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace JSC
index 4243e5c..1f79762 100644 (file)
@@ -41,12 +41,12 @@ static EncodedJSValue JSC_HOST_CALL callReturnUndefined(ExecState*)
 CallType NullGetterFunction::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callReturnUndefined;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 ConstructType NullGetterFunction::getConstructData(JSCell*, ConstructData&)
 {
-    return ConstructTypeNone;
+    return ConstructType::None;
 }
 
 }
index 059b74f..7496be4 100644 (file)
@@ -80,12 +80,12 @@ static EncodedJSValue JSC_HOST_CALL callReturnUndefined(ExecState* exec)
 CallType NullSetterFunction::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callReturnUndefined;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 ConstructType NullSetterFunction::getConstructData(JSCell*, ConstructData&)
 {
-    return ConstructTypeNone;
+    return ConstructType::None;
 }
 
 }
index 64a3636..020ea69 100644 (file)
@@ -93,7 +93,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithNumberConstructor(ExecState* ex
 ConstructType NumberConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithNumberConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 // ECMA 15.7.2
@@ -105,7 +105,7 @@ static EncodedJSValue JSC_HOST_CALL callNumberConstructor(ExecState* exec)
 CallType NumberConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callNumberConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 // ECMA-262 20.1.2.2
index e8fe74c..bc0a252 100644 (file)
@@ -134,7 +134,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithObjectConstructor(ExecState* ex
 ConstructType ObjectConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithObjectConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec)
@@ -145,7 +145,7 @@ static EncodedJSValue JSC_HOST_CALL callObjectConstructor(ExecState* exec)
 CallType ObjectConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callObjectConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 class ObjectConstructorGetPrototypeOfFunctor {
@@ -349,7 +349,7 @@ bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
             return false;
         if (!get.isUndefined()) {
             CallData callData;
-            if (getCallData(get, callData) == CallTypeNone) {
+            if (getCallData(get, callData) == CallType::None) {
                 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Getter must be a function.")));
                 return false;
             }
@@ -364,7 +364,7 @@ bool toPropertyDescriptor(ExecState* exec, JSValue in, PropertyDescriptor& desc)
             return false;
         if (!set.isUndefined()) {
             CallData callData;
-            if (getCallData(set, callData) == CallTypeNone) {
+            if (getCallData(set, callData) == CallType::None) {
                 exec->vm().throwException(exec, createTypeError(exec, ASCIILiteral("Setter must be a function.")));
                 return false;
             }
index 4cb86ee..326c75e 100644 (file)
@@ -120,7 +120,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineGetter(ExecState* exec)
 
     JSValue get = exec->argument(1);
     CallData callData;
-    if (getCallData(get, callData) == CallTypeNone)
+    if (getCallData(get, callData) == CallType::None)
         return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid getter usage")));
 
     auto propertyName = exec->argument(0).toPropertyKey(exec);
@@ -146,7 +146,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncDefineSetter(ExecState* exec)
 
     JSValue set = exec->argument(1);
     CallData callData;
-    if (getCallData(set, callData) == CallTypeNone)
+    if (getCallData(set, callData) == CallType::None)
         return throwVMError(exec, createTypeError(exec, ASCIILiteral("invalid setter usage")));
 
     auto propertyName = exec->argument(0).toPropertyKey(exec);
@@ -246,7 +246,7 @@ EncodedJSValue JSC_HOST_CALL objectProtoFuncToLocaleString(ExecState* exec)
     // 3. If IsCallable(toString) is false, throw a TypeError exception.
     CallData callData;
     CallType callType = getCallData(toString, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return JSValue::encode(jsUndefined());
 
     // 4. Return the result of calling the [[Call]] internal method of toString passing O as the this value and no arguments.
index 5732cfd..de893c1 100644 (file)
@@ -78,7 +78,7 @@ JSValue jsTypeStringForValue(VM& vm, JSGlobalObject* globalObject, JSValue v)
         if (object->inlineTypeFlags() & TypeOfShouldCallGetCallData) {
             CallData callData;
             JSObject* object = asObject(v);
-            if (object->methodTable(vm)->getCallData(object, callData) != CallTypeNone)
+            if (object->methodTable(vm)->getCallData(object, callData) != CallType::None)
                 return vm.smallStrings.functionString();
         }
     }
@@ -103,7 +103,7 @@ bool jsIsObjectTypeOrNull(CallFrame* callFrame, JSValue v)
             return false;
         CallData callData;
         JSObject* object = asObject(v);
-        if (object->methodTable(callFrame->vm())->getCallData(object, callData) != CallTypeNone)
+        if (object->methodTable(callFrame->vm())->getCallData(object, callData) != CallType::None)
             return false;
     }
     return true;
@@ -114,7 +114,7 @@ bool jsIsFunctionType(JSValue v)
     if (v.isObject()) {
         CallData callData;
         JSObject* object = asObject(v);
-        if (object->methodTable()->getCallData(object, callData) != CallTypeNone)
+        if (object->methodTable()->getCallData(object, callData) != CallType::None)
             return true;
     }
     return false;
index a3bf232..77a8cd0 100644 (file)
@@ -72,7 +72,7 @@ static EncodedJSValue JSC_HOST_CALL constructProxyObject(ExecState* exec)
 ConstructType ProxyConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructProxyObject;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 static EncodedJSValue JSC_HOST_CALL callProxy(ExecState* exec)
@@ -83,7 +83,7 @@ static EncodedJSValue JSC_HOST_CALL callProxy(ExecState* exec)
 CallType ProxyConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callProxy;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace JSC
index e59d3ab..016a268 100644 (file)
@@ -68,10 +68,10 @@ void ProxyObject::finishCreation(VM& vm, ExecState* exec, JSValue target, JSValu
     JSObject* targetAsObject = jsCast<JSObject*>(target);
 
     CallData ignoredCallData;
-    m_isCallable = targetAsObject->methodTable(vm)->getCallData(targetAsObject, ignoredCallData) != CallTypeNone;
+    m_isCallable = targetAsObject->methodTable(vm)->getCallData(targetAsObject, ignoredCallData) != CallType::None;
 
     ConstructData ignoredConstructData;
-    m_isConstructible = jsCast<JSObject*>(target)->methodTable(vm)->getConstructData(jsCast<JSObject*>(target), ignoredConstructData) != ConstructTypeNone;
+    m_isConstructible = jsCast<JSObject*>(target)->methodTable(vm)->getConstructData(jsCast<JSObject*>(target), ignoredConstructData) != ConstructType::None;
 
     m_target.set(vm, this, targetAsObject);
     m_handler.set(vm, this, handler);
@@ -457,7 +457,7 @@ static EncodedJSValue JSC_HOST_CALL performProxyCall(ExecState* exec)
     if (applyMethod.isUndefined()) {
         CallData callData;
         CallType callType = target->methodTable(vm)->getCallData(target, callData);
-        RELEASE_ASSERT(callType != CallTypeNone);
+        RELEASE_ASSERT(callType != CallType::None);
         return JSValue::encode(call(exec, target, callType, callData, exec->thisValue(), ArgList(exec)));
     }
 
@@ -477,11 +477,11 @@ CallType ProxyObject::getCallData(JSCell* cell, CallData& callData)
     if (!proxy->m_isCallable) {
         callData.js.functionExecutable = nullptr;
         callData.js.scope = nullptr;
-        return CallTypeNone;
+        return CallType::None;
     }
 
     callData.native.function = performProxyCall;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 static EncodedJSValue JSC_HOST_CALL performProxyConstruct(ExecState* exec)
@@ -502,7 +502,7 @@ static EncodedJSValue JSC_HOST_CALL performProxyConstruct(ExecState* exec)
     if (constructMethod.isUndefined()) {
         ConstructData constructData;
         ConstructType constructType = target->methodTable(vm)->getConstructData(target, constructData);
-        RELEASE_ASSERT(constructType != ConstructTypeNone);
+        RELEASE_ASSERT(constructType != ConstructType::None);
         return JSValue::encode(construct(exec, target, constructType, constructData, ArgList(exec), exec->newTarget()));
     }
 
@@ -527,11 +527,11 @@ ConstructType ProxyObject::getConstructData(JSCell* cell, ConstructData& constru
     if (!proxy->m_isConstructible) {
         constructData.js.functionExecutable = nullptr;
         constructData.js.scope = nullptr;
-        return ConstructTypeNone;
+        return ConstructType::None;
     }
 
     constructData.native.function = performProxyConstruct;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 template <typename DefaultDeleteFunction>
index 19bf1c5..894aafa 100644 (file)
@@ -34,6 +34,7 @@
 
 namespace JSC {
 
+static EncodedJSValue JSC_HOST_CALL reflectObjectConstruct(ExecState*);
 static EncodedJSValue JSC_HOST_CALL reflectObjectDefineProperty(ExecState*);
 static EncodedJSValue JSC_HOST_CALL reflectObjectEnumerate(ExecState*);
 static EncodedJSValue JSC_HOST_CALL reflectObjectGet(ExecState*);
@@ -57,6 +58,7 @@ const ClassInfo ReflectObject::s_info = { "Reflect", &Base::s_info, &reflectObje
 /* Source for ReflectObject.lut.h
 @begin reflectObjectTable
     apply                    JSBuiltin                             DontEnum|Function 3
+    construct                reflectObjectConstruct                DontEnum|Function 2
     defineProperty           reflectObjectDefineProperty           DontEnum|Function 3
     deleteProperty           JSBuiltin                             DontEnum|Function 2
     enumerate                reflectObjectEnumerate                DontEnum|Function 1
@@ -89,7 +91,41 @@ bool ReflectObject::getOwnPropertySlot(JSObject* object, ExecState* exec, Proper
 
 // ------------------------------ Functions --------------------------------
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.defineproperty
+// https://tc39.github.io/ecma262/#sec-reflect.construct
+EncodedJSValue JSC_HOST_CALL reflectObjectConstruct(ExecState* exec)
+{
+    JSValue target = exec->argument(0);
+    if (!target.isObject())
+        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Reflect.construct requires the first argument be a constructor")));
+
+    ConstructData constructData;
+    ConstructType constructType;
+    if (!target.isConstructor(constructType, constructData))
+        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Reflect.construct requires the first argument be a constructor")));
+
+    JSValue newTarget = target;
+    if (exec->argumentCount() >= 3) {
+        newTarget = exec->argument(2);
+        if (!newTarget.isConstructor())
+            return JSValue::encode(throwTypeError(exec, ASCIILiteral("Reflect.construct requires the third argument be a constructor if present")));
+    }
+
+    MarkedArgumentBuffer arguments;
+    JSObject* argumentsObject = jsDynamicCast<JSObject*>(exec->argument(1));
+    if (!argumentsObject)
+        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Reflect.construct requires the second argument be an object")));
+
+    createListFromArrayLike(exec, argumentsObject, RuntimeTypeMaskAllTypes, ASCIILiteral("This error must not be raised"), [&] (JSValue value, RuntimeType) -> bool {
+        arguments.append(value);
+        return false;
+    });
+    if (exec->hadException())
+        return JSValue::encode(jsUndefined());
+
+    return JSValue::encode(construct(exec, target, constructType, constructData, arguments, newTarget));
+}
+
+// https://tc39.github.io/ecma262/#sec-reflect.defineproperty
 EncodedJSValue JSC_HOST_CALL reflectObjectDefineProperty(ExecState* exec)
 {
     JSValue target = exec->argument(0);
@@ -111,6 +147,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectDefineProperty(ExecState* exec)
     return JSValue::encode(jsBoolean(targetObject->methodTable(exec->vm())->defineOwnProperty(targetObject, exec, propertyName, descriptor, shouldThrow)));
 }
 
+// FIXME: Reflect.enumerate is removed in ECMA 2016 draft.
 // http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.enumerate
 EncodedJSValue JSC_HOST_CALL reflectObjectEnumerate(ExecState* exec)
 {
@@ -120,7 +157,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectEnumerate(ExecState* exec)
     return JSValue::encode(JSPropertyNameIterator::create(exec, exec->lexicalGlobalObject()->propertyNameIteratorStructure(), asObject(target)));
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.get
+// https://tc39.github.io/ecma262/#sec-reflect.get
 EncodedJSValue JSC_HOST_CALL reflectObjectGet(ExecState* exec)
 {
     JSValue target = exec->argument(0);
@@ -139,7 +176,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectGet(ExecState* exec)
     return JSValue::encode(target.get(exec, propertyName, slot));
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.getownpropertydescriptor
+// https://tc39.github.io/ecma262/#sec-reflect.getownpropertydescriptor
 EncodedJSValue JSC_HOST_CALL reflectObjectGetOwnPropertyDescriptor(ExecState* exec)
 {
     JSValue target = exec->argument(0);
@@ -153,7 +190,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectGetOwnPropertyDescriptor(ExecState* ex
     return JSValue::encode(objectConstructorGetOwnPropertyDescriptor(exec, asObject(target), key));
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.getprototypeof
+// https://tc39.github.io/ecma262/#sec-reflect.getprototypeof
 EncodedJSValue JSC_HOST_CALL reflectObjectGetPrototypeOf(ExecState* exec)
 {
     JSValue target = exec->argument(0);
@@ -162,7 +199,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectGetPrototypeOf(ExecState* exec)
     return JSValue::encode(objectConstructorGetPrototypeOf(exec, asObject(target)));
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.isextensible
+// https://tc39.github.io/ecma262/#sec-reflect.isextensible
 EncodedJSValue JSC_HOST_CALL reflectObjectIsExtensible(ExecState* exec)
 {
     JSValue target = exec->argument(0);
@@ -175,7 +212,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectIsExtensible(ExecState* exec)
     return JSValue::encode(jsBoolean(isExtensible));
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.ownkeys
+// https://tc39.github.io/ecma262/#sec-reflect.ownkeys
 EncodedJSValue JSC_HOST_CALL reflectObjectOwnKeys(ExecState* exec)
 {
     JSValue target = exec->argument(0);
@@ -184,7 +221,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectOwnKeys(ExecState* exec)
     return JSValue::encode(ownPropertyKeys(exec, jsCast<JSObject*>(target), PropertyNameMode::StringsAndSymbols, DontEnumPropertiesMode::Include));
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.preventextensions
+// https://tc39.github.io/ecma262/#sec-reflect.preventextensions
 EncodedJSValue JSC_HOST_CALL reflectObjectPreventExtensions(ExecState* exec)
 {
     JSValue target = exec->argument(0);
@@ -197,7 +234,7 @@ EncodedJSValue JSC_HOST_CALL reflectObjectPreventExtensions(ExecState* exec)
     return JSValue::encode(jsBoolean(result));
 }
 
-// http://www.ecma-international.org/ecma-262/6.0/#sec-reflect.setprototypeof
+// https://tc39.github.io/ecma262/#sec-reflect.setprototypeof
 EncodedJSValue JSC_HOST_CALL reflectObjectSetPrototypeOf(ExecState* exec)
 {
     JSValue target = exec->argument(0);
index 5e618e1..b0aa5f6 100644 (file)
@@ -308,7 +308,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* ex
 ConstructType RegExpConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithRegExpConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 // ECMA 15.10.3
@@ -321,7 +321,7 @@ static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec)
 CallType RegExpConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callRegExpConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace JSC
index d57b8fb..3b216ed 100644 (file)
@@ -46,6 +46,8 @@ enum RuntimeType : uint16_t {
 
 typedef uint16_t RuntimeTypeMask;
 
+static const RuntimeTypeMask RuntimeTypeMaskAllTypes = TypeFunction | TypeUndefined | TypeNull | TypeBoolean | TypeMachineInt | TypeNumber | TypeString | TypeObject | TypeSymbol;
+
 class JSValue;
 RuntimeType runtimeTypeForValue(JSValue);
 String runtimeTypeAsString(RuntimeType);
index 9c7ad74..dcb9056 100644 (file)
@@ -368,7 +368,7 @@ void SamplingProfiler::processUnverifiedStackTraces()
                 CallData callData;
                 CallType callType;
                 callType = getCallData(calleeCell, callData);
-                if (callType == CallTypeHost)
+                if (callType == CallType::Host)
                     result = FrameType::Host;
 
                 stackFrame.frameType = result;
index 8a6f14c..9a4e978 100644 (file)
@@ -71,7 +71,7 @@ static EncodedJSValue JSC_HOST_CALL constructSet(ExecState* exec)
 
     CallData adderFunctionCallData;
     CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
-    if (adderFunctionCallType == CallTypeNone)
+    if (adderFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
@@ -80,7 +80,7 @@ static EncodedJSValue JSC_HOST_CALL constructSet(ExecState* exec)
 
     CallData iteratorFunctionCallData;
     CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
-    if (iteratorFunctionCallType == CallTypeNone)
+    if (iteratorFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     ArgList iteratorFunctionArguments;
@@ -118,13 +118,13 @@ static EncodedJSValue JSC_HOST_CALL constructSet(ExecState* exec)
 ConstructType SetConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructSet;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType SetConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callSet;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 }
index fbe5677..3d59427 100644 (file)
@@ -137,7 +137,7 @@ static EncodedJSValue JSC_HOST_CALL constructWithStringConstructor(ExecState* ex
 ConstructType StringConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWithStringConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 JSCell* stringConstructor(ExecState* exec, JSValue argument)
@@ -157,7 +157,7 @@ static EncodedJSValue JSC_HOST_CALL callStringConstructor(ExecState* exec)
 CallType StringConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callStringConstructor;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace JSC
index 3ba6cff..c8f9301 100644 (file)
@@ -502,7 +502,7 @@ static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
 
-        if (callType == CallTypeNone && !replacementString.length())
+        if (callType == CallType::None && !replacementString.length())
             return removeUsingRegExpSearch(exec, string, source, regExp);
     }
 
@@ -517,7 +517,7 @@ static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(
     Vector<String, 16> replacements;
 
     // This is either a loop (if global is set) or a one-way (if not).
-    if (global && callType == CallTypeJS) {
+    if (global && callType == CallType::JS) {
         // regExp->numSubpatterns() + 1 for pattern args, + 2 for match start and string
         int argCount = regExp->numSubpatterns() + 1 + 2;
         JSFunction* func = jsCast<JSFunction*>(replaceValue);
@@ -612,7 +612,7 @@ static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(
             if (!result)
                 break;
 
-            if (callType != CallTypeNone) {
+            if (callType != CallType::None) {
                 sourceRanges.append(StringRange(lastIndex, result.start - lastIndex));
 
                 MarkedArgumentBuffer args;
@@ -681,7 +681,7 @@ EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpEmptyStr(
     CallData callData;
     String replacementString = emptyString();
     return replaceUsingRegExpSearch(
-        exec, thisValue, searchValue, callData, CallTypeNone, replacementString, JSValue());
+        exec, thisValue, searchValue, callData, CallType::None, replacementString, JSValue());
 }
 
 EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
@@ -690,7 +690,7 @@ EncodedJSValue JIT_OPERATION operationStringProtoFuncReplaceRegExpString(
     CallData callData;
     String replacementString = replaceString->value(exec);
     return replaceUsingRegExpSearch(
-        exec, thisValue, searchValue, callData, CallTypeNone, replacementString, replaceString);
+        exec, thisValue, searchValue, callData, CallType::None, replacementString, replaceString);
 }
 
 static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JSString* string, JSValue searchValue, JSValue replaceValue)
@@ -698,7 +698,7 @@ static ALWAYS_INLINE EncodedJSValue replaceUsingRegExpSearch(ExecState* exec, JS
     String replacementString;
     CallData callData;
     CallType callType = getCallData(replaceValue, callData);
-    if (callType == CallTypeNone) {
+    if (callType == CallType::None) {
         replacementString = replaceValue.toString(exec)->value(exec);
         if (exec->hadException())
             return JSValue::encode(jsUndefined());
@@ -722,7 +722,7 @@ static ALWAYS_INLINE EncodedJSValue replaceUsingStringSearch(ExecState* exec, JS
 
     CallData callData;
     CallType callType = getCallData(replaceValue, callData);
-    if (callType != CallTypeNone) {
+    if (callType != CallType::None) {
         MarkedArgumentBuffer args;
         args.append(jsSubstring(exec, string, matchStart, searchString.impl()->length()));
         args.append(jsNumber(matchStart));
index 753ce60..740fb68 100644 (file)
@@ -90,13 +90,13 @@ static EncodedJSValue JSC_HOST_CALL callSymbol(ExecState* exec)
 
 ConstructType SymbolConstructor::getConstructData(JSCell*, ConstructData&)
 {
-    return ConstructTypeNone;
+    return ConstructType::None;
 }
 
 CallType SymbolConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callSymbol;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 EncodedJSValue JSC_HOST_CALL symbolConstructorFor(ExecState* exec)
index 943f78d..22354a7 100644 (file)
@@ -68,7 +68,7 @@ static EncodedJSValue JSC_HOST_CALL constructWeakMap(ExecState* exec)
 
     CallData adderFunctionCallData;
     CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
-    if (adderFunctionCallType == CallTypeNone)
+    if (adderFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
@@ -77,7 +77,7 @@ static EncodedJSValue JSC_HOST_CALL constructWeakMap(ExecState* exec)
 
     CallData iteratorFunctionCallData;
     CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
-    if (iteratorFunctionCallType == CallTypeNone)
+    if (iteratorFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     ArgList iteratorFunctionArguments;
@@ -134,13 +134,13 @@ static EncodedJSValue JSC_HOST_CALL constructWeakMap(ExecState* exec)
 ConstructType WeakMapConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWeakMap;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType WeakMapConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callWeakMap;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 }
index 1551e77..9d983d6 100644 (file)
@@ -68,7 +68,7 @@ static EncodedJSValue JSC_HOST_CALL constructWeakSet(ExecState* exec)
 
     CallData adderFunctionCallData;
     CallType adderFunctionCallType = getCallData(adderFunction, adderFunctionCallData);
-    if (adderFunctionCallType == CallTypeNone)
+    if (adderFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     JSValue iteratorFunction = iterable.get(exec, exec->propertyNames().iteratorSymbol);
@@ -77,7 +77,7 @@ static EncodedJSValue JSC_HOST_CALL constructWeakSet(ExecState* exec)
 
     CallData iteratorFunctionCallData;
     CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
-    if (iteratorFunctionCallType == CallTypeNone)
+    if (iteratorFunctionCallType == CallType::None)
         return JSValue::encode(throwTypeError(exec));
 
     ArgList iteratorFunctionArguments;
@@ -115,13 +115,13 @@ static EncodedJSValue JSC_HOST_CALL constructWeakSet(ExecState* exec)
 ConstructType WeakSetConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructWeakSet;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 CallType WeakSetConstructor::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callWeakSet;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 }
index ca79132..e4d22fa 100644 (file)
 - path: es6/Proxy_setPrototypeOf_handler.js
   cmd: runES6 :normal
 - path: es6/Reflect_Reflect.construct.js
-  cmd: runES6 :fail
+  cmd: runES6 :normal
 - path: es6/Reflect_Reflect.construct_creates_instance_from_newTarget_argument.js
-  cmd: runES6 :fail
+  cmd: runES6 :normal
 - path: es6/Reflect_Reflect.construct_sets_new.target_meta_property.js
-  cmd: runES6 :fail
+  cmd: runES6 :normal
 - path: es6/Reflect_Reflect.set.js
   cmd: runES6 :fail
 - path: es6/RegExp.prototype_properties_RegExp.prototype[Symbol.match].js
diff --git a/Source/JavaScriptCore/tests/stress/reflect-construct.js b/Source/JavaScriptCore/tests/stress/reflect-construct.js
new file mode 100644 (file)
index 0000000..8939ab1
--- /dev/null
@@ -0,0 +1,228 @@
+function shouldBe(actual, expected) {
+    if (actual !== expected)
+        throw new Error('bad value: ' + actual);
+}
+
+function shouldThrow(func, message) {
+    var error = null;
+    try {
+        func();
+    } catch (e) {
+        error = e;
+    }
+    if (!error)
+        throw new Error("not thrown.");
+    if (String(error) !== message)
+        throw new Error("bad error: " + String(error));
+}
+
+shouldBe(Reflect.construct.length, 2);
+
+shouldThrow(() => {
+    Reflect.construct("hello", 42);
+}, `TypeError: Reflect.construct requires the first argument be a constructor`);
+
+shouldThrow(() => {
+    Reflect.construct(Array.prototype.forEach, []);
+}, `TypeError: Reflect.construct requires the first argument be a constructor`);
+
+shouldThrow(() => {
+    Reflect.construct(function () { }, 42, null);
+}, `TypeError: Reflect.construct requires the third argument be a constructor if present`);
+
+shouldThrow(() => {
+    Reflect.construct(function () { }, 42, {});
+}, `TypeError: Reflect.construct requires the third argument be a constructor if present`);
+
+shouldThrow(() => {
+    Reflect.construct(function () { }, 42, Array.prototype.forEach);
+}, `TypeError: Reflect.construct requires the third argument be a constructor if present`);
+
+shouldThrow(() => {
+    Reflect.construct(function () { }, 42, function () { });
+}, `TypeError: Reflect.construct requires the second argument be an object`);
+
+shouldThrow(() => {
+    var array = {
+        get length() {
+            throw new Error("ok");
+        },
+        get 0() {
+            throw new Error("ng");
+        }
+    };
+    Reflect.construct(function () { }, array);
+}, `Error: ok`);
+
+shouldThrow(() => {
+    var array = {
+        get length() {
+            return 1;
+        },
+        get 0() {
+            throw new Error("ok");
+        }
+    };
+    Reflect.construct(function () { }, array);
+}, `Error: ok`);
+
+var array = {
+    get length() {
+        return 0;
+    },
+    get 0() {
+        throw new Error("ng");
+    }
+};
+shouldBe(Reflect.construct(function () { this.length = arguments.length; }, array).length, 0);
+
+var globalObject = this;
+shouldBe(Reflect.construct(function Hello() {
+    "use strict";
+    shouldBe(arguments[0], 0);
+    shouldBe(arguments[1], 1);
+    shouldBe(arguments[2], 2);
+    shouldBe(typeof this, "object");
+    shouldBe(new.target, Hello);
+    this.result = arguments.length;
+}, [0,1,2]).result, 3)
+
+shouldBe(Reflect.construct(function Hello() {
+    shouldBe(arguments[0], 0);
+    shouldBe(arguments[1], 1);
+    shouldBe(arguments[2], 2);
+    shouldBe(typeof this, "object");
+    shouldBe(new.target, Hello);
+    this.result = arguments.length;
+}, [0,1,2]).result, 3)
+
+var newTarget = function () { };
+shouldBe(Reflect.construct(function () {
+    "use strict";
+    shouldBe(new.target, newTarget);
+    this.result = arguments.length;
+}, [], newTarget).result, 0)
+
+shouldBe(Reflect.construct(function () {
+    shouldBe(new.target, newTarget);
+    this.result = arguments.length;
+}, [], newTarget).result, 0)
+
+{
+    class A {
+        constructor()
+        {
+            this.type = "A";
+        }
+    }
+
+    class B extends A {
+        constructor()
+        {
+            super();
+            this.type = "B";
+        }
+    }
+
+    shouldBe(Reflect.construct(A, []).type, "A");
+    shouldBe(Reflect.construct(B, []).type, "B");
+
+    shouldBe(Reflect.construct(B, [], B).__proto__, B.prototype);
+    shouldBe(Reflect.construct(B, [], A).__proto__, A.prototype);
+    shouldBe(Reflect.construct(B, [], A).type, "B");
+    shouldBe(Reflect.construct(B, [], B).type, "B");
+
+    shouldBe(Reflect.construct(A, [], A).__proto__, A.prototype);
+    shouldBe(Reflect.construct(A, [], B).__proto__, B.prototype);
+    shouldBe(Reflect.construct(A, [], A).type, "A");
+    shouldBe(Reflect.construct(A, [], B).type, "A");
+}
+
+function nativeConstructorTest()
+{
+    class DerivedMap {
+    }
+    shouldBe(Reflect.construct(Map, [], DerivedMap).__proto__, DerivedMap.prototype);
+    let map = Reflect.construct(Map, [], DerivedMap);
+    map.__proto__ = Map.prototype;
+    map.set(20, 30);
+    shouldBe(map.get(20), 30);
+
+    class FailedMap {
+    }
+    shouldBe(Reflect.construct(FailedMap, [], Map).__proto__, Map.prototype);
+    shouldThrow(() => {
+        let map = Reflect.construct(FailedMap, [], Map);
+        map.set(20, 30);
+    }, `TypeError: Map operation called on non-Map object`);
+
+    shouldBe(Reflect.construct(Set, [], Map).__proto__, Map.prototype);
+    shouldThrow(() => {
+        let map = Reflect.construct(Set, [], Map);
+        map.set(20, 30);
+    }, `TypeError: Map operation called on non-Map object`);
+
+    let set = Reflect.construct(Set, [], Map);
+    Set.prototype.add.call(set, 20);
+    shouldBe(Set.prototype.has.call(set, 20), true);
+}
+noInline(nativeConstructorTest);
+
+for (var i = 0; i < 1e4; ++i)
+    nativeConstructorTest();
+
+(function () {
+    function Hello() { }
+    let result = {};
+    let proxy = new Proxy(Hello, {
+        construct(theTarget, argArray, newTarget) {
+            shouldBe(newTarget, Map);
+            shouldBe(theTarget, Hello);
+            shouldBe(argArray.length, 2);
+            shouldBe(argArray[0], 10);
+            shouldBe(argArray[1], 20);
+            return result;
+        }
+    });
+    shouldBe(Reflect.construct(proxy, [10, 20], Map), result);
+}());
+
+(function () {
+    var proxy = new Proxy(Map, {
+        construct(theTarget, argArray, newTarget) {
+        }
+    });
+
+    var result = {};
+    function Hello() {
+        shouldBe(new.target, proxy);
+        shouldBe(new.target.prototype, Map.prototype);
+        shouldBe(arguments.length, 2);
+        shouldBe(arguments[0], 10);
+        shouldBe(arguments[1], 20);
+        return result;
+    }
+    shouldBe(Reflect.construct(Hello, [10, 20], proxy), result);
+}());
+
+(function () {
+    function Hello() { }
+    var result = {};
+    var proxy1 = new Proxy(Hello, {
+        construct(theTarget, argArray, newTarget) {
+            shouldBe(newTarget, proxy2);
+            shouldBe(theTarget, Hello);
+            shouldBe(argArray.length, 2);
+            shouldBe(argArray[0], 10);
+            shouldBe(argArray[1], 20);
+            return result;
+        }
+    });
+
+    var proxy2 = new Proxy(Map, {
+        construct(theTarget, argArray, newTarget) {
+        }
+    });
+
+    shouldBe(Reflect.construct(proxy1, [10, 20], proxy2), result);
+}());
index 6ded160..dd2b3ce 100644 (file)
@@ -1,3 +1,84 @@
+2016-03-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Support Reflect.construct
+        https://bugs.webkit.org/show_bug.cgi?id=147330
+
+        Reviewed by Saam Barati.
+
+        * Modules/plugins/QuickTimePluginReplacement.mm:
+        (WebCore::QuickTimePluginReplacement::installReplacement):
+        * bindings/js/CallbackFunction.cpp:
+        (WebCore::checkFunctionOnlyCallback):
+        * bindings/js/JSCallbackData.cpp:
+        (WebCore::JSCallbackData::invokeCallback):
+        * bindings/js/JSCustomElementInterface.cpp:
+        (WebCore::JSCustomElementInterface::constructElement):
+        (WebCore::JSCustomElementInterface::attributeChanged):
+        * bindings/js/JSCustomXPathNSResolver.cpp:
+        (WebCore::JSCustomXPathNSResolver::lookupNamespaceURI):
+        * bindings/js/JSDOMBinding.cpp:
+        (WebCore::callFunctionWithCurrentArguments):
+        (WebCore::DOMConstructorObject::getCallData):
+        * bindings/js/JSDOMConstructor.h:
+        (WebCore::JSDOMConstructorNotConstructable::getCallData):
+        (WebCore::JSDOMConstructor<JSClass>::getConstructData):
+        (WebCore::JSDOMNamedConstructor<JSClass>::getConstructData):
+        (WebCore::JSBuiltinConstructor<JSClass>::getConstructData):
+        * bindings/js/JSDOMPromise.cpp:
+        (WebCore::DeferredWrapper::callFunction):
+        * bindings/js/JSDocumentCustom.cpp:
+        (WebCore::JSDocument::defineElement):
+        * bindings/js/JSErrorHandler.cpp:
+        (WebCore::JSErrorHandler::handleEvent):
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSEventListener::handleEvent):
+        * bindings/js/JSHTMLAllCollectionCustom.cpp:
+        (WebCore::JSHTMLAllCollection::getCallData):
+        * bindings/js/JSHTMLDocumentCustom.cpp:
+        (WebCore::JSHTMLDocument::open):
+        * bindings/js/JSKeyValueIterator.h:
+        (WebCore::keyValueIteratorForEach):
+        * bindings/js/JSMainThreadExecStateInstrumentation.h:
+        (WebCore::JSMainThreadExecState::instrumentFunctionCall):
+        (WebCore::JSMainThreadExecState::instrumentFunctionConstruct):
+        * bindings/js/JSMutationCallback.cpp:
+        (WebCore::JSMutationCallback::call):
+        * bindings/js/JSMutationObserverCustom.cpp:
+        (WebCore::constructJSMutationObserver):
+        * bindings/js/JSPluginElementFunctions.cpp:
+        (WebCore::callPlugin):
+        (WebCore::pluginElementGetCallData):
+        * bindings/js/ScheduledAction.cpp:
+        (WebCore::ScheduledAction::create):
+        (WebCore::ScheduledAction::executeFunctionInContext):
+        * bindings/objc/WebScriptObject.mm:
+        (-[WebScriptObject callWebScriptMethod:withArguments:]):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateConstructorHelperMethods):
+        * bindings/scripts/test/JS/JSFloat64Array.cpp:
+        (WebCore::JSFloat64ArrayConstructor::getConstructData):
+        * bindings/scripts/test/JS/JSTestInterface.cpp:
+        (WebCore::JSTestInterfaceConstructor::getConstructData):
+        * bridge/NP_jsobject.cpp:
+        (_NPN_InvokeDefault):
+        (_NPN_Invoke):
+        (_NPN_Construct):
+        * bridge/objc/objc_runtime.mm:
+        (JSC::Bindings::ObjcFallbackObjectImp::getCallData):
+        * bridge/runtime_method.cpp:
+        (JSC::RuntimeMethod::getCallData):
+        * bridge/runtime_object.cpp:
+        (JSC::Bindings::RuntimeObject::getCallData):
+        (JSC::Bindings::RuntimeObject::getConstructData):
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::updateCaptionContainer):
+        (WebCore::HTMLMediaElement::didAddUserAgentShadowRoot):
+        (WebCore::HTMLMediaElement::getCurrentMediaControlsStatus):
+        * html/HTMLPlugInImageElement.cpp:
+        (WebCore::HTMLPlugInImageElement::didAddUserAgentShadowRoot):
+        * testing/Internals.cpp:
+        (WebCore::Internals::isReadableStreamDisturbed):
+
 2016-03-05  Ryosuke Niwa  <rniwa@webkit.org>
 
         Fix the bindings test after r197611.
index 14fbc4c..a193bb8 100644 (file)
@@ -192,7 +192,7 @@ bool QuickTimePluginReplacement::installReplacement(ShadowRoot* root)
     JSC::JSObject* replacementObject = replacementFunction.toObject(exec);
     JSC::CallData callData;
     JSC::CallType callType = replacementObject->methodTable()->getCallData(replacementObject, callData);
-    if (callType == JSC::CallTypeNone)
+    if (callType == JSC::CallType::None)
         return false;
 
     JSC::MarkedArgumentBuffer argList;
index 145d055..a62cf95 100644 (file)
@@ -40,7 +40,7 @@ bool checkFunctionOnlyCallback(JSC::ExecState* exec, JSC::JSValue value, Callbac
         return false;
 
     JSC::CallData callData;
-    if (getCallData(value, callData) == JSC::CallTypeNone) {
+    if (getCallData(value, callData) == JSC::CallType::None) {
         setDOMException(exec, TYPE_MISMATCH_ERR);
         return false;
     }
index 07d54bc..945ac91 100644 (file)
@@ -49,13 +49,13 @@ JSValue JSCallbackData::invokeCallback(JSObject* callback, MarkedArgumentBuffer&
     ExecState* exec = globalObject->globalExec();
     JSValue function;
     CallData callData;
-    CallType callType = CallTypeNone;
+    CallType callType = CallType::None;
 
     if (method != CallbackType::Object) {
         function = callback;
         callType = callback->methodTable()->getCallData(callback, callData);
     }
-    if (callType == CallTypeNone) {
+    if (callType == CallType::None) {
         if (method == CallbackType::Function) {
             returnedException = Exception::create(exec->vm(), createTypeError(exec));
             return JSValue();
@@ -64,14 +64,14 @@ JSValue JSCallbackData::invokeCallback(JSObject* callback, MarkedArgumentBuffer&
         ASSERT(!functionName.isNull());
         function = callback->get(exec, functionName);
         callType = getCallData(function, callData);
-        if (callType == CallTypeNone) {
+        if (callType == CallType::None) {
             returnedException = Exception::create(exec->vm(), createTypeError(exec));
             return JSValue();
         }
     }
 
     ASSERT(!function.isEmpty());
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     ScriptExecutionContext* context = globalObject->scriptExecutionContext();
     // We will fail to get the context if the frame has been detached.
index 515b6de..525974a 100644 (file)
@@ -77,7 +77,7 @@ RefPtr<Element> JSCustomElementInterface::constructElement(const AtomicString& t
 
     ConstructData constructData;
     ConstructType constructType = m_constructor->methodTable()->getConstructData(m_constructor.get(), constructData);
-    if (constructType == ConstructTypeNone) {
+    if (constructType == ConstructType::None) {
         ASSERT_NOT_REACHED();
         return nullptr;
     }
@@ -125,7 +125,7 @@ void JSCustomElementInterface::attributeChanged(Element& element, const Qualifie
     JSValue callback = jsElement->get(state, attributeChanged);
     CallData callData;
     CallType callType = getCallData(callback, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return;
 
     const AtomicString& namespaceURI = attributeName.namespaceURI();
index d2084a8..ee9f968 100644 (file)
@@ -77,9 +77,9 @@ String JSCustomXPathNSResolver::lookupNamespaceURI(const String& prefix)
     JSValue function = m_customResolver->get(exec, Identifier::fromString(exec, "lookupNamespaceURI"));
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone) {
+    if (callType == CallType::None) {
         callType = m_customResolver->methodTable()->getCallData(m_customResolver.get(), callData);
-        if (callType == CallTypeNone) {
+        if (callType == CallType::None) {
             if (PageConsoleClient* console = m_globalObject->wrapped().console())
                 console->addMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("XPathNSResolver does not have a lookupNamespaceURI method."));
             return String();
index 83b613c..4033502 100644 (file)
@@ -708,7 +708,7 @@ void callFunctionWithCurrentArguments(JSC::ExecState& state, JSC::JSObject& this
 {
     JSC::CallData callData;
     JSC::CallType callType = JSC::getCallData(&function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     JSC::MarkedArgumentBuffer arguments;
     for (unsigned i = 0; i < state.argumentCount(); ++i)
@@ -733,7 +733,7 @@ static EncodedJSValue JSC_HOST_CALL callThrowTypeError(ExecState* exec)
 CallType DOMConstructorObject::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callThrowTypeError;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace WebCore
index eb5dfff..cbbe801 100644 (file)
@@ -52,7 +52,7 @@ private:
     static JSC::CallType getCallData(JSC::JSCell*, JSC::CallData& callData)
     {
         callData.native.function = callThrowTypeError;
-        return JSC::CallTypeHost;
+        return JSC::CallType::Host;
     }
 };
 
@@ -168,7 +168,7 @@ template<typename JSClass> inline void JSDOMConstructor<JSClass>::finishCreation
 template<typename JSClass> inline JSC::ConstructType JSDOMConstructor<JSClass>::getConstructData(JSC::JSCell*, JSC::ConstructData& constructData)
 {
     constructData.native.function = construct;
-    return JSC::ConstructTypeHost;
+    return JSC::ConstructType::Host;
 }
 
 template<typename JSClass> inline JSDOMNamedConstructor<JSClass>* JSDOMNamedConstructor<JSClass>::create(JSC::VM& vm, JSC::Structure* structure, JSDOMGlobalObject& globalObject)
@@ -193,7 +193,7 @@ template<typename JSClass> inline void JSDOMNamedConstructor<JSClass>::finishCre
 template<typename JSClass> inline JSC::ConstructType JSDOMNamedConstructor<JSClass>::getConstructData(JSC::JSCell*, JSC::ConstructData& constructData)
 {
     constructData.native.function = construct;
-    return JSC::ConstructTypeHost;
+    return JSC::ConstructType::Host;
 }
 
 template<typename JSClass> inline JSBuiltinConstructor<JSClass>* JSBuiltinConstructor<JSClass>::create(JSC::VM& vm, JSC::Structure* structure, JSDOMGlobalObject& globalObject)
@@ -232,7 +232,7 @@ template<typename JSClass> inline JSC::JSObject* JSBuiltinConstructor<JSClass>::
 template<typename JSClass> inline JSC::ConstructType JSBuiltinConstructor<JSClass>::getConstructData(JSC::JSCell*, JSC::ConstructData& constructData)
 {
     constructData.native.function = construct;
-    return JSC::ConstructTypeHost;
+    return JSC::ConstructType::Host;
 }
 
 } // namespace WebCore
index dcd132a..988528d 100644 (file)
@@ -55,7 +55,7 @@ void DeferredWrapper::callFunction(ExecState& exec, JSValue function, JSValue re
 {
     CallData callData;
     CallType callType = getCallData(function, callData);
-    ASSERT(callType != CallTypeNone);
+    ASSERT(callType != CallType::None);
 
     MarkedArgumentBuffer arguments;
     arguments.append(resolution);
index 7f57f08..4b5f4a5 100644 (file)
@@ -143,7 +143,7 @@ JSValue JSDocument::defineElement(ExecState& state)
 
     JSObject* object = state.argument(1).getObject();
     ConstructData callData;
-    if (!object || object->methodTable()->getConstructData(object, callData) == ConstructTypeNone)
+    if (!object || object->methodTable()->getConstructData(object, callData) == ConstructType::None)
         return throwTypeError(&state, "The second argument must be a constructor");
 
     Document& document = wrapped();
index 29f8703..6eba4de 100644 (file)
@@ -83,7 +83,7 @@ void JSErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext,
     CallData callData;
     CallType callType = jsFunction->methodTable()->getCallData(jsFunction, callData);
 
-    if (callType != CallTypeNone) {
+    if (callType != CallType::None) {
         Ref<JSErrorHandler> protectedctor(*this);
 
         Event* savedEvent = globalObject->currentEvent();
index 21c896e..ee1ed93 100644 (file)
@@ -105,12 +105,12 @@ void JSEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext
     CallData callData;
     CallType callType = getCallData(handleEventFunction, callData);
     // If jsFunction is not actually a function, see if it implements the EventListener interface and use that
-    if (callType == CallTypeNone) {
+    if (callType == CallType::None) {
         handleEventFunction = jsFunction->get(exec, Identifier::fromString(exec, "handleEvent"));
         callType = getCallData(handleEventFunction, callData);
     }
 
-    if (callType != CallTypeNone) {
+    if (callType != CallType::None) {
         Ref<JSEventListener> protect(*this);
 
         MarkedArgumentBuffer args;
index c988198..d190250 100644 (file)
@@ -89,7 +89,7 @@ static EncodedJSValue JSC_HOST_CALL callHTMLAllCollection(ExecState* exec)
 CallType JSHTMLAllCollection::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callHTMLAllCollection;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 bool JSHTMLAllCollection::nameGetter(ExecState* state, PropertyName propertyName, JSValue& value)
index f64e5fc..af4042d 100644 (file)
@@ -144,7 +144,7 @@ JSValue JSHTMLDocument::open(ExecState& state)
                 JSValue function = wrapper->get(&state, Identifier::fromString(&state, "open"));
                 CallData callData;
                 CallType callType = ::getCallData(function, callData);
-                if (callType == CallTypeNone)
+                if (callType == CallType::None)
                     return throwTypeError(&state);
                 return JSC::call(&state, function, callType, callData, wrapper, ArgList(&state));
             }
index 62272f5..c26e946 100644 (file)
@@ -123,7 +123,7 @@ JSC::EncodedJSValue keyValueIteratorForEach(JSC::ExecState& state, const char* p
 
     JSC::CallData callData;
     JSC::CallType callType = JSC::getCallData(state.argument(0), callData);
-    if (callType == JSC::CallTypeNone)
+    if (callType == JSC::CallType::None)
         return throwVMTypeError(&state);
 
     auto iterator = wrapper->wrapped().createIterator();
index 4b12b45..ce7e35b 100644 (file)
@@ -50,12 +50,12 @@ inline InspectorInstrumentationCookie JSMainThreadExecState::instrumentFunctionI
 
 inline InspectorInstrumentationCookie JSMainThreadExecState::instrumentFunctionCall(ScriptExecutionContext* context, JSC::CallType type, const JSC::CallData& data)
 {
-    return instrumentFunctionInternal<JSC::CallType, JSC::CallTypeJS, JSC::CallData>(context, type, data);
+    return instrumentFunctionInternal<JSC::CallType, JSC::CallType::JS, JSC::CallData>(context, type, data);
 }
 
 inline InspectorInstrumentationCookie JSMainThreadExecState::instrumentFunctionConstruct(ScriptExecutionContext* context, JSC::ConstructType type, const JSC::ConstructData& data)
 {
-    return instrumentFunctionInternal<JSC::ConstructType, JSC::ConstructTypeJS, JSC::ConstructData>(context, type, data);
+    return instrumentFunctionInternal<JSC::ConstructType, JSC::ConstructType::JS, JSC::ConstructData>(context, type, data);
 }
 
 } // namespace WebCore
index f11660d..efe35aa 100644 (file)
@@ -66,7 +66,7 @@ void JSMutationCallback::call(const Vector<RefPtr<MutationRecord>>& mutations, M
     JSValue callback = m_callback.get();
     CallData callData;
     CallType callType = getCallData(callback, callData);
-    if (callType == CallTypeNone) {
+    if (callType == CallType::None) {
         ASSERT_NOT_REACHED();
         return;
     }
index c6c5724..c73fca3 100644 (file)
@@ -50,7 +50,7 @@ EncodedJSValue JSC_HOST_CALL constructJSMutationObserver(ExecState* exec)
 
     JSObject* object = exec->argument(0).getObject();
     CallData callData;
-    if (!object || object->methodTable()->getCallData(object, callData) == CallTypeNone)
+    if (!object || object->methodTable()->getCallData(object, callData) == CallType::None)
         return throwVMError(exec, createTypeError(exec, "Callback argument must be a function"));
 
     DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec->callee());
index cd183f6..7ea73b1 100644 (file)
@@ -145,7 +145,7 @@ static EncodedJSValue JSC_HOST_CALL callPlugin(ExecState* exec)
 
     CallData callData;
     CallType callType = getCallData(scriptObject, callData);
-    ASSERT(callType == CallTypeHost);
+    ASSERT(callType == CallType::Host);
 
     // Call the object.
     JSValue result = call(exec, scriptObject, callType, callData, exec->thisValue(), argumentList);
@@ -158,18 +158,18 @@ CallType pluginElementGetCallData(JSHTMLElement* element, CallData& callData)
     if (JSObject* scriptObject = pluginScriptObjectFromPluginViewBase(element)) {
         CallData scriptObjectCallData;
         
-        if (scriptObject->methodTable()->getCallData(scriptObject, scriptObjectCallData) == CallTypeNone)
-            return CallTypeNone;
+        if (scriptObject->methodTable()->getCallData(scriptObject, scriptObjectCallData) == CallType::None)
+            return CallType::None;
 
         callData.native.function = callPlugin;
-        return CallTypeHost;
+        return CallType::Host;
     }
     
     Instance* instance = pluginInstance(element->wrapped());
     if (!instance || !instance->supportsInvokeDefaultMethod())
-        return CallTypeNone;
+        return CallType::None;
     callData.native.function = callPlugin;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace WebCore
index 50f793a..0d16be4 100644 (file)
@@ -50,7 +50,7 @@ std::unique_ptr<ScheduledAction> ScheduledAction::create(ExecState* exec, DOMWra
 {
     JSValue v = exec->argument(0);
     CallData callData;
-    if (getCallData(v, callData) == CallTypeNone) {
+    if (getCallData(v, callData) == CallType::None) {
         if (policy && !policy->allowEval(exec))
             return nullptr;
         String string = v.toString(exec)->value(exec);
@@ -87,7 +87,7 @@ void ScheduledAction::executeFunctionInContext(JSGlobalObject* globalObject, JSV
 
     CallData callData;
     CallType callType = getCallData(m_function.get(), callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return;
 
     ExecState* exec = globalObject->globalExec();
index 0466329..19f7c3a 100644 (file)
@@ -58,7 +58,7 @@ using namespace WebCore;
 
 using JSC::CallData;
 using JSC::CallType;
-using JSC::CallTypeNone;
+using JSC::CallType::None;
 using JSC::ExecState;
 using JSC::Identifier;
 using JSC::JSLockHolder;
@@ -315,7 +315,7 @@ static void getListFromNSArray(ExecState *exec, NSArray *array, RootObject* root
     JSC::JSValue function = [self _imp]->get(exec, Identifier::fromString(exec, String(name)));
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return nil;
 
     MarkedArgumentBuffer argList;
index 2f72404..be1f8e6 100644 (file)
@@ -5064,7 +5064,7 @@ sub GenerateConstructorHelperMethods
         push(@$outputArray, "#if $conditionalString\n");
         push(@$outputArray, "    UNUSED_PARAM(cell);\n");
         push(@$outputArray, "    constructData.native.function = construct;\n");
-        push(@$outputArray, "    return ConstructTypeHost;\n");
+        push(@$outputArray, "    return ConstructType::Host;\n");
         push(@$outputArray, "#else\n");
         push(@$outputArray, "    return Base::getConstructData(cell, constructData);\n");
         push(@$outputArray, "#endif\n");
index eae20f5..2450dd9 100644 (file)
@@ -106,7 +106,7 @@ bool JSFloat64ArrayConstructor::getOwnPropertyDescriptor(JSObject* object, ExecS
 ConstructType JSFloat64ArrayConstructor::getConstructData(JSCell*, ConstructData& constructData)
 {
     constructData.native.function = constructJSFloat64Array;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 /* Hash table for prototype */
index 27d62c4..e796ea4 100644 (file)
@@ -264,7 +264,7 @@ template<> ConstructType JSTestInterfaceConstructor::getConstructData(JSCell* ce
 #if ENABLE(TEST_INTERFACE)
     UNUSED_PARAM(cell);
     constructData.native.function = construct;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 #else
     return Base::getConstructData(cell, constructData);
 #endif
index a3985d7..2fa9a7a 100644 (file)
@@ -184,7 +184,7 @@ bool _NPN_InvokeDefault(NPP, NPObject* o, const NPVariant* args, uint32_t argCou
         JSValue function = obj->imp;
         CallData callData;
         CallType callType = getCallData(function, callData);
-        if (callType == CallTypeNone)
+        if (callType == CallType::None)
             return false;
         
         MarkedArgumentBuffer argList;
@@ -230,7 +230,7 @@ bool _NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVariant*
         JSValue function = obj->imp->get(exec, identifierFromNPIdentifier(exec, i->string()));
         CallData callData;
         CallType callType = getCallData(function, callData);
-        if (callType == CallTypeNone)
+        if (callType == CallType::None)
             return false;
 
         // Call the function object.
@@ -487,7 +487,7 @@ bool _NPN_Construct(NPP, NPObject* o, const NPVariant* args, uint32_t argCount,
         JSValue constructor = obj->imp;
         ConstructData constructData;
         ConstructType constructType = getConstructData(constructor, constructData);
-        if (constructType == ConstructTypeNone)
+        if (constructType == ConstructType::None)
             return false;
         
         MarkedArgumentBuffer argList;
index fec1098..a6c9023 100644 (file)
@@ -261,9 +261,9 @@ CallType ObjcFallbackObjectImp::getCallData(JSCell* cell, CallData& callData)
     ObjcFallbackObjectImp* thisObject = jsCast<ObjcFallbackObjectImp*>(cell);
     id targetObject = thisObject->_instance->getObject();
     if (![targetObject respondsToSelector:@selector(invokeUndefinedMethodFromWebScript:withArguments:)])
-        return CallTypeNone;
+        return CallType::None;
     callData.native.function = callObjCFallbackObject;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 bool ObjcFallbackObjectImp::deleteProperty(JSCell*, ExecState*, PropertyName)
index f4b0bb4..ae2b2b9 100644 (file)
@@ -106,7 +106,7 @@ static EncodedJSValue JSC_HOST_CALL callRuntimeMethod(ExecState* exec)
 CallType RuntimeMethod::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callRuntimeMethod;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 }
index 7366f92..f7f98bf 100644 (file)
@@ -216,14 +216,14 @@ CallType RuntimeObject::getCallData(JSCell* cell, CallData& callData)
 {
     RuntimeObject* thisObject = jsCast<RuntimeObject*>(cell);
     if (!thisObject->m_instance)
-        return CallTypeNone;
+        return CallType::None;
     
     RefPtr<Instance> instance = thisObject->m_instance;
     if (!instance->supportsInvokeDefaultMethod())
-        return CallTypeNone;
+        return CallType::None;
     
     callData.native.function = callRuntimeObject;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 static EncodedJSValue JSC_HOST_CALL callRuntimeConstructor(ExecState* exec)
@@ -244,14 +244,14 @@ ConstructType RuntimeObject::getConstructData(JSCell* cell, ConstructData& const
 {
     RuntimeObject* thisObject = jsCast<RuntimeObject*>(cell);
     if (!thisObject->m_instance)
-        return ConstructTypeNone;
+        return ConstructType::None;
     
     RefPtr<Instance> instance = thisObject->m_instance;
     if (!instance->supportsConstruct())
-        return ConstructTypeNone;
+        return ConstructType::None;
     
     constructData.native.function = callRuntimeConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 void RuntimeObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode)
index d558c7a..4adc51d 100644 (file)
@@ -3920,7 +3920,7 @@ void HTMLMediaElement::updateCaptionContainer()
 
     JSC::CallData callData;
     JSC::CallType callType = methodObject->methodTable()->getCallData(methodObject, callData);
-    if (callType == JSC::CallTypeNone)
+    if (callType == JSC::CallType::None)
         return;
 
     JSC::MarkedArgumentBuffer noArguments;
@@ -6357,7 +6357,7 @@ void HTMLMediaElement::didAddUserAgentShadowRoot(ShadowRoot* root)
     JSC::JSObject* function = functionValue.toObject(exec);
     JSC::CallData callData;
     JSC::CallType callType = function->methodTable()->getCallData(function, callData);
-    if (callType == JSC::CallTypeNone)
+    if (callType == JSC::CallType::None)
         return;
 
     JSC::JSValue controllerValue = JSC::call(exec, function, callType, callData, globalObject, argList);
@@ -6452,7 +6452,7 @@ String HTMLMediaElement::getCurrentMediaControlsStatus()
     JSC::CallData callData;
     JSC::CallType callType = function->methodTable()->getCallData(function, callData);
     JSC::MarkedArgumentBuffer argList;
-    if (callType == JSC::CallTypeNone)
+    if (callType == JSC::CallType::None)
         return "";
 
     JSC::JSValue outputValue = JSC::call(exec, function, callType, callData, controllerObject, argList);
index 2a40da1..5133274 100644 (file)
@@ -406,7 +406,7 @@ void HTMLPlugInImageElement::didAddUserAgentShadowRoot(ShadowRoot* root)
     JSC::JSObject* overlay = globalObject->get(exec, JSC::Identifier::fromString(exec, "createOverlay")).toObject(exec);
     JSC::CallData callData;
     JSC::CallType callType = overlay->methodTable()->getCallData(overlay, callData);
-    if (callType == JSC::CallTypeNone)
+    if (callType == JSC::CallType::None)
         return;
 
     JSC::call(exec, overlay, callType, callData, globalObject, argList);
index d806523..31a0e72 100644 (file)
@@ -3468,7 +3468,7 @@ bool Internals::isReadableStreamDisturbed(ScriptState& state, JSValue stream)
     JSObject* function = value.getObject();
     CallData callData;
     CallType callType = JSC::getCallData(function, callData);
-    ASSERT(callType != JSC::CallTypeNone);
+    ASSERT(callType != JSC::CallType::None);
     MarkedArgumentBuffer arguments;
     arguments.append(stream);
     JSValue returnedValue = JSC::call(&state, function, callType, callData, JSC::jsUndefined(), arguments);
index 064bd68..0498396 100644 (file)
@@ -1,3 +1,15 @@
+2016-03-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Support Reflect.construct
+        https://bugs.webkit.org/show_bug.cgi?id=147330
+
+        Reviewed by Saam Barati.
+
+        * Plugins/Hosted/NetscapePluginInstanceProxy.mm:
+        (WebKit::NetscapePluginInstanceProxy::invoke):
+        (WebKit::NetscapePluginInstanceProxy::invokeDefault):
+        (WebKit::NetscapePluginInstanceProxy::construct):
+
 2016-03-04  Brent Fulgham  <bfulgham@apple.com>
 
         Unreviewed test fix for null global WebResourceLoadStatisticsStore.
index fe8c14f..5b0c90a 100644 (file)
@@ -919,7 +919,7 @@ bool NetscapePluginInstanceProxy::invoke(uint32_t objectID, const Identifier& me
     JSValue function = object->get(exec, methodName);
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return false;
 
     MarkedArgumentBuffer argList;
@@ -951,7 +951,7 @@ bool NetscapePluginInstanceProxy::invokeDefault(uint32_t objectID, data_t argume
     JSLockHolder lock(exec);    
     CallData callData;
     CallType callType = object->methodTable()->getCallData(object, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return false;
 
     MarkedArgumentBuffer argList;
@@ -984,7 +984,7 @@ bool NetscapePluginInstanceProxy::construct(uint32_t objectID, data_t argumentsD
 
     ConstructData constructData;
     ConstructType constructType = object->methodTable()->getConstructData(object, constructData);
-    if (constructType == ConstructTypeNone)
+    if (constructType == ConstructType::None)
         return false;
 
     MarkedArgumentBuffer argList;
index 8ac82a9..0997e0a 100644 (file)
@@ -1,3 +1,13 @@
+2016-03-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Support Reflect.construct
+        https://bugs.webkit.org/show_bug.cgi?id=147330
+
+        Reviewed by Saam Barati.
+
+        * Plugins/PluginPackage.cpp:
+        (WebCore::NPN_Invoke):
+
 2016-02-24  Per Arne Vollan  <peavo@outlook.com>
 
         [WinCairo] Mark layer as non composited.
index 787edda..cb39d1e 100644 (file)
@@ -252,7 +252,7 @@ static bool NPN_Invoke(NPP npp, NPObject* o, NPIdentifier methodName, const NPVa
         JSC::JSValue function = obj->imp->get(exec, JSC::Bindings::identifierFromNPIdentifier(exec, i->string()));
         JSC::CallData callData;
         JSC::CallType callType = getCallData(function, callData);
-        if (callType == JSC::CallTypeNone)
+        if (callType == JSC::CallType::None)
             return false;
 
         // Call the function object.
index 24c6451..2e2425a 100644 (file)
@@ -1,3 +1,20 @@
+2016-03-05  Yusuke Suzuki  <utatane.tea@gmail.com>
+
+        [ES6] Support Reflect.construct
+        https://bugs.webkit.org/show_bug.cgi?id=147330
+
+        Reviewed by Saam Barati.
+
+        * WebProcess/Plugins/Netscape/JSNPMethod.cpp:
+        (WebKit::JSNPMethod::getCallData):
+        * WebProcess/Plugins/Netscape/JSNPObject.cpp:
+        (WebKit::JSNPObject::getCallData):
+        (WebKit::JSNPObject::getConstructData):
+        * WebProcess/Plugins/Netscape/NPJSObject.cpp:
+        (WebKit::NPJSObject::hasMethod):
+        (WebKit::NPJSObject::construct):
+        (WebKit::NPJSObject::invoke):
+
 2016-03-04  Alex Christensen  <achristensen@webkit.org>
 
         Fix file mime-types when using NetworkSession
index 214838c..ba61677 100644 (file)
@@ -84,7 +84,7 @@ static EncodedJSValue JSC_HOST_CALL callMethod(ExecState* exec)
 CallType JSNPMethod::getCallData(JSCell*, CallData& callData)
 {
     callData.native.function = callMethod;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 } // namespace WebKit
index 5377f91..a905b3d 100644 (file)
@@ -238,10 +238,10 @@ JSC::CallType JSNPObject::getCallData(JSC::JSCell* cell, JSC::CallData& callData
     JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     if (!thisObject->m_npObject || !thisObject->m_npObject->_class->invokeDefault)
-        return CallTypeNone;
+        return CallType::None;
 
     callData.native.function = callNPJSObject;
-    return CallTypeHost;
+    return CallType::Host;
 }
 
 static EncodedJSValue JSC_HOST_CALL constructWithConstructor(ExecState* exec)
@@ -257,10 +257,10 @@ ConstructType JSNPObject::getConstructData(JSCell* cell, ConstructData& construc
     JSNPObject* thisObject = JSC::jsCast<JSNPObject*>(cell);
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     if (!thisObject->m_npObject || !thisObject->m_npObject->_class->construct)
-        return ConstructTypeNone;
+        return ConstructType::None;
 
     constructData.native.function = constructWithConstructor;
-    return ConstructTypeHost;
+    return ConstructType::Host;
 }
 
 bool JSNPObject::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
index ffc7793..20e6b20 100644 (file)
@@ -107,7 +107,7 @@ bool NPJSObject::hasMethod(NPIdentifier methodName)
     exec->clearException();
 
     CallData callData;
-    return getCallData(value, callData) != CallTypeNone;
+    return getCallData(value, callData) != CallType::None;
 }
 
 bool NPJSObject::invoke(NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, NPVariant* result)
@@ -263,7 +263,7 @@ bool NPJSObject::construct(const NPVariant* arguments, uint32_t argumentCount, N
 
     ConstructData constructData;
     ConstructType constructType = getConstructData(m_jsObject.get(), constructData);
-    if (constructType == ConstructTypeNone)
+    if (constructType == ConstructType::None)
         return false;
 
     // Convert the passed in arguments.
@@ -284,7 +284,7 @@ bool NPJSObject::invoke(ExecState* exec, JSGlobalObject* globalObject, JSValue f
 {
     CallData callData;
     CallType callType = getCallData(function, callData);
-    if (callType == CallTypeNone)
+    if (callType == CallType::None)
         return false;
 
     // Convert the passed in arguments.