We should be able to jsDynamicCast from JSType when possible
authorkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Feb 2018 02:08:41 +0000 (02:08 +0000)
committerkeith_miller@apple.com <keith_miller@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 15 Feb 2018 02:08:41 +0000 (02:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=182804

Reviewed by Filip Pizlo and Mark Lam.

This patch beefs up jsDynamicCast in some of the cases where we
can use the JSType to quickly determine if a cell is a subclass of
the desired type. Since all JSCells have a range of JSTypes they support,
if there is a range exclusive to a class and all subclasses we can use
that range to quickly determine if the cast should be successful.

Additionally, the JSValue versions of jsCast and jsDynamicCast now
call the JSCell version after checking the value is a cell.

Finally, the casting functions have been moved to a new header,
JSCast.h

* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CallVariant.h:
* bytecode/CodeBlock.h:
* bytecode/ExecutableToCodeBlockEdge.h:
* bytecode/TrackedReferences.h:
* bytecode/UnlinkedCodeBlock.h:
* bytecode/UnlinkedFunctionExecutable.h:
* dfg/DFGAbstractValue.h:
* dfg/DFGCommonData.h:
* dfg/DFGFrozenValue.h:
* dfg/DFGStructureAbstractValue.h:
* heap/CellContainerInlines.h:
* heap/ConservativeRoots.cpp:
* heap/GCLogging.cpp:
* heap/HeapInlines.h:
* heap/HeapSnapshotBuilder.cpp:
* heap/MarkedBlock.cpp:
* heap/MarkedBlockInlines.h:
* heap/SubspaceInlines.h:
* heap/WeakInlines.h:
* jit/JITOpcodes.cpp:
* jit/JITOpcodes32_64.cpp:
* llint/LLIntOffsetsExtractor.cpp:
* runtime/ArrayBufferNeuteringWatchpoint.h:
* runtime/BigIntPrototype.cpp:
* runtime/ClassInfo.h:
* runtime/CustomGetterSetter.h:
* runtime/FunctionRareData.h:
* runtime/GetterSetter.h:
* runtime/InferredType.h:
* runtime/InferredTypeTable.h:
* runtime/InferredValue.h:
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::finishCreation):
* runtime/JSAPIValueWrapper.h:
* runtime/JSArray.h:
(JSC::JSArray::finishCreation):
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::finishCreation):
* runtime/JSCast.h: Added.
(JSC::jsCast):
(JSC::JSCastingHelpers::jsDynamicCastGenericImpl):
(JSC::JSCastingHelpers::jsDynamicCastJSTypeImpl):
(JSC::JSCastingHelpers::JSDynamicCastTraits::cast):
(JSC::jsDynamicCast):
* runtime/JSCell.cpp:
* runtime/JSCell.h:
(JSC::jsCast): Deleted.
(JSC::jsDynamicCast): Deleted.
* runtime/JSCellInlines.h:
* runtime/JSFunction.cpp:
(JSC::JSFunction::finishCreation):
* runtime/JSJob.h:
* runtime/JSObject.h:
(JSC::JSObject::finishCreation):
* runtime/JSPromiseDeferred.h:
* runtime/JSPropertyNameEnumerator.h:
* runtime/NativeStdFunctionCell.h:
* runtime/ScopedArgumentsTable.h:
* runtime/SparseArrayValueMap.h:
* runtime/Structure.h:
* runtime/StructureChain.h:
* runtime/StructureRareData.h:
* tools/CellProfile.h:
* wasm/js/JSWebAssemblyCodeBlock.h:

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

