Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (266106 => 266107)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2020-08-25 08:06:48 UTC (rev 266107)
@@ -818,6 +818,7 @@
runtime/CommonIdentifiers.h
runtime/CompilationResult.h
runtime/Completion.h
+ runtime/Concurrency.h
runtime/ConcurrentJSLock.h
runtime/ConfigFile.h
runtime/ConsoleClient.h
Modified: trunk/Source/_javascript_Core/ChangeLog (266106 => 266107)
--- trunk/Source/_javascript_Core/ChangeLog 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-08-25 08:06:48 UTC (rev 266107)
@@ -1,3 +1,48 @@
+2020-08-25 Yusuke Suzuki <[email protected]>
+
+ [JSC] Add concurrency-aware version of isCallable / isConstructor to make it usable in DFG compiler
+ https://bugs.webkit.org/show_bug.cgi?id=215746
+
+ Reviewed by Saam Barati.
+
+ This patch adds isCallableWithConcurrency and isConstructorWithConcurrency to JSCell, JSValue etc.
+ This can work even if it is called from concurrent compiler threads. We also add jsTypeStringForValueWithConcurrency
+ and jsTypeofIsFunctionWithConcurrency which are using the above WithConcurrency functionalities.
+
+ * CMakeLists.txt:
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
+ * runtime/Concurrency.h: Added.
+ (WTF::printInternal):
+ * runtime/InternalFunction.cpp:
+ (JSC::InternalFunction::finishCreation):
+ (JSC::InternalFunction::getCallData):
+ (JSC::InternalFunction::getConstructData):
+ * runtime/JSCJSValue.h:
+ * runtime/JSCJSValueInlines.h:
+ (JSC::JSValue::isCallableWithConcurrency const):
+ (JSC::JSValue::isConstructorWithConcurrency const):
+ * runtime/JSCell.h:
+ * runtime/JSCellInlines.h:
+ (JSC::JSCell::isCallableWithConcurrency):
+ (JSC::JSCell::isConstructorWithConcurrency):
+ (JSC::JSCell::isCallable):
+ (JSC::JSCell::isConstructor):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::finishCreation):
+ (JSC::JSFunction::getCallData):
+ (JSC::JSFunction::getConstructData):
+ * runtime/NumberPrototype.cpp:
+ (JSC::throwVMToThisNumberError):
+ * runtime/Operations.cpp:
+ (JSC::jsTypeStringForValueWithConcurrency):
+ (JSC::jsTypeStringForValue): Deleted.
+ * runtime/Operations.h:
+ (JSC::jsTypeofIsFunctionWithConcurrency):
+ (JSC::jsTypeStringForValue):
+ (JSC::jsTypeofIsFunction):
+
2020-08-25 Alexey Shvayka <[email protected]>
Implementation of the class "extends" clause incorrectly uses __proto__ for setting prototypes
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (266106 => 266107)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2020-08-25 08:06:48 UTC (rev 266107)
@@ -1848,6 +1848,7 @@
E365F33B24AA623B00C991B2 /* IntlDisplayNamesPrototype.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E365F33824AA621100C991B2 /* IntlDisplayNamesPrototype.lut.h */; };
E36B767022F8D61900D09818 /* WasmOMGForOSREntryPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = E36B766F22F8D61100D09818 /* WasmOMGForOSREntryPlan.h */; };
E36CC9472086314F0051FFD6 /* WasmCreationMode.h in Headers */ = {isa = PBXBuildFile; fileRef = E36CC9462086314F0051FFD6 /* WasmCreationMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E36EDCE524F0975700E60DA2 /* Concurrency.h in Headers */ = {isa = PBXBuildFile; fileRef = E36EDCE424F0975700E60DA2 /* Concurrency.h */; settings = {ATTRIBUTES = (Private, ); }; };
E3794E761B77EB97005543AE /* ModuleAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = E3794E741B77EB97005543AE /* ModuleAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
E383500A2390D93B0036316D /* WasmGlobal.h in Headers */ = {isa = PBXBuildFile; fileRef = E38350092390D9370036316D /* WasmGlobal.h */; };
E3850B15226ED641009ABF9C /* DFGMinifiedIDInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3850B14226ED63E009ABF9C /* DFGMinifiedIDInlines.h */; };
@@ -5047,6 +5048,7 @@
E36B766E22F8D61100D09818 /* WasmOMGForOSREntryPlan.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOMGForOSREntryPlan.cpp; sourceTree = "<group>"; };
E36B766F22F8D61100D09818 /* WasmOMGForOSREntryPlan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WasmOMGForOSREntryPlan.h; sourceTree = "<group>"; };
E36CC9462086314F0051FFD6 /* WasmCreationMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmCreationMode.h; sourceTree = "<group>"; };
+ E36EDCE424F0975700E60DA2 /* Concurrency.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Concurrency.h; sourceTree = "<group>"; };
E3794E731B77EB97005543AE /* ModuleAnalyzer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModuleAnalyzer.cpp; sourceTree = "<group>"; };
E3794E741B77EB97005543AE /* ModuleAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleAnalyzer.h; sourceTree = "<group>"; };
E37CFB2D22F27C57009A7B38 /* WasmCompilationMode.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmCompilationMode.cpp; sourceTree = "<group>"; };
@@ -7155,6 +7157,7 @@
A7E5A3A61797432D00E893C0 /* CompilationResult.h */,
969A09220ED1E09C00F1F681 /* Completion.cpp */,
F5BB2BC5030F772101FCFE1D /* Completion.h */,
+ E36EDCE424F0975700E60DA2 /* Concurrency.h */,
0FDB2CE9174896C7007B3C1B /* ConcurrentJSLock.h */,
658824B01E5CFDF400FB7359 /* ConfigFile.cpp */,
658824AE1E5CFDB000FB7359 /* ConfigFile.h */,
@@ -9316,6 +9319,7 @@
0FD2FD9420B52BDE00F09441 /* CompleteSubspaceInlines.h in Headers */,
BC18C3F40E16F5CD00B34460 /* Completion.h in Headers */,
0F6FC751196110A800E1D02D /* ComplexGetStatus.h in Headers */,
+ E36EDCE524F0975700E60DA2 /* Concurrency.h in Headers */,
0FDB2CEA174896C7007B3C1B /* ConcurrentJSLock.h in Headers */,
BC18C3F50E16F5CD00B34460 /* config.h in Headers */,
658824AF1E5CFDB000FB7359 /* ConfigFile.h in Headers */,
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (266106 => 266107)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2020-08-25 08:06:48 UTC (rev 266107)
@@ -1491,9 +1491,14 @@
} else
setConstant(node, jsBoolean(child.value().isNull()));
break;
- case TypeOfIsFunction:
- setConstant(node, jsBoolean(jsTypeofIsFunction(m_codeBlock->globalObjectFor(node->origin.semantic), child.value())));
+ case TypeOfIsFunction: {
+ TriState result = jsTypeofIsFunctionWithConcurrency<Concurrency::ConcurrentThread>(m_codeBlock->globalObjectFor(node->origin.semantic), child.value());
+ if (result != TriState::Indeterminate)
+ setConstant(node, jsBoolean(result == TriState::True));
+ else
+ constantWasSet = false;
break;
+ }
case IsUndefinedOrNull:
setConstant(node, jsBoolean(child.value().isUndefinedOrNull()));
break;
@@ -1512,12 +1517,22 @@
case IsObject:
setConstant(node, jsBoolean(child.value().isObject()));
break;
- case IsCallable:
- setConstant(node, jsBoolean(child.value().isCallable(m_vm)));
+ case IsCallable: {
+ TriState result = child.value().isCallableWithConcurrency<Concurrency::ConcurrentThread>(m_vm);
+ if (result != TriState::Indeterminate)
+ setConstant(node, jsBoolean(result == TriState::True));
+ else
+ constantWasSet = false;
break;
- case IsConstructor:
- setConstant(node, jsBoolean(child.value().isConstructor(m_vm)));
+ }
+ case IsConstructor: {
+ TriState result = child.value().isConstructorWithConcurrency<Concurrency::ConcurrentThread>(m_vm);
+ if (result != TriState::Indeterminate)
+ setConstant(node, jsBoolean(result == TriState::True));
+ else
+ constantWasSet = false;
break;
+ }
case IsEmpty:
setConstant(node, jsBoolean(child.value().isEmpty()));
break;
@@ -1782,9 +1797,10 @@
JSValue child = forNode(node->child1()).value();
AbstractValue& abstractChild = forNode(node->child1());
if (child) {
- JSValue typeString = jsTypeStringForValue(m_vm, m_codeBlock->globalObjectFor(node->origin.semantic), child);
- setConstant(node, *m_graph.freeze(typeString));
- break;
+ if (JSString* typeString = jsTypeStringForValueWithConcurrency(m_vm, m_codeBlock->globalObjectFor(node->origin.semantic), child, Concurrency::ConcurrentThread)) {
+ setConstant(node, *m_graph.freeze(typeString));
+ break;
+ }
}
if (isFullNumberSpeculation(abstractChild.m_type)) {
Added: trunk/Source/_javascript_Core/runtime/Concurrency.h (0 => 266107)
--- trunk/Source/_javascript_Core/runtime/Concurrency.h (rev 0)
+++ trunk/Source/_javascript_Core/runtime/Concurrency.h 2020-08-25 08:06:48 UTC (rev 266107)
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/PrintStream.h>
+
+namespace JSC {
+
+enum class Concurrency : uint8_t {
+ MainThread,
+ ConcurrentThread,
+};
+
+} // namespace JSC
+
+namespace WTF {
+
+inline void printInternal(PrintStream& out, JSC::Concurrency concurrency)
+{
+ switch (concurrency) {
+ case JSC::Concurrency::MainThread:
+ out.print("MainThread");
+ return;
+ case JSC::Concurrency::ConcurrentThread:
+ out.print("ConcurrentThread");
+ return;
+ }
+ RELEASE_ASSERT_NOT_REACHED();
+}
+
+} // namespace WTF
+
Modified: trunk/Source/_javascript_Core/runtime/InternalFunction.cpp (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/InternalFunction.cpp 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/InternalFunction.cpp 2020-08-25 08:06:48 UTC (rev 266107)
@@ -47,6 +47,7 @@
{
Base::finishCreation(vm);
ASSERT(jsDynamicCast<InternalFunction*>(vm, this));
+ // JSCell::{getCallData,getConstructData} relies on the following conditions.
ASSERT(methodTable(vm)->getCallData == InternalFunction::info()->methodTable.getCallData);
ASSERT(methodTable(vm)->getConstructData == InternalFunction::info()->methodTable.getConstructData);
ASSERT(type() == InternalFunctionType || type() == NullSetterFunctionType);
@@ -86,6 +87,7 @@
CallData InternalFunction::getCallData(JSCell* cell)
{
+ // Keep this function OK for invocation from concurrent compilers.
auto* function = jsCast<InternalFunction*>(cell);
ASSERT(function->m_functionForCall);
@@ -97,6 +99,7 @@
CallData InternalFunction::getConstructData(JSCell* cell)
{
+ // Keep this function OK for invocation from concurrent compilers.
CallData constructData;
auto* function = jsCast<InternalFunction*>(cell);
if (function->m_functionForConstruct != callHostFunctionAsConstructor) {
Modified: trunk/Source/_javascript_Core/runtime/JSCJSValue.h (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/JSCJSValue.h 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValue.h 2020-08-25 08:06:48 UTC (rev 266107)
@@ -22,6 +22,7 @@
#pragma once
+#include "Concurrency.h"
#include "ECMAMode.h"
#include "JSExportMacros.h"
#include "PureNaN.h"
@@ -233,7 +234,9 @@
// Querying the type.
bool isEmpty() const;
bool isCallable(VM&) const;
+ template<Concurrency> TriState isCallableWithConcurrency(VM&) const;
bool isConstructor(VM&) const;
+ template<Concurrency> TriState isConstructorWithConcurrency(VM&) const;
bool isUndefined() const;
bool isNull() const;
bool isUndefinedOrNull() const;
Modified: trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValueInlines.h 2020-08-25 08:06:48 UTC (rev 266107)
@@ -920,11 +920,27 @@
return isCell() && asCell()->isCallable(vm);
}
+template<Concurrency concurrency>
+inline TriState JSValue::isCallableWithConcurrency(VM& vm) const
+{
+ if (!isCell())
+ return TriState::False;
+ return asCell()->isCallableWithConcurrency<concurrency>(vm);
+}
+
inline bool JSValue::isConstructor(VM& vm) const
{
return isCell() && asCell()->isConstructor(vm);
}
+template<Concurrency concurrency>
+inline TriState JSValue::isConstructorWithConcurrency(VM& vm) const
+{
+ if (!isCell())
+ return TriState::False;
+ return asCell()->isConstructorWithConcurrency<concurrency>(vm);
+}
+
// this method is here to be after the inline declaration of JSCell::inherits
inline bool JSValue::inherits(VM& vm, const ClassInfo* classInfo) const
{
Modified: trunk/Source/_javascript_Core/runtime/JSCell.h (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/JSCell.h 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/JSCell.h 2020-08-25 08:06:48 UTC (rev 266107)
@@ -109,6 +109,8 @@
bool isProxy() const;
bool isCallable(VM&);
bool isConstructor(VM&);
+ template<Concurrency> TriState isCallableWithConcurrency(VM&);
+ template<Concurrency> TriState isConstructorWithConcurrency(VM&);
bool inherits(VM&, const ClassInfo*) const;
template<typename Target> bool inherits(VM&) const;
bool isAPIValueWrapper() const;
Modified: trunk/Source/_javascript_Core/runtime/JSCellInlines.h (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/JSCellInlines.h 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/JSCellInlines.h 2020-08-25 08:06:48 UTC (rev 266107)
@@ -241,20 +241,55 @@
return m_type == ImpureProxyType || m_type == PureForwardingProxyType || m_type == ProxyObjectType;
}
-ALWAYS_INLINE bool JSCell::isCallable(VM& vm)
+// FIXME: Consider making getCallData concurrency-safe once NPAPI support is removed.
+// https://bugs.webkit.org/show_bug.cgi?id=215801
+template<Concurrency concurrency>
+ALWAYS_INLINE TriState JSCell::isCallableWithConcurrency(VM& vm)
{
+ if (!isObject())
+ return TriState::False;
if (type() == JSFunctionType)
- return true;
- if (inlineTypeFlags() & OverridesGetCallData)
- return methodTable(vm)->getCallData(this).type != CallData::Type::None;
- return false;
+ return TriState::True;
+ if (inlineTypeFlags() & OverridesGetCallData) {
+ if constexpr (concurrency == Concurrency::MainThread)
+ return (methodTable(vm)->getCallData(this).type != CallData::Type::None) ? TriState::True : TriState::False;
+ // We know that InternalFunction::getCallData is concurrency aware. Plus, derived classes of InternalFunction never
+ // override getCallData (this is ensured by ASSERT in InternalFunction).
+ if (type() == InternalFunctionType)
+ return (methodTable(vm)->getCallData(this).type != CallData::Type::None) ? TriState::True : TriState::False;
+ return TriState::Indeterminate;
+ }
+ return TriState::False;
}
-inline bool JSCell::isConstructor(VM& vm)
+template<Concurrency concurrency>
+inline TriState JSCell::isConstructorWithConcurrency(VM& vm)
{
- return methodTable(vm)->getConstructData(this).type != CallData::Type::None;
+ if (!isObject())
+ return TriState::False;
+ if constexpr (concurrency == Concurrency::MainThread)
+ return (methodTable(vm)->getConstructData(this).type != CallData::Type::None) ? TriState::True : TriState::False;
+ // We know that both getConstructData of both types are concurrency aware. Plus, derived classes of JSFunction and InternalFunction
+ // never override getConstructData (this is ensured by ASSERT in JSFunction and InternalFunction).
+ if (type() == JSFunctionType || type() == InternalFunctionType)
+ return (methodTable(vm)->getConstructData(this).type != CallData::Type::None) ? TriState::True : TriState::False;
+ return TriState::Indeterminate;
}
+ALWAYS_INLINE bool JSCell::isCallable(VM& vm)
+{
+ auto result = isCallableWithConcurrency<Concurrency::MainThread>(vm);
+ ASSERT(result != TriState::Indeterminate);
+ return result == TriState::True;
+}
+
+ALWAYS_INLINE bool JSCell::isConstructor(VM& vm)
+{
+ auto result = isConstructorWithConcurrency<Concurrency::MainThread>(vm);
+ ASSERT(result != TriState::Indeterminate);
+ return result == TriState::True;
+}
+
inline bool JSCell::isAPIValueWrapper() const
{
return m_type == APIValueWrapperType;
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2020-08-25 08:06:48 UTC (rev 266107)
@@ -109,6 +109,7 @@
Base::finishCreation(vm);
ASSERT(jsDynamicCast<JSFunction*>(vm, this));
ASSERT(type() == JSFunctionType);
+ // JSCell::{getCallData,getConstructData} relies on the following conditions.
ASSERT(methodTable(vm)->getConstructData == &JSFunction::getConstructData);
ASSERT(methodTable(vm)->getCallData == &JSFunction::getCallData);
}
@@ -118,6 +119,7 @@
Base::finishCreation(vm);
ASSERT(inherits(vm, info()));
ASSERT(type() == JSFunctionType);
+ // JSCell::{getCallData,getConstructData} relies on the following conditions.
ASSERT(methodTable(vm)->getConstructData == &JSFunction::getConstructData);
ASSERT(methodTable(vm)->getCallData == &JSFunction::getCallData);
@@ -258,6 +260,7 @@
CallData JSFunction::getCallData(JSCell* cell)
{
+ // Keep this function OK for invocation from concurrent compilers.
CallData callData;
JSFunction* thisObject = jsCast<JSFunction*>(cell);
@@ -682,6 +685,7 @@
// ECMA 13.2.2 [[Construct]]
CallData JSFunction::getConstructData(JSCell* cell)
{
+ // Keep this function OK for invocation from concurrent compilers.
CallData constructData;
JSFunction* thisObject = jsCast<JSFunction*>(cell);
Modified: trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/NumberPrototype.cpp 2020-08-25 08:06:48 UTC (rev 266107)
@@ -104,7 +104,7 @@
static ALWAYS_INLINE EncodedJSValue throwVMToThisNumberError(JSGlobalObject* globalObject, ThrowScope& scope, JSValue thisValue)
{
- auto typeString = asString(jsTypeStringForValue(globalObject->vm(), globalObject, thisValue))->value(globalObject);
+ auto typeString = jsTypeStringForValue(globalObject, thisValue)->value(globalObject);
scope.assertNoException();
return throwVMTypeError(globalObject, scope, WTF::makeString("thisNumberValue called on incompatible ", typeString));
}
Modified: trunk/Source/_javascript_Core/runtime/Operations.cpp (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/Operations.cpp 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/Operations.cpp 2020-08-25 08:06:48 UTC (rev 266107)
@@ -75,7 +75,7 @@
RELEASE_AND_RETURN(scope, arithmeticBinaryOp(globalObject, p1, p2, doubleOp, bigIntOp, "Invalid mix of BigInt and other type in addition."_s));
}
-JSValue jsTypeStringForValue(VM& vm, JSGlobalObject* globalObject, JSValue v)
+JSString* jsTypeStringForValueWithConcurrency(VM& vm, JSGlobalObject* globalObject, JSValue v, Concurrency concurrency)
{
if (v.isUndefined())
return vm.smallStrings.undefinedString();
@@ -95,17 +95,24 @@
// as null when doing comparisons.
if (object->structure(vm)->masqueradesAsUndefined(globalObject))
return vm.smallStrings.undefinedString();
- if (object->isCallable(vm))
+ if (LIKELY(concurrency == Concurrency::MainThread)) {
+ if (object->isCallable(vm))
+ return vm.smallStrings.functionString();
+ return vm.smallStrings.objectString();
+ }
+
+ switch (object->isCallableWithConcurrency<Concurrency::ConcurrentThread>(vm)) {
+ case TriState::True:
return vm.smallStrings.functionString();
+ case TriState::False:
+ return vm.smallStrings.objectString();
+ case TriState::Indeterminate:
+ return nullptr;
+ }
}
return vm.smallStrings.objectString();
}
-JSValue jsTypeStringForValue(JSGlobalObject* globalObject, JSValue v)
-{
- return jsTypeStringForValue(globalObject->vm(), globalObject, v);
-}
-
bool jsTypeofIsObject(JSGlobalObject* globalObject, JSValue v)
{
VM& vm = globalObject->vm();
Modified: trunk/Source/_javascript_Core/runtime/Operations.h (266106 => 266107)
--- trunk/Source/_javascript_Core/runtime/Operations.h 2020-08-25 07:45:00 UTC (rev 266106)
+++ trunk/Source/_javascript_Core/runtime/Operations.h 2020-08-25 08:06:48 UTC (rev 266107)
@@ -31,24 +31,34 @@
#define InvalidPrototypeChain (std::numeric_limits<size_t>::max())
NEVER_INLINE JSValue jsAddSlowCase(JSGlobalObject*, JSValue, JSValue);
-JSValue jsTypeStringForValue(JSGlobalObject*, JSValue);
-JSValue jsTypeStringForValue(VM&, JSGlobalObject*, JSValue);
+JSString* jsTypeStringForValueWithConcurrency(VM&, JSGlobalObject*, JSValue, Concurrency);
bool jsTypeofIsObject(JSGlobalObject*, JSValue);
size_t normalizePrototypeChain(JSGlobalObject*, JSCell*, bool& sawPolyProto);
-ALWAYS_INLINE bool jsTypeofIsFunction(JSGlobalObject* globalObject, JSValue value)
+template<Concurrency concurrency>
+ALWAYS_INLINE TriState jsTypeofIsFunctionWithConcurrency(JSGlobalObject* globalObject, JSValue value)
{
VM& vm = globalObject->vm();
- if (value.isObject()) {
- JSObject* object = asObject(value);
- if (object->structure(vm)->masqueradesAsUndefined(globalObject))
- return false;
- if (object->isCallable(vm))
- return true;
- }
- return false;
+ if (!value.isObject())
+ return TriState::False;
+ JSObject* object = asObject(value);
+ if (object->structure(vm)->masqueradesAsUndefined(globalObject))
+ return TriState::False;
+ return object->isCallableWithConcurrency<concurrency>(vm);
}
+inline JSString* jsTypeStringForValue(JSGlobalObject* globalObject, JSValue value)
+{
+ return jsTypeStringForValueWithConcurrency(getVM(globalObject), globalObject, value, Concurrency::MainThread);
+}
+
+ALWAYS_INLINE bool jsTypeofIsFunction(JSGlobalObject* globalObject, JSValue value)
+{
+ auto result = jsTypeofIsFunctionWithConcurrency<Concurrency::MainThread>(globalObject, value);
+ ASSERT(result != TriState::Indeterminate);
+ return result == TriState::True;
+}
+
ALWAYS_INLINE JSString* jsString(JSGlobalObject* globalObject, const String& u1, JSString* s2)
{
VM& vm = getVM(globalObject);