56 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/bytecode/CallVariant.h
Source/JavaScriptCore/bytecode/CodeBlock.h
Source/JavaScriptCore/bytecode/ExecutableToCodeBlockEdge.h
Source/JavaScriptCore/bytecode/TrackedReferences.h
Source/JavaScriptCore/bytecode/UnlinkedCodeBlock.h
Source/JavaScriptCore/bytecode/UnlinkedFunctionExecutable.h
Source/JavaScriptCore/dfg/DFGAbstractValue.h
Source/JavaScriptCore/dfg/DFGCommonData.h
Source/JavaScriptCore/dfg/DFGFrozenValue.h
Source/JavaScriptCore/dfg/DFGStructureAbstractValue.h
Source/JavaScriptCore/heap/CellContainerInlines.h
Source/JavaScriptCore/heap/ConservativeRoots.cpp
Source/JavaScriptCore/heap/GCLogging.cpp
Source/JavaScriptCore/heap/HeapInlines.h
Source/JavaScriptCore/heap/HeapSnapshotBuilder.cpp
Source/JavaScriptCore/heap/MarkedBlock.cpp
Source/JavaScriptCore/heap/MarkedBlockInlines.h
Source/JavaScriptCore/heap/SubspaceInlines.h
Source/JavaScriptCore/heap/WeakInlines.h
Source/JavaScriptCore/jit/JITOpcodes.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
Source/JavaScriptCore/runtime/ArrayBufferNeuteringWatchpoint.h
Source/JavaScriptCore/runtime/BigIntPrototype.cpp
Source/JavaScriptCore/runtime/ClassInfo.h
Source/JavaScriptCore/runtime/CustomGetterSetter.h
Source/JavaScriptCore/runtime/FunctionRareData.h
Source/JavaScriptCore/runtime/GetterSetter.h
Source/JavaScriptCore/runtime/InferredType.h
Source/JavaScriptCore/runtime/InferredTypeTable.h
Source/JavaScriptCore/runtime/InferredValue.h
Source/JavaScriptCore/runtime/InternalFunction.cpp
Source/JavaScriptCore/runtime/JSAPIValueWrapper.h
Source/JavaScriptCore/runtime/JSArray.h
Source/JavaScriptCore/runtime/JSArrayBufferView.cpp
Source/JavaScriptCore/runtime/JSCast.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSCell.cpp
Source/JavaScriptCore/runtime/JSCell.h
Source/JavaScriptCore/runtime/JSCellInlines.h
Source/JavaScriptCore/runtime/JSFunction.cpp
Source/JavaScriptCore/runtime/JSJob.h
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/JSPromiseDeferred.h
Source/JavaScriptCore/runtime/JSPropertyNameEnumerator.h
Source/JavaScriptCore/runtime/JSType.h
Source/JavaScriptCore/runtime/NativeStdFunctionCell.h
Source/JavaScriptCore/runtime/ScopedArgumentsTable.h
Source/JavaScriptCore/runtime/SparseArrayValueMap.h
Source/JavaScriptCore/runtime/Structure.h
Source/JavaScriptCore/runtime/StructureChain.h
Source/JavaScriptCore/runtime/StructureRareData.h
Source/JavaScriptCore/tools/CellProfile.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyCodeBlock.h

index 067b86a..e558bae 100644 (file)
@@ -747,6 +747,7 @@ set(JavaScriptCore_FORWARDING_HEADERS
     runtime/JSCJSValueInlines.h
     runtime/JSCPoison.h
     runtime/JSCallee.h
+    runtime/JSCast.h
     runtime/JSCell.h
     runtime/JSCellInlines.h
     runtime/JSDataView.h
index 11763cc..a2f7d63 100644 (file)
@@ -1,3 +1,88 @@
+2018-02-14  Keith Miller  <keith_miller@apple.com>
+
+        We should be able to jsDynamicCast from JSType when possible
+        https://bugs.webkit.org/show_bug.cgi?id=182804
+
+        Reviewed by Filip Pizlo and Mark Lam.
+
+        This patch beefs up jsDynamicCast in some of the cases where we
+        can use the JSType to quickly determine if a cell is a subclass of
+        the desired type. Since all JSCells have a range of JSTypes they support,
+        if there is a range exclusive to a class and all subclasses we can use
+        that range to quickly determine if the cast should be successful.
+
+        Additionally, the JSValue versions of jsCast and jsDynamicCast now
+        call the JSCell version after checking the value is a cell.
+
+        Finally, the casting functions have been moved to a new header,
+        JSCast.h
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * bytecode/CallVariant.h:
+        * bytecode/CodeBlock.h:
+        * bytecode/ExecutableToCodeBlockEdge.h:
+        * bytecode/TrackedReferences.h:
+        * bytecode/UnlinkedCodeBlock.h:
+        * bytecode/UnlinkedFunctionExecutable.h:
+        * dfg/DFGAbstractValue.h:
+        * dfg/DFGCommonData.h:
+        * dfg/DFGFrozenValue.h:
+        * dfg/DFGStructureAbstractValue.h:
+        * heap/CellContainerInlines.h:
+        * heap/ConservativeRoots.cpp:
+        * heap/GCLogging.cpp:
+        * heap/HeapInlines.h:
+        * heap/HeapSnapshotBuilder.cpp:
+        * heap/MarkedBlock.cpp:
+        * heap/MarkedBlockInlines.h:
+        * heap/SubspaceInlines.h:
+        * heap/WeakInlines.h:
+        * jit/JITOpcodes.cpp:
+        * jit/JITOpcodes32_64.cpp:
+        * llint/LLIntOffsetsExtractor.cpp:
+        * runtime/ArrayBufferNeuteringWatchpoint.h:
+        * runtime/BigIntPrototype.cpp:
+        * runtime/ClassInfo.h:
+        * runtime/CustomGetterSetter.h:
+        * runtime/FunctionRareData.h:
+        * runtime/GetterSetter.h:
+        * runtime/InferredType.h:
+        * runtime/InferredTypeTable.h:
+        * runtime/InferredValue.h:
+        * runtime/InternalFunction.cpp:
+        (JSC::InternalFunction::finishCreation):
+        * runtime/JSAPIValueWrapper.h:
+        * runtime/JSArray.h:
+        (JSC::JSArray::finishCreation):
+        * runtime/JSArrayBufferView.cpp:
+        (JSC::JSArrayBufferView::finishCreation):
+        * runtime/JSCast.h: Added.
+        (JSC::jsCast):
+        (JSC::JSCastingHelpers::jsDynamicCastGenericImpl):
+        (JSC::JSCastingHelpers::jsDynamicCastJSTypeImpl):
+        (JSC::JSCastingHelpers::JSDynamicCastTraits::cast):
+        (JSC::jsDynamicCast):
+        * runtime/JSCell.cpp:
+        * runtime/JSCell.h:
+        (JSC::jsCast): Deleted.
+        (JSC::jsDynamicCast): Deleted.
+        * runtime/JSCellInlines.h:
+        * runtime/JSFunction.cpp:
+        (JSC::JSFunction::finishCreation):
+        * runtime/JSJob.h:
+        * runtime/JSObject.h:
+        (JSC::JSObject::finishCreation):
+        * runtime/JSPromiseDeferred.h:
+        * runtime/JSPropertyNameEnumerator.h:
+        * runtime/NativeStdFunctionCell.h:
+        * runtime/ScopedArgumentsTable.h:
+        * runtime/SparseArrayValueMap.h:
+        * runtime/Structure.h:
+        * runtime/StructureChain.h:
+        * runtime/StructureRareData.h:
+        * tools/CellProfile.h:
+        * wasm/js/JSWebAssemblyCodeBlock.h:
+
 2018-02-14  Michael Saboff  <msaboff@apple.com>
 
         Crash: triggerOMGTierUpThunkGenerator() doesn't align the stack pointer before calling C++ code
index cfa7e07..7faf77f 100644 (file)
                53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
                539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; };
                53B4BD121F68B32500D2BEA3 /* WasmOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 533B15DE1DC7F463004D500A /* WasmOps.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               53B601EC2034B8C5006BE667 /* JSCast.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B601EB2034B8C5006BE667 /* JSCast.h */; settings = {ATTRIBUTES = (Private, ); }; };
                53C6FEEF1E8ADFA900B18425 /* WasmOpcodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 53C6FEEE1E8ADFA900B18425 /* WasmOpcodeOrigin.h */; };
                53CA730A1EA533D80076049D /* WasmBBQPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CA73081EA533D80076049D /* WasmBBQPlan.h */; };
                53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */; };
                53B0BE331E561AC900A8FC29 /* GetterSetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GetterSetterAccessCase.cpp; sourceTree = "<group>"; };
                53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyableAccessCase.cpp; sourceTree = "<group>"; };
                53B0BE371E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicGetterAccessCase.cpp; sourceTree = "<group>"; };
+               53B601EB2034B8C5006BE667 /* JSCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSCast.h; sourceTree = "<group>"; };
                53C6FEEE1E8ADFA900B18425 /* WasmOpcodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOpcodeOrigin.h; sourceTree = "<group>"; };
                53C6FEF01E8AFE0C00B18425 /* WasmOpcodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOpcodeOrigin.cpp; sourceTree = "<group>"; };
                53CA73071EA533D80076049D /* WasmBBQPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBBQPlan.cpp; sourceTree = "<group>"; };
                                86FA9E90142BBB2E001773B7 /* JSBoundFunction.h */,
                                657CF45619BF6662004ACBF2 /* JSCallee.cpp */,
                                657CF45719BF6662004ACBF2 /* JSCallee.h */,
+                               53B601EB2034B8C5006BE667 /* JSCast.h */,
                                BC7F8FBA0E19D1EF008632C0 /* JSCell.cpp */,
                                BC1167D80E19BCC9008066DD /* JSCell.h */,
                                0F97496F1687ADE200A4FF6A /* JSCellInlines.h */,
                                BC18C41B0E16F5CD00B34460 /* JSCallbackObject.h in Headers */,
                                BC18C41C0E16F5CD00B34460 /* JSCallbackObjectFunctions.h in Headers */,
                                657CF45919BF6662004ACBF2 /* JSCallee.h in Headers */,
+                               53B601EC2034B8C5006BE667 /* JSCast.h in Headers */,
                                535C24691F7A1624006EC40E /* JSCBuiltins.cpp in Headers */,
                                A7D801A91880D6A80026C39B /* JSCBuiltins.h in Headers */,
                                BC1167DA0E19BCC9008066DD /* JSCell.h in Headers */,
index 94e72bb..61c69e4 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "FunctionExecutable.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSFunction.h"
 #include "NativeExecutable.h"
 
index dcd9d22..47d9048 100644 (file)
@@ -50,7 +50,7 @@
 #include "JITCode.h"
 #include "JITMathICForwards.h"
 #include "JSCPoison.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSGlobalObject.h"
 #include "JumpTable.h"
 #include "LLIntCallLinkInfo.h"
index a2b9b50..c2eeac2 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "ConcurrentJSLock.h"
 #include "IsoSubspace.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "VM.h"
 
 namespace JSC {
index a102167..ec34362 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "JSCJSValue.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include <wtf/HashSet.h>
 #include <wtf/PrintStream.h>
 
index 54d5a4e..6acb500 100644 (file)
@@ -31,7 +31,7 @@
 #include "ExpressionRangeInfo.h"
 #include "HandlerInfo.h"
 #include "Identifier.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "LockDuringMarking.h"
 #include "ParserModes.h"
 #include "RegExp.h"
index ed5e9c6..de0bfec 100644 (file)
@@ -31,7 +31,7 @@
 #include "ExpressionRangeInfo.h"
 #include "Identifier.h"
 #include "Intrinsic.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "ParserModes.h"
 #include "RegExp.h"
 #include "SourceCode.h"
index 03a5056..f45c13f 100644 (file)
@@ -34,7 +34,7 @@
 #include "DFGStructureAbstractValue.h"
 #include "DFGStructureClobberState.h"
 #include "InferredType.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "ResultType.h"
 #include "SpeculatedType.h"
 #include "DumpContext.h"
index 2408744..15e3853 100644 (file)
@@ -33,7 +33,7 @@
 #include "DFGJumpReplacement.h"
 #include "DFGOSREntry.h"
 #include "InlineCallFrameSet.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "ProfilerCompilation.h"
 #include <wtf/Bag.h>
 #include <wtf/Noncopyable.h>
index 7cce251..21bc415 100644 (file)
@@ -28,8 +28,8 @@
 #if ENABLE(DFG_JIT)
 
 #include "DFGValueStrength.h"
-#include "JSCell.h"
 #include "JSCJSValue.h"
+#include "JSCast.h"
 #include "Structure.h"
 
 namespace JSC { namespace DFG {
index 5c6adc7..e3bfbc4 100644 (file)
@@ -30,7 +30,7 @@
 #include "DFGRegisteredStructureSet.h"
 #include "DFGTransition.h"
 #include "DumpContext.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "SpeculatedType.h"
 #include "StructureSet.h"
 
index c23d488..6e66572 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "CellContainer.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "LargeAllocation.h"
 #include "MarkedBlock.h"
 #include "VM.h"
index 1e7e05f..30a26dd 100644 (file)
@@ -31,7 +31,7 @@
 #include "HeapInlines.h"
 #include "HeapUtil.h"
 #include "JITStubRoutineSet.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSObject.h"
 #include "JSCInlines.h"
 #include "MarkedBlockInlines.h"
index 688de60..bea4c8c 100644 (file)
@@ -29,7 +29,7 @@
 #include "ClassInfo.h"
 #include "Heap.h"
 #include "HeapIterationScope.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSCellInlines.h"
 #include <wtf/PrintStream.h>
 
index 04586bf..e561c96 100644 (file)
@@ -30,7 +30,7 @@
 #include "HeapCellInlines.h"
 #include "IndexingHeader.h"
 #include "JSCallee.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "Structure.h"
 #include <type_traits>
 #include <wtf/Assertions.h>
index 2345b2d..65f633f 100644 (file)
@@ -31,7 +31,7 @@
 #include "HeapProfiler.h"
 #include "HeapSnapshot.h"
 #include "JSCInlines.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "PreventCollectionScope.h"
 #include "VM.h"
 #include <wtf/text/StringBuilder.h>
index 6c10322..d9424a8 100644 (file)
@@ -29,7 +29,7 @@
 #include "AlignedMemoryAllocator.h"
 #include "BlockDirectoryInlines.h"
 #include "FreeListInlines.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSDestructibleObject.h"
 #include "JSCInlines.h"
 #include "MarkedBlockInlines.h"
index f44af67..e330da2 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "BlockDirectory.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "MarkedBlock.h"
 #include "MarkedSpace.h"
 #include "Operations.h"
index e7ed218..e83b382 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "BlockDirectoryInlines.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "MarkedBlock.h"
 #include "MarkedSpace.h"
 #include "Subspace.h"
index d53cc54..0f7d560 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "WeakSetInlines.h"
 #include <wtf/Assertions.h>
 
index 9fe67ee..a6edf2f 100644 (file)
@@ -35,7 +35,7 @@
 #include "InterpreterInlines.h"
 #include "JITInlines.h"
 #include "JSArray.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSFunction.h"
 #include "JSPropertyNameEnumerator.h"
 #include "LinkBuffer.h"
index 0b05204..1d363f3 100644 (file)
@@ -35,7 +35,7 @@
 #include "Exception.h"
 #include "JITInlines.h"
 #include "JSArray.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSFunction.h"
 #include "JSPropertyNameEnumerator.h"
 #include "LinkBuffer.h"
index ae7559d..56aced7 100644 (file)
@@ -38,7 +38,7 @@
 #include "Interpreter.h"
 #include "JSArray.h"
 #include "JSArrayBufferView.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSLexicalEnvironment.h"
index 6435cc8..4498158 100644 (file)
@@ -31,7 +31,7 @@
 #include "JSBigInt.h"
 #include "JSCBuiltins.h"
 #include "JSCInlines.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSFunction.h"
 #include "JSGlobalObject.h"
 #include "JSString.h"
index 7541d18..95084db 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "CallFrame.h"
 #include "ConstructData.h"
-#include "JSCell.h"
+#include "JSCast.h"
 
 namespace WTF {
 class PrintStream;
index d3b62fe..bc09d36 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "JSCPoison.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "PropertySlot.h"
 #include "PutPropertySlot.h"
 #include "Structure.h"
index 1fc5db1..f11ba2e 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "InternalFunctionAllocationProfile.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "ObjectAllocationProfile.h"
 #include "Watchpoint.h"
 
index 751ab19..7f51b35 100644 (file)
@@ -22,7 +22,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 
 #include "CallFrame.h"
 #include "JSGlobalObject.h"
index 56fb652..e73f118 100644 (file)
@@ -28,7 +28,7 @@
 #include "ConcurrentJSLock.h"
 #include "InferredStructure.h"
 #include "IsoCellSet.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "PropertyName.h"
 #include "PutByIdFlags.h"
 #include "Watchpoint.h"
index 6b4515f..e529eb4 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "Identifier.h"
 #include "InferredType.h"
-#include "JSCell.h"
+#include "JSCast.h"
 
 namespace JSC {
 
index 9c93181..4d0429c 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "IsoSubspace.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "VM.h"
 #include "Watchpoint.h"
 #include "WriteBarrier.h"
index 3e84cc7..73b5313 100644 (file)
@@ -48,7 +48,7 @@ InternalFunction::InternalFunction(VM& vm, Structure* structure, NativeFunction
 void InternalFunction::finishCreation(VM& vm, const String& name, NameVisibility nameVisibility)
 {
     Base::finishCreation(vm);
-    ASSERT(inherits(vm, info()));
+    ASSERT(jsDynamicCast<InternalFunction*>(vm, this));
     ASSERT(methodTable(vm)->getCallData == InternalFunction::info()->methodTable.getCallData);
     ASSERT(methodTable(vm)->getConstructData == InternalFunction::info()->methodTable.getConstructData);
     ASSERT(type() == InternalFunctionType);
index 8c7c845..345459f 100644 (file)
@@ -22,9 +22,9 @@
 
 #pragma once
 
-#include "JSCJSValue.h"
-#include "JSCell.h"
 #include "CallFrame.h"
+#include "JSCJSValue.h"
+#include "JSCast.h"
 #include "Structure.h"
 
 namespace JSC {
index 3244d77..8772aa2 100644 (file)
@@ -173,6 +173,7 @@ protected:
     void finishCreation(VM& vm)
     {
         Base::finishCreation(vm);
+        ASSERT(jsDynamicCast<JSArray*>(vm, this));
         ASSERT_WITH_MESSAGE(type() == ArrayType || type() == DerivedArrayType, "Instance inheriting JSArray should have either ArrayType or DerivedArrayType");
     }
 
index ef7a187..ec2f633 100644 (file)
@@ -138,6 +138,7 @@ JSArrayBufferView::JSArrayBufferView(VM& vm, ConstructionContext& context)
 void JSArrayBufferView::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
+    ASSERT(jsDynamicCast<JSArrayBufferView*>(vm, this));
     switch (m_mode) {
     case FastTypedArray:
         return;
diff --git a/Source/JavaScriptCore/runtime/JSCast.h b/Source/JavaScriptCore/runtime/JSCast.h
new file mode 100644 (file)
index 0000000..4fe2b9f
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018 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. ``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
+ * 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 "JSCell.h"
+
+namespace JSC {
+
+template<typename To, typename From>
+inline To jsCast(From* from)
+{
+    static_assert(std::is_base_of<JSCell, typename std::remove_pointer<To>::type>::value && std::is_base_of<JSCell, typename std::remove_pointer<From>::type>::value, "JS casting expects that the types you are casting to/from are subclasses of JSCell");
+    ASSERT_WITH_SECURITY_IMPLICATION(!from || from->JSCell::inherits(*from->JSCell::vm(), std::remove_pointer<To>::type::info()));
+    return static_cast<To>(from);
+}
+
+template<typename To>
+inline To jsCast(JSValue from)
+{
+    static_assert(std::is_base_of<JSCell, typename std::remove_pointer<To>::type>::value, "JS casting expects that the types you are casting to is a subclass of JSCell");
+    ASSERT_WITH_SECURITY_IMPLICATION(from.isCell() && from.asCell()->JSCell::inherits(*from.asCell()->vm(), std::remove_pointer<To>::type::info()));
+    return static_cast<To>(from.asCell());
+}
+
+// Specific type overloads.
+#define FOR_EACH_JS_DYNAMIC_CAST_JS_TYPE_OVERLOAD(macro) \
+    macro(JSObject, JSType::ObjectType, JSType::LastJSCObjectType) \
+    macro(JSFunction, JSType::JSFunctionType, JSType::JSFunctionType) \
+    macro(InternalFunction, JSType::InternalFunctionType, JSType::InternalFunctionType) \
+    macro(JSArray, JSType::ArrayType, JSType::DerivedArrayType) \
+    macro(JSArrayBufferView, FirstTypedArrayType, LastTypedArrayType) \
+
+
+// Forward declare the classes because they may not already exist.
+#define FORWARD_DECLARE_OVERLOAD_CLASS(className, jsType, op) class className;
+FOR_EACH_JS_DYNAMIC_CAST_JS_TYPE_OVERLOAD(FORWARD_DECLARE_OVERLOAD_CLASS)
+#undef FORWARD_DECLARE_OVERLOAD_CLASS
+
+namespace JSCastingHelpers {
+
+template<typename To, typename From>
+inline To jsDynamicCastGenericImpl(VM& vm, From* from)
+{
+    static_assert(!std::is_same<JSObject*, To*>::value, "This ensures our overloads work");
+    static_assert(std::is_base_of<JSCell, typename std::remove_pointer<To>::type>::value && std::is_base_of<JSCell, typename std::remove_pointer<From>::type>::value, "JS casting expects that the types you are casting to/from are subclasses of JSCell");
+    if (LIKELY(from->JSCell::inherits(vm, std::remove_pointer<To>::type::info())))
+        return static_cast<To>(from);
+    return nullptr;
+}
+
+template<typename To, typename From>
+inline To jsDynamicCastJSTypeImpl(VM& vm, From* from, JSType firstType, JSType lastType)
+{
+    bool canCast = firstType <= from->type() && from->type() <= lastType;
+    ASSERT_UNUSED(vm, canCast == jsDynamicCastGenericImpl<To>(vm, from));
+    if (LIKELY(canCast))
+        return static_cast<To>(from);
+    return nullptr;
+}
+
+// C++ has bad syntax so we need to use this struct because C++ doesn't have a
+// way to say that we are overloading just the first type in a template list...
+template<typename to>
+struct JSDynamicCastTraits {
+    template<typename To, typename From>
+    static inline To cast(VM& vm, From* from) { return jsDynamicCastGenericImpl<To>(vm, from); }
+};
+
+#define DEFINE_TRAITS_FOR_JS_TYPE_OVERLOAD(className, firstJSType, lastJSType) \
+    template<> \
+    struct JSDynamicCastTraits<className*> { \
+        template<typename To, typename From> \
+        static inline To cast(VM& vm, From* from) { return jsDynamicCastJSTypeImpl<To>(vm, from, firstJSType, lastJSType); } \
+    }; \
+
+FOR_EACH_JS_DYNAMIC_CAST_JS_TYPE_OVERLOAD(DEFINE_TRAITS_FOR_JS_TYPE_OVERLOAD)
+
+#undef DEFINE_TRAITS_FOR_JS_TYPE_OVERLOAD
+
+} // namespace JSCastingHelpers
+
+template<typename To, typename From>
+To jsDynamicCast(VM& vm, From* from)
+{
+    typedef JSCastingHelpers::JSDynamicCastTraits<typename std::remove_cv<typename std::remove_pointer<To>::type>::type> Dispatcher;
+    return Dispatcher::template cast<To>(vm, from);
+}
+
+template<typename To>
+To jsDynamicCast(VM& vm, JSValue from)
+{
+    if (UNLIKELY(!from.isCell()))
+        return nullptr;
+    return jsDynamicCast<To>(vm, from.asCell());
+}
+
+}
index 23c6d41..3035cbf 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "ArrayBufferView.h"
 #include "JSCInlines.h"
+#include "JSCast.h"
 #include "JSFunction.h"
 #include "JSString.h"
 #include "JSObject.h"
index 64c84ad..cadcf77 100644 (file)
@@ -296,36 +296,6 @@ private:
     JS_EXPORT_PRIVATE void unlockSlow();
 };
 
-template<typename To, typename From>
-inline To jsCast(From* from)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(!from || from->JSCell::inherits(*from->JSCell::vm(), std::remove_pointer<To>::type::info()));
-    return static_cast<To>(from);
-}
-    
-template<typename To>
-inline To jsCast(JSValue from)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(from.isCell() && from.asCell()->JSCell::inherits(*from.asCell()->vm(), std::remove_pointer<To>::type::info()));
-    return static_cast<To>(from.asCell());
-}
-
-template<typename To, typename From>
-inline To jsDynamicCast(VM& vm, From* from)
-{
-    if (LIKELY(from->JSCell::inherits(vm, std::remove_pointer<To>::type::info())))
-        return static_cast<To>(from);
-    return nullptr;
-}
-
-template<typename To>
-inline To jsDynamicCast(VM& vm, JSValue from)
-{
-    if (LIKELY(from.isCell() && from.asCell()->inherits(vm, std::remove_pointer<To>::type::info())))
-        return static_cast<To>(from.asCell());
-    return nullptr;
-}
-
 // FIXME: Refer to Subspace by reference.
 // https://bugs.webkit.org/show_bug.cgi?id=166988
 template<typename Type>
index 836d851..908d19a 100644 (file)
@@ -29,7 +29,7 @@
 #include "CallFrame.h"
 #include "DeferGC.h"
 #include "Handle.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSDestructibleObject.h"
 #include "JSObject.h"
 #include "JSString.h"
index 010f3ae..c58cec8 100644 (file)
@@ -106,7 +106,7 @@ JSFunction::JSFunction(VM& vm, JSGlobalObject* globalObject, Structure* structur
 void JSFunction::finishCreation(VM& vm)
 {
     Base::finishCreation(vm);
-    ASSERT(inherits(vm, info()));
+    ASSERT(jsDynamicCast<JSFunction*>(vm, this));
     if (isBuiltinFunction() && jsExecutable()->name().isPrivateName()) {
         // This is anonymous builtin function.
         rareData(vm)->setHasReifiedName();
index a73715c..0a9e636 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "Structure.h"
 
 namespace JSC {
index b158ee1..80f64e9 100644 (file)
@@ -33,7 +33,7 @@
 #include "DOMAttributeGetterSetter.h"
 #include "Heap.h"
 #include "IndexingHeaderInlines.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "ObjectInitializationScope.h"
 #include "PropertySlot.h"
 #include "PropertyStorage.h"
@@ -877,7 +877,7 @@ protected:
     void finishCreation(VM& vm)
     {
         Base::finishCreation(vm);
-        ASSERT(inherits(vm, info()));
+        ASSERT(jsDynamicCast<JSObject*>(vm, this));
         ASSERT(structure()->hasPolyProto() || getPrototypeDirect(vm).isNull() || Heap::heap(this) == Heap::heap(getPrototypeDirect(vm)));
         ASSERT(structure()->isObject());
         ASSERT(classInfo(vm));
index 0922a94..4187a7c 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "Structure.h"
 
 namespace JSC {
index b8b37a3..570c883 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "Operations.h"
 #include "PropertyNameArray.h"
 #include "Structure.h"
index bc59787..c882218 100644 (file)
@@ -66,9 +66,12 @@ enum JSType : uint8_t {
     ScopedArgumentsType,
     ClonedArgumentsType,
 
+    // Start JSArray types.
     ArrayType,
     DerivedArrayType,
+    // End JSArray types.
 
+    // Start JSArrayBufferView types.
     Int8ArrayType,
     Uint8ArrayType,
     Uint8ClampedArrayType,
@@ -79,6 +82,7 @@ enum JSType : uint8_t {
     Float32ArrayType,
     Float64ArrayType,
     DataViewType,
+    // End JSArrayBufferView types.
 
     GetterSetterType,
 
index 0d3a10e..f327b2d 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSNativeStdFunction.h"
 
 namespace JSC {
index 7c7207b..40e7c7e 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "ScopeOffset.h"
 #include <wtf/Assertions.h>
 #include <wtf/CagedUniquePtr.h>
index 1c7dcb2..aa1ac22 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSTypeInfo.h"
 #include "PropertyDescriptor.h"
 #include "PutDirectIndexMode.h"
index 9d454f5..116ff3a 100644 (file)
@@ -30,7 +30,7 @@
 #include "IndexingType.h"
 #include "InferredTypeTable.h"
 #include "JSCJSValue.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSType.h"
 #include "PropertyName.h"
 #include "PropertyNameArray.h"
index 93ae33b..47f3a5f 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSObject.h"
 #include "Structure.h"
 #include <wtf/StdLibExtras.h>
index 1774e3d..11c181d 100644 (file)
@@ -26,7 +26,7 @@
 #pragma once
 
 #include "ClassInfo.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "JSTypeInfo.h"
 #include "PropertyOffset.h"
 #include "PropertySlot.h"
index 741836b..f546b60 100644 (file)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "JSCell.h"
+#include "JSCast.h"
 #include "Structure.h"
 #include <wtf/MonotonicTime.h>
 #include <wtf/StackTrace.h>
index e76a617..77bfac1 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "CallLinkInfo.h"
 #include "JSCPoison.h"
-#include "JSCell.h"
+#include "JSCast.h"
 #include "PromiseDeferredTimer.h"
 #include "Structure.h"
 #include "UnconditionalFinalizer.h"