Changeset 283852 in webkit
- Timestamp:
- Oct 8, 2021 4:32:45 PM (9 months ago)
- Location:
- trunk
- Files:
-
- 40 added
- 83 edited
- 8 copied
-
JSTests/ChangeLog (modified) (1 diff)
-
JSTests/wasm.yaml (modified) (1 diff)
-
JSTests/wasm/Builder.js (modified) (9 diffs)
-
JSTests/wasm/Builder_WebAssemblyBinary.js (modified) (3 diffs)
-
JSTests/wasm/assert.js (modified) (1 diff)
-
JSTests/wasm/self-test/test_BuilderJSON.js (modified) (1 diff)
-
JSTests/wasm/stress/catch-with-delegate.js (added)
-
JSTests/wasm/stress/create-tag-from.js (added)
-
JSTests/wasm/stress/exception-cross-instance-2.js (added)
-
JSTests/wasm/stress/exception-cross-instance-3.js (added)
-
JSTests/wasm/stress/exception-cross-instance.js (added)
-
JSTests/wasm/stress/exception-liveness-tier-up.js (added)
-
JSTests/wasm/stress/exception-multiple-instances.js (added)
-
JSTests/wasm/stress/exception-simple-delegate.js (added)
-
JSTests/wasm/stress/exception-simple-throw-catch.js (added)
-
JSTests/wasm/stress/exception-thrown-from-js-to-wasm-catchall-rethrow.js (added)
-
JSTests/wasm/stress/exception-thrown-from-js-to-wasm-catchall.js (added)
-
JSTests/wasm/stress/exception-thrown-from-js-to-wasm.js (added)
-
JSTests/wasm/stress/exception-thrown-out-of-wasm.js (added)
-
JSTests/wasm/stress/exception-thrown-over-wasm.js (added)
-
JSTests/wasm/stress/exception-trap.js (added)
-
JSTests/wasm/stress/rethrow-from-catch-to-catch.js (added)
-
JSTests/wasm/stress/rethrow-to-catch.js (added)
-
JSTests/wasm/stress/rethrow-to-delegate-to-catch.js (added)
-
JSTests/wasm/stress/simple-export-exception.js (added)
-
JSTests/wasm/v8 (added)
-
JSTests/wasm/v8/LICENSE (added)
-
JSTests/wasm/v8/exceptions-api.js (added)
-
JSTests/wasm/v8/exceptions-export.js (added)
-
JSTests/wasm/v8/exceptions-externref.js (added)
-
JSTests/wasm/v8/exceptions-import.js (added)
-
JSTests/wasm/v8/exceptions-rethrow.js (added)
-
JSTests/wasm/v8/exceptions-shared.js (added)
-
JSTests/wasm/v8/exceptions-type-reflection.js (added)
-
JSTests/wasm/v8/exceptions-utils.js (added)
-
JSTests/wasm/v8/exceptions.js (added)
-
JSTests/wasm/v8/mjsunit.js (added)
-
JSTests/wasm/v8/wasm-module-builder.js (added)
-
JSTests/wasm/wasm.json (modified) (2 diffs)
-
Source/JavaScriptCore/CMakeLists.txt (modified) (6 diffs)
-
Source/JavaScriptCore/ChangeLog (modified) (1 diff)
-
Source/JavaScriptCore/DerivedSources-input.xcfilelist (modified) (2 diffs)
-
Source/JavaScriptCore/DerivedSources-output.xcfilelist (modified) (2 diffs)
-
Source/JavaScriptCore/DerivedSources.make (modified) (2 diffs)
-
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (modified) (19 diffs)
-
Source/JavaScriptCore/Sources.txt (modified) (5 diffs)
-
Source/JavaScriptCore/bytecode/BytecodeList.rb (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/HandlerInfo.h (modified) (1 diff)
-
Source/JavaScriptCore/bytecode/Instruction.h (modified) (1 diff)
-
Source/JavaScriptCore/interpreter/CallFrame.cpp (modified) (1 diff)
-
Source/JavaScriptCore/interpreter/CallFrame.h (modified) (4 diffs)
-
Source/JavaScriptCore/interpreter/Interpreter.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/interpreter/Interpreter.h (modified) (4 diffs)
-
Source/JavaScriptCore/interpreter/StackVisitor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/AssemblyHelpers.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/jit/AssemblyHelpers.h (modified) (1 diff)
-
Source/JavaScriptCore/jit/JITExceptions.cpp (modified) (1 diff)
-
Source/JavaScriptCore/jit/JSInterfaceJIT.h (modified) (2 diffs)
-
Source/JavaScriptCore/llint/LLIntData.h (modified) (1 diff)
-
Source/JavaScriptCore/llint/LLIntExceptions.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/llint/LLIntExceptions.h (modified) (2 diffs)
-
Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp (modified) (1 diff)
-
Source/JavaScriptCore/llint/WebAssembly.asm (modified) (11 diffs)
-
Source/JavaScriptCore/runtime/ErrorInstance.cpp (modified) (1 diff)
-
Source/JavaScriptCore/runtime/ErrorInstance.h (modified) (2 diffs)
-
Source/JavaScriptCore/runtime/JSGlobalObject.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/runtime/JSGlobalObject.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/OptionsList.h (modified) (1 diff)
-
Source/JavaScriptCore/runtime/VM.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/runtime/VM.h (modified) (7 diffs)
-
Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (modified) (127 diffs)
-
Source/JavaScriptCore/wasm/WasmB3IRGenerator.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmBBQPlan.cpp (modified) (7 diffs)
-
Source/JavaScriptCore/wasm/WasmBBQPlan.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmCallee.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmCallee.h (modified) (9 diffs)
-
Source/JavaScriptCore/wasm/WasmCallingConvention.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmFormat.h (modified) (9 diffs)
-
Source/JavaScriptCore/wasm/WasmFunctionCodeBlock.h (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmFunctionParser.h (modified) (9 diffs)
-
Source/JavaScriptCore/wasm/WasmHandlerInfo.cpp (added)
-
Source/JavaScriptCore/wasm/WasmHandlerInfo.h (added)
-
Source/JavaScriptCore/wasm/WasmInstance.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/WasmInstance.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp (modified) (23 diffs)
-
Source/JavaScriptCore/wasm/WasmLLIntGenerator.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmLimits.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmModuleInformation.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmModuleInformation.h (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmOMGPlan.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmOSREntryData.h (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/WasmOperations.cpp (modified) (11 diffs)
-
Source/JavaScriptCore/wasm/WasmOperations.h (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmSectionParser.cpp (modified) (4 diffs)
-
Source/JavaScriptCore/wasm/WasmSections.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmSignature.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmSlowPaths.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmSlowPaths.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmStreamingParser.cpp (modified) (1 diff)
-
Source/JavaScriptCore/wasm/WasmTag.cpp (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmTag.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.h) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmThunks.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/WasmThunks.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/generateWasmB3IRGeneratorInlinesHeader.py (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/generateWasmOpsHeader.py (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyException.cpp (added)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyException.h (added)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h (modified) (1 diff)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyTag.cpp (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.cpp) (2 diffs)
-
Source/JavaScriptCore/wasm/js/JSWebAssemblyTag.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WasmToJS.cpp (modified) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyExceptionConstructor.cpp (added)
-
Source/JavaScriptCore/wasm/js/WebAssemblyExceptionConstructor.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyExceptionPrototype.cpp (added)
-
Source/JavaScriptCore/wasm/js/WebAssemblyExceptionPrototype.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (modified) (3 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp (modified) (6 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyTagConstructor.cpp (added)
-
Source/JavaScriptCore/wasm/js/WebAssemblyTagConstructor.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h) (2 diffs)
-
Source/JavaScriptCore/wasm/js/WebAssemblyTagPrototype.cpp (added)
-
Source/JavaScriptCore/wasm/js/WebAssemblyTagPrototype.h (copied) (copied from trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h) (2 diffs)
-
Source/JavaScriptCore/wasm/wasm.json (modified) (2 diffs)
-
Tools/ChangeLog (modified) (1 diff)
-
Tools/Scripts/run-jsc-stress-tests (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r283841 r283852 1 2021-10-08 Tadeu Zagallo <tzagallo@apple.com> 2 3 Implement the WebAssembly exception handling proposal 4 https://bugs.webkit.org/show_bug.cgi?id=229681 5 <rdar://81603387> 6 7 Reviewed by Keith Miller. 8 9 Add new tests for the exception handling and import a set of tests used by V8 into wasm/v8. 10 11 * wasm.yaml: 12 * wasm/Builder.js: 13 (const._importExceptionContinuation.type.Import.field): 14 (export.default.Builder.prototype._registerSectionBuilders.const.section.in.WASM.description.section.switch.section.case.string_appeared_here.this.section): 15 (const._exportFunctionContinuation.type.Export.field): Deleted. 16 (const._exportFunctionContinuation): Deleted. 17 * wasm/Builder_WebAssemblyBinary.js: 18 (const.emitters.Import): 19 (const.emitters.Export): 20 (const.emitters.Exception): 21 * wasm/assert.js: 22 * wasm/self-test/test_BuilderJSON.js: 23 (ImportBeforeTypeSections): Deleted. 24 * wasm/stress/catch-with-delegate.js: Added. 25 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.callback): 26 (assert.throws): 27 * wasm/stress/create-tag-from.js: Added. 28 * wasm/stress/exception-cross-instance-2.js: Added. 29 (test): 30 (assert.eq): 31 * wasm/stress/exception-cross-instance-3.js: Added. 32 (test): 33 (assert.eq): 34 * wasm/stress/exception-cross-instance.js: Added. 35 (test): 36 (assert.throws): 37 (instB.new.WebAssembly.Instance): 38 * wasm/stress/exception-liveness-tier-up.js: Added. 39 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.catch): 40 (assert.eq.): 41 (assert.eq): 42 * wasm/stress/exception-multiple-instances.js: Added. 43 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.const.module.new.WebAssembly.Module): 44 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.inst.exports.throw): 45 * wasm/stress/exception-simple-delegate.js: Added. 46 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.testSimpleThrowDelegate): 47 (testThrowDelegateSkip): 48 (testDelegateCaller): 49 (testSimpleDelegateMerge): 50 * wasm/stress/exception-simple-throw-catch.js: Added. 51 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.testSimpleTryCatch): 52 (testSimpleTryCatchAll): 53 (testCallTryCatch): 54 (testCallTryCatchAll): 55 (testSimpleTryCatchValue): 56 (testCallTryCatchValue): 57 (testStackTryCatch): 58 (testLiveAfterTryCatch): 59 (testLiveAfterTryCatchAll): 60 (testUnifyTryCatchCatch): 61 (testUnifyTryCatchCatchAll): 62 (testUnifyTryNoThrow): 63 (testUnifyTryNoCatch): 64 (testNestedCatch): 65 * wasm/stress/exception-thrown-from-js-to-wasm-catchall-rethrow.js: Added. 66 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.callback): 67 * wasm/stress/exception-thrown-from-js-to-wasm-catchall.js: Added. 68 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.callback): 69 * wasm/stress/exception-thrown-from-js-to-wasm.js: Added. 70 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.callback): 71 * wasm/stress/exception-thrown-out-of-wasm.js: Added. 72 * wasm/stress/exception-thrown-over-wasm.js: Added. 73 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.callback): 74 * wasm/stress/exception-trap.js: Added. 75 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.testCannotCatchUnreachable): 76 (testCannotCatchOOB): 77 (testWasmAPIThrow): 78 (testJSCatchAndRethrow): 79 * wasm/stress/rethrow-from-catch-to-catch.js: Added. 80 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.callback): 81 * wasm/stress/rethrow-to-catch.js: Added. 82 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here.callback): 83 (assert.throws.callback): 84 (assert.throws): 85 * wasm/stress/rethrow-to-delegate-to-catch.js: Added. 86 (import.Builder.from.string_appeared_here.import.as.assert.from.string_appeared_here): 87 (assert.eq.exn.getArg): 88 (assert.throws): 89 (assert.throws.callback): 90 (assert.eq): 91 * wasm/stress/simple-export-exception.js: Added. 92 * wasm/v8/LICENSE: Added. 93 * wasm/v8/exceptions-api.js: Added. 94 (TestImport): 95 (TestImportExport): 96 (TestExceptionConstructor): 97 (TestExceptionConstructorWithPayload): 98 (TestCatchJSException.js_func): 99 (js_func): 100 (TestCatchJS): 101 (TestCatchJSExceptionWithPayload): 102 (TestGetArg): 103 * wasm/v8/exceptions-export.js: Added. 104 (TestExportMultiple): 105 (TestExportOutOfBounds): 106 * wasm/v8/exceptions-externref.js: Added. 107 (TestThrowRefNull): 108 (TestThrowRefParam): 109 * wasm/v8/exceptions-import.js: Added. 110 (NewExportedTag): 111 (TestImportSimple): 112 (TestImportMissing): 113 * wasm/v8/exceptions-rethrow.js: Added. 114 (TestRethrowInCatch): 115 (TestRethrowInCatchAll): 116 (TestRethrowNested): 117 (TestRethrowRecatch): 118 * wasm/v8/exceptions-shared.js: Added. 119 (NewExportedException): 120 (TestSingleInstance.let.instance.builder.instantiate.): 121 (TestSingleInstance): 122 (TestMultiInstanceNonShared.let.instance2.builder.instantiate.): 123 (TestMultiInstanceShared.let.instance2.builder.instantiate.): 124 (TestMultiModuleShared.let.instance2.builder2.instantiate.): 125 * wasm/v8/exceptions-type-reflection.js: Added. 126 (TestExport): 127 (TestImportExport): 128 * wasm/v8/exceptions-utils.js: Added. 129 (assertWasmThrows): 130 * wasm/v8/exceptions.js: Added. 131 (TestThrowSimple): 132 (TestCatchSimple): 133 (TestTrapNotCaught): 134 (TestTrapViaJSNotCaught.js_import): 135 (TestManuallyThrownRuntimeErrorCaught.throw_exc): 136 (TestManuallyThrownRuntimeErrorCaught): 137 (TestExnWithWasmProtoNotCaught.js_import): 138 (TestExnWithWasmProtoNotCaught): 139 (TestStackOverflowNotCaught.stack_overflow): 140 (TestStackOverflowNotCaught): 141 (TestThrowParamI): 142 (TestThrowParamF): 143 (TestThrowParamL): 144 (TestThrowParamD): 145 (TestCatchCrossFunctions.throw_value): 146 (TestCatchCrossFunctions.throw_string): 147 (TestCatchCrossFunctions.throw_undefined): 148 (TestCatchCrossFunctions.throw_fp): 149 (TestCatchCrossFunctions.throw_large): 150 (TestDelegateNoThrow): 151 (TestDelegateThrow): 152 (TestDelegateThrowNoCatch): 153 (TestDelegateMerge): 154 (TestDelegate1): 155 (TestDelegateUnreachable): 156 (TestDelegateToCaller): 157 (TestUnreachableInCatchAll): 158 (TestThrowWithLocal): 159 (TestCatchlessTry): 160 * wasm/v8/mjsunit.js: Added. 161 (MjsUnitAssertionError): 162 (MjsUnitAssertionError.prototype.toString): 163 (catch): 164 (classOf): 165 (ValueOf): 166 (prettyPrinted): 167 (prettyPrintedArrayElement): 168 (failWithMessage): 169 (formatFailureText): 170 (fail): 171 (deepObjectEquals): 172 (deepEquals): 173 (assertSame): 174 (assertNotSame): 175 (assertEquals): 176 (assertNotEquals): 177 (assertEqualsDelta): 178 (assertArrayEquals): 179 (assertPropertiesEqual): 180 (assertToStringEquals): 181 (assertTrue): 182 (assertFalse): 183 (assertNull): 184 (assertNotNull): 185 (executeCode): 186 (checkException): 187 (assertThrows): 188 (assertThrowsEquals): 189 (assertThrowsAsync): 190 (assertInstanceof): 191 (assertDoesNotThrow): 192 (assertUnreachable): 193 (assertContains): 194 (assertMatches): 195 (concatenateErrors): 196 (assertPromiseResult): 197 (OptimizationStatus): 198 (assertUnoptimized): 199 (assertOptimized): 200 (isNeverOptimizeLiteMode): 201 (isNeverOptimize): 202 (isAlwaysOptimize): 203 (isInterpreted): 204 (isBaseline): 205 (isUnoptimized): 206 (isOptimized): 207 (isTurboFanned): 208 (MjsUnitAssertionError.prepareStackTrace): 209 * wasm/v8/wasm-module-builder.js: Added. 210 (bytes): 211 (wasmOptRefType): 212 (wasmRefType): 213 (wasmRtt): 214 (wasmRttNoDepth): 215 (makeSig): 216 (makeSig_v_x): 217 (makeSig_x_v): 218 (makeSig_v_xx): 219 (makeSig_r_v): 220 (makeSig_r_x): 221 (makeSig_r_xx): 222 (defineWasmOpcode): 223 (assertTraps): 224 (Binary): 225 (Binary.prototype.ensure_space): 226 (Binary.prototype.trunc_buffer): 227 (Binary.prototype.reset): 228 (Binary.prototype.emit_u8): 229 (Binary.prototype.emit_u16): 230 (Binary.prototype.emit_u32): 231 (Binary.prototype.emit_leb_u): 232 (Binary.prototype.emit_u32v): 233 (Binary.prototype.emit_u64v): 234 (Binary.prototype.emit_bytes): 235 (Binary.prototype.emit_string): 236 (Binary.prototype.emit_heap_type): 237 (Binary.prototype.emit_type): 238 (Binary.prototype.emit_init_expr_recursive): 239 (Binary.prototype.emit_init_expr): 240 (Binary.prototype.emit_header): 241 (Binary.prototype.emit_section): 242 (WasmFunctionBuilder): 243 (WasmFunctionBuilder.prototype.numLocalNames): 244 (WasmFunctionBuilder.prototype.exportAs): 245 (WasmFunctionBuilder.prototype.exportFunc): 246 (WasmFunctionBuilder.prototype.setCompilationHint): 247 (WasmFunctionBuilder.prototype.addBody): 248 (WasmFunctionBuilder.prototype.addBodyWithEnd): 249 (WasmFunctionBuilder.prototype.getNumLocals): 250 (WasmFunctionBuilder.prototype.addLocals): 251 (WasmFunctionBuilder.prototype.end): 252 (WasmInitExpr.I32Const): 253 (WasmInitExpr.I64Const): 254 (WasmInitExpr.F32Const): 255 (WasmInitExpr.F64Const): 256 (WasmInitExpr.S128Const): 257 (WasmInitExpr.GlobalGet): 258 (WasmInitExpr.RefFunc): 259 (WasmInitExpr.RefNull): 260 (WasmInitExpr.StructNewWithRtt): 261 (WasmInitExpr.StructNew): 262 (WasmInitExpr.StructNewDefaultWithRtt): 263 (WasmInitExpr.StructNewDefault): 264 (WasmInitExpr.ArrayInit): 265 (WasmInitExpr.ArrayInitStatic): 266 (WasmInitExpr.RttCanon): 267 (WasmInitExpr.RttSub): 268 (WasmInitExpr.RttFreshSub): 269 (WasmInitExpr.defaultFor): 270 (WasmInitExpr): 271 (WasmGlobalBuilder): 272 (WasmGlobalBuilder.prototype.exportAs): 273 (WasmTableBuilder): 274 (WasmTableBuilder.prototype.exportAs): 275 (makeField): 276 (WasmStruct): 277 (WasmStructSubtype): 278 (WasmArray): 279 (WasmArraySubtype): 280 (WasmElemSegment): 281 (WasmElemSegment.prototype.is_active): 282 (WasmElemSegment.prototype.is_passive): 283 (WasmElemSegment.prototype.is_declarative): 284 (WasmElemSegment.prototype.expressions_as_elements): 285 (WasmModuleBuilder): 286 (WasmModuleBuilder.prototype.addStart): 287 (WasmModuleBuilder.prototype.addMemory): 288 (WasmModuleBuilder.prototype.addMemory64): 289 (WasmModuleBuilder.prototype.addExplicitSection): 290 (WasmModuleBuilder.prototype.stringToBytes): 291 (WasmModuleBuilder.prototype.createCustomSection): 292 (WasmModuleBuilder.prototype.addCustomSection): 293 (WasmModuleBuilder.prototype.addType): 294 (WasmModuleBuilder.prototype.addStruct): 295 (WasmModuleBuilder.prototype.addStructSubtype): 296 (WasmModuleBuilder.prototype.addArray): 297 (WasmModuleBuilder.prototype.addArraySubtype): 298 (WasmModuleBuilder.prototype.addGlobal): 299 (WasmModuleBuilder.prototype.addTable): 300 (WasmModuleBuilder.prototype.addTag): 301 (WasmModuleBuilder.prototype.addFunction): 302 (WasmModuleBuilder.prototype.addImport): 303 (WasmModuleBuilder.prototype.addImportedGlobal): 304 (WasmModuleBuilder.prototype.addImportedMemory): 305 (WasmModuleBuilder.prototype.addImportedTable): 306 (WasmModuleBuilder.prototype.addImportedTag): 307 (WasmModuleBuilder.prototype.addExport): 308 (WasmModuleBuilder.prototype.addExportOfKind): 309 (WasmModuleBuilder.prototype.setCompilationHint): 310 (WasmModuleBuilder.prototype.addDataSegment): 311 (WasmModuleBuilder.prototype.addPassiveDataSegment): 312 (WasmModuleBuilder.prototype.exportMemoryAs): 313 (WasmModuleBuilder.prototype.addActiveElementSegment): 314 (WasmModuleBuilder.prototype.addPassiveElementSegment): 315 (WasmModuleBuilder.prototype.addDeclarativeElementSegment): 316 (WasmModuleBuilder.prototype.appendToTable): 317 (WasmModuleBuilder.prototype.setTableBounds): 318 (WasmModuleBuilder.prototype.setName): 319 (WasmModuleBuilder.prototype.toBuffer): 320 (WasmModuleBuilder.prototype.toArray): 321 (WasmModuleBuilder.prototype.instantiate): 322 (WasmModuleBuilder.prototype.asyncInstantiate): 323 (WasmModuleBuilder.prototype.toModule): 324 (wasmSignedLeb): 325 (wasmUnsignedLeb): 326 (wasmI32Const): 327 (wasmI64Const): 328 (wasmF32Const): 329 (wasmF64Const): 330 (wasmS128Const): 331 (getOpcodeName): 332 * wasm/wasm.json: 333 1 334 2021-10-08 Yusuke Suzuki <ysuzuki@apple.com> 2 335 -
trunk/JSTests/wasm.yaml
r276896 r283852 46 46 - path: wasm/self-test/ 47 47 cmd: runWebAssemblySuite unless parseRunCommands 48 - path: wasm/v8/ 49 cmd: runWebAssemblySuite(:no_module, "mjsunit.js") unless parseRunCommands 48 50 49 51 - path: wasm/references-spec-tests/elem.wast.js -
trunk/JSTests/wasm/Builder.js
r270344 r283852 129 129 }; 130 130 131 const _importExceptionContinuation = (builder, section, nextBuilder) => { 132 return (module, field, type) => { 133 assert.isString(module, `Import function module should be a string, got "${module}"`); 134 assert.isString(field, `Import function field should be a string, got "${field}"`); 135 const typeSection = builder._getSection("Type"); 136 type = _maybeRegisterType(builder, type); 137 const tag = 0; 138 section.data.push({ field, type, tag, kind: "Exception", module }); 139 return _errorHandlingProxyFor(nextBuilder); 140 } 141 }; 142 131 143 const _exportFunctionContinuation = (builder, section, nextBuilder) => { 132 144 return (field, index, type) => { … … 212 224 assert.isNumber(index, `Table exports only support number indices`); 213 225 section.data.push({field, kind: "Table", index}); 226 return _errorHandlingProxyFor(nextBuilder); 227 } 228 }; 229 230 const _exportExceptionContinuation = (builder, section, nextBuilder) => { 231 return (field, index) => { 232 assert.isNumber(index, `Exception exports only support number indices`); 233 section.data.push({field, kind: "Exception", index}); 214 234 return _errorHandlingProxyFor(nextBuilder); 215 235 } … … 308 328 case "reserved": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421 309 329 case "table_index": break; // improve checking https://bugs.webkit.org/show_bug.cgi?id=163421 330 case "exn": break; 310 331 case "reftype": 311 332 assert.truthy(WASM.isValidRefType(imms[idx]), `Invalid ref type on ${op}: "${imms[idx]}"`); … … 336 357 break; 337 358 case "End": 359 case "Delegate": 338 360 nextBuilder = previousBuilder; 339 361 break; … … 341 363 case "Loop": 342 364 case "If": 365 case "Try": 343 366 nextBuilder = _createFunctionBuilder(func, builder, functionBuilder); 344 367 break; … … 489 512 importBuilder.Memory = _importMemoryContinuation(this, s, importBuilder); 490 513 importBuilder.Table = _importTableContinuation(this, s, importBuilder); 514 importBuilder.Exception = _importExceptionContinuation(this, s, importBuilder); 491 515 return _errorHandlingProxyFor(importBuilder); 492 516 }; … … 531 555 }; 532 556 break; 557 558 case "Exception": { 559 this[section] = function() { 560 const s = this._addSection(section); 561 const dataBuilder = { 562 End: () => this, 563 Signature: (signature) => { 564 let type = _maybeRegisterType(this, signature); 565 s.data.push({ tag: 0, type }); 566 return _errorHandlingProxyFor(dataBuilder); 567 }, 568 // If we add tags with non-zero value then we can add a new member. 569 }; 570 return _errorHandlingProxyFor(dataBuilder); 571 }; 572 break; 573 } 533 574 534 575 case "Global": … … 570 611 exportBuilder.Memory = _exportMemoryContinuation(this, s, exportBuilder); 571 612 exportBuilder.Table = _exportTableContinuation(this, s, exportBuilder); 613 exportBuilder.Exception = _exportExceptionContinuation(this, s, exportBuilder); 572 614 return _errorHandlingProxyFor(exportBuilder); 573 615 }; … … 738 780 if (number !== _unknownSectionId) 739 781 assert.falsy(s.name === name && s.id === number, `Cannot have two sections with the same name "${name}" and ID ${number}`); 740 // Check ordering.741 if ((number !== _unknownSectionId) && (this._sections.length !== 0)) {742 for (let i = this._sections.length - 1; i >= 0; --i) {743 if (this._sections[i].id === _unknownSectionId)744 continue;745 assert.le(this._sections[i].id, number, `Bad section ordering: "${this._sections[i].name}" cannot precede "${name}"`);746 break;747 }748 }749 782 } 750 783 const s = Object.assign({ name: name, id: number, data: [] }, extraObject || {}); -
trunk/JSTests/wasm/Builder_WebAssemblyBinary.js
r270344 r283852 144 144 putGlobalType(bin, entry.globalDescription); 145 145 break; 146 case "Exception": 147 put(bin, "varuint32", entry.tag); 148 put(bin, "varuint32", entry.type); 149 break; 146 150 } 147 151 } … … 186 190 case "Memory": 187 191 case "Table": 192 case "Exception": 188 193 put(bin, "varuint32", entry.index); 189 194 break; … … 253 258 for (const byte of datum.data) 254 259 put(bin, "uint8", byte); 260 } 261 }, 262 263 Exception: (section, bin) => { 264 put(bin, "varuint32", section.data.length); 265 for (const exn of section.data) { 266 put(bin, "varuint32", exn.tag); 267 put(bin, "varuint32", exn.type); 255 268 } 256 269 }, -
trunk/JSTests/wasm/assert.js
r262227 r283852 125 125 func(...args); 126 126 } catch (e) { 127 if (e instanceof type && e.message.indexOf(message) >= 0)127 if (e instanceof type && (typeof(e.message) == "undefined" || e.message.indexOf(message) >= 0)) 128 128 return e; 129 129 _fail(`Expected to throw a ${type.name} with message "${message}", got ${e.name} with message "${e.message}"`); -
trunk/JSTests/wasm/self-test/test_BuilderJSON.js
r232970 r283852 139 139 assert.eq(j.section[0].name, "Import"); 140 140 assert.eq(j.section[0].data.length, 0); 141 })();142 143 (function ImportBeforeTypeSections() {144 const b = (new Builder()).Import().End();145 assert.throws(() => b.Type(), Error, `Expected: "2" > "1": Bad section ordering: "Import" cannot precede "Type"`);146 141 })(); 147 142 -
trunk/JSTests/wasm/wasm.json
r279265 r283852 24 24 "ref_type": ["funcref", "externref", "type_idx"], 25 25 "external_kind": { 26 "Function": { "type": "uint8", "value": 0 }, 27 "Table": { "type": "uint8", "value": 1 }, 28 "Memory": { "type": "uint8", "value": 2 }, 29 "Global": { "type": "uint8", "value": 3 } 26 "Function": { "type": "uint8", "value": 0 }, 27 "Table": { "type": "uint8", "value": 1 }, 28 "Memory": { "type": "uint8", "value": 2 }, 29 "Global": { "type": "uint8", "value": 3 }, 30 "Exception": { "type": "uint8", "value": 4 } 30 31 }, 31 32 "section" : { 32 "Type": { "type": "varuint7", "value": 1, "description": "Function signature declarations" }, 33 "Import": { "type": "varuint7", "value": 2, "description": "Import declarations" }, 34 "Function": { "type": "varuint7", "value": 3, "description": "Function declarations" }, 35 "Table": { "type": "varuint7", "value": 4, "description": "Indirect function table and other tables" }, 36 "Memory": { "type": "varuint7", "value": 5, "description": "Memory attributes" }, 37 "Global": { "type": "varuint7", "value": 6, "description": "Global declarations" }, 38 "Export": { "type": "varuint7", "value": 7, "description": "Exports" }, 39 "Start": { "type": "varuint7", "value": 8, "description": "Start function declaration" }, 40 "Element": { "type": "varuint7", "value": 9, "description": "Elements section" }, 41 "Code": { "type": "varuint7", "value": 10, "description": "Function bodies (code)" }, 42 "Data": { "type": "varuint7", "value": 11, "description": "Data segments" } 33 "Type": { "type": "varuint7", "value": 1, "description": "Function signature declarations" }, 34 "Import": { "type": "varuint7", "value": 2, "description": "Import declarations" }, 35 "Function": { "type": "varuint7", "value": 3, "description": "Function declarations" }, 36 "Table": { "type": "varuint7", "value": 4, "description": "Indirect function table and other tables" }, 37 "Memory": { "type": "varuint7", "value": 5, "description": "Memory attributes" }, 38 "Exception": { "type": "varuint7", "value": 13, "description": "Exception declarations" }, 39 "Global": { "type": "varuint7", "value": 6, "description": "Global declarations" }, 40 "Export": { "type": "varuint7", "value": 7, "description": "Exports" }, 41 "Start": { "type": "varuint7", "value": 8, "description": "Start function declaration" }, 42 "Element": { "type": "varuint7", "value": 9, "description": "Elements section" }, 43 "Code": { "type": "varuint7", "value": 10, "description": "Function bodies (code)" }, 44 "Data": { "type": "varuint7", "value": 11, "description": "Data segments" }, 45 "DataCount": { "type": "varuint7", "value": 12, "description": "Number of data segments" } 43 46 }, 44 47 "opcode": { 45 48 "unreachable": { "category": "control", "value": 0, "return": [], "parameter": [], "immediate": [], "description": "trap immediately" }, 49 "nop": { "category": "control", "value": 1, "return": [], "parameter": [], "immediate": [], "description": "no operation" }, 46 50 "block": { "category": "control", "value": 2, "return": ["control"], "parameter": [], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin a sequence of expressions, yielding 0 or 1 values" }, 47 51 "loop": { "category": "control", "value": 3, "return": ["control"], "parameter": [], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin a block which can also form control flow loops" }, 48 52 "if": { "category": "control", "value": 4, "return": ["control"], "parameter": ["bool"], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin if expression" }, 49 53 "else": { "category": "control", "value": 5, "return": ["control"], "parameter": [], "immediate": [], "description": "begin else expression of if" }, 50 " select": { "category": "control", "value": 27, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [], "description": "select one of two values based on condition" },51 " annotated_select": { "category": "control", "value": 28, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [{"name": "target_types_count", "type": "varuint32", "description": "number of entries in the target types vector"},52 {"name": "target_types", "type": "value_type*", "description": "target types that indicate result of select instruction"}],53 "description": "the same as just select but with the annotation for result types" },54 "try": { "category": "control", "value": 6, "return": ["control"], "parameter": [], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin try expression" }, 55 "catch": { "category": "control", "value": 7, "return": ["control"], "parameter": [], "immediate": [{"name": "exn", "type": "varuint32"}], "description": "begin catch expression of try" }, 56 "throw": { "category": "control", "value": 8, "return": ["control"], "parameter": [], "immediate": [{"name": "exn", "type": "varuint32"}], "description": "throw exception" }, 57 "rethrow": { "category": "control", "value": 9, "return": ["control"], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "rethrow the exception at the top of the stack" }, 54 58 "br": { "category": "control", "value": 12, "return": [], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "break that targets an outer nested block" }, 55 59 "br_if": { "category": "control", "value": 13, "return": [], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "conditional break that targets an outer nested block" }, … … 59 63 "description": "branch table control flow construct" }, 60 64 "return": { "category": "control", "value": 15, "return": [], "parameter": [], "immediate": [], "description": "return zero or one value from this function" }, 65 "delegate": { "category": "control", "value": 24, "return": ["control"], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "delegate to a parent try block" }, 66 "catch_all": { "category": "control", "value": 25, "return": ["control"], "parameter": [], "immediate": [], "description": "catch exceptions regardless of tag" }, 61 67 "drop": { "category": "control", "value": 26, "return": [], "parameter": ["any"], "immediate": [], "description": "ignore value" }, 62 "nop": { "category": "control", "value": 1, "return": [], "parameter": [], "immediate": [], "description": "no operation" }, 68 "select": { "category": "control", "value": 27, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [], "description": "select one of two values based on condition" }, 69 "annotated_select": { "category": "control", "value": 28, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [{"name": "target_types_count", "type": "varuint32", "description": "number of entries in the target types vector"}, 70 {"name": "target_types", "type": "value_type*", "description": "target types that indicate result of select instruction"}], 71 "description": "the same as just select but with the annotation for result types" }, 63 72 "end": { "category": "control", "value": 11, "return": [], "parameter": [], "immediate": [], "description": "end a block, loop, or if" }, 64 73 "i32.const": { "category": "special", "value": 65, "return": ["i32"], "parameter": [], "immediate": [{"name": "value", "type": "varint32"}], "description": "a constant value interpreted as i32" }, -
trunk/Source/JavaScriptCore/CMakeLists.txt
r283851 r283852 123 123 wasm/js/WebAssemblyCompileErrorConstructor.cpp 124 124 wasm/js/WebAssemblyCompileErrorPrototype.cpp 125 wasm/js/WebAssemblyExceptionConstructor.cpp 126 wasm/js/WebAssemblyExceptionPrototype.cpp 125 127 wasm/js/WebAssemblyGlobalConstructor.cpp 126 128 wasm/js/WebAssemblyGlobalPrototype.cpp … … 137 139 wasm/js/WebAssemblyTableConstructor.cpp 138 140 wasm/js/WebAssemblyTablePrototype.cpp 141 wasm/js/WebAssemblyTagConstructor.cpp 142 wasm/js/WebAssemblyTagPrototype.cpp 139 143 ) 140 144 … … 604 608 b3/B3Common.h 605 609 b3/B3Type.h 610 b3/B3ValueRep.h 606 611 607 612 bindings/ScriptFunctionCall.h … … 1223 1228 wasm/WasmFormat.h 1224 1229 wasm/WasmFunctionCodeBlock.h 1230 wasm/WasmHandlerInfo.h 1225 1231 wasm/WasmIndexOrName.h 1226 1232 wasm/WasmLLIntTierUpCounter.h … … 1231 1237 wasm/WasmName.h 1232 1238 wasm/WasmNameSection.h 1239 wasm/WasmOSREntryData.h 1233 1240 wasm/WasmPageCount.h 1234 1241 wasm/WasmSections.h … … 1237 1244 wasm/WasmStreamingParser.h 1238 1245 wasm/WasmTierUpCount.h 1246 wasm/WasmValueLocation.h 1239 1247 1240 1248 wasm/js/JSWebAssembly.h -
trunk/Source/JavaScriptCore/ChangeLog
r283851 r283852 1 2021-10-08 Tadeu Zagallo <tzagallo@apple.com> and Keith Miller <keith_miller@apple.com> 2 3 Implement the WebAssembly exception handling proposal 4 https://bugs.webkit.org/show_bug.cgi?id=229681 5 <rdar://81603387> 6 7 Reviewed by Keith Miller. 8 9 Add support for the WebAssembly exception handling proposal, as per 10 the WIP spec: https://github.com/WebAssembly/exception-handling 11 12 The proposal includes 6 new instructions: try, catch, catch_all, 13 delegate, throw and rethrow. All the instructions are supported by 14 the LLInt and B3 generators, but not yet supported in Air. Any 15 functions use exceptions will use B3 in BBQ. 16 17 A few important notes about the implementation: 18 - In B3, since we can now have multiple entrypoints (one for the 19 function entry + 1 for each catch/catch_all), we can no longer just 20 replace every value in the stack with a Phi when we find a new 21 entrypoint. This worked so far because of the assumption that any 22 block couldn't access its enclosing stack, and since the enclosing stack 23 would only be accessible when we exited the current block, we added Phis 24 at the end of each block when we had a new entrypoint. Now, since we have to capture all 25 live values at any point that might throw (calls, throw and rethrow), 26 we break that assumption. To simplify all the possible ways we might 27 have to merge the state from multiple entrypoints we now use B3 28 Variables to represent stack slots. 29 - Some extra information is required to be able to properly restore 30 the state when catching an exception: 31 - We added a field VM::calleeForWasmCatch. This field is necessary 32 because whenever we throw, we might end up in JavaScript, which 33 assumes the callee is a cell and uses it to get the VM and restore 34 callee saves. The issue is when catching exceptions in wasm we 35 still need the original callee, and if throwing and catching from 36 the same frame, that call frame slot has now been overwritten, so 37 we store its original value in the VM field. 38 - We also need to store the current Wasm Instance into the call 39 frame's slot for the `this` argument. The instance is used both by 40 the unwinder, to check if the exception being thrown matches the 41 exceptions handled by catch candidates, and by the catch implementation, 42 which is necessary when throwing from a cross instance call where both 43 the callee save or TLS will have the callee's instance. 44 - We store the current opcode for the llint, or the 45 call site index for B3, in the call frame slot for the argument 46 count tag. The call site index is used by the unwinder to check 47 if a given catch can handle the exception being thrown. 48 49 * DerivedSources-input.xcfilelist: 50 * DerivedSources-output.xcfilelist: 51 * DerivedSources.make: 52 * JavaScriptCore.xcodeproj/project.pbxproj: 53 * Sources.txt: 54 * bytecode/BytecodeList.rb: 55 * bytecode/HandlerInfo.h: 56 * bytecode/Instruction.h: 57 (JSC::BaseInstruction::name const): 58 * interpreter/CallFrame.cpp: 59 (JSC::CallFrame::bytecodeIndex const): 60 * interpreter/CallFrame.h: 61 (JSC::CallSiteIndex::CallSiteIndex): 62 (JSC::CallSiteIndex::hash const): 63 (JSC::CallSiteIndex::deletedValue): 64 (JSC::CallSiteIndex::isHashTableDeletedValue const): 65 (JSC::CallSiteIndexHash::hash): 66 (JSC::CallSiteIndexHash::equal): 67 * interpreter/Interpreter.cpp: 68 (JSC::CatchInfo::CatchInfo): 69 (JSC::UnwindFunctor::UnwindFunctor): 70 (JSC::UnwindFunctor::operator() const): 71 (JSC::Interpreter::unwind): 72 * interpreter/Interpreter.h: 73 (JSC::CatchInfo::CatchInfo): 74 * interpreter/StackVisitor.cpp: 75 (JSC::StackVisitor::readNonInlinedFrame): 76 * jit/AssemblyHelpers.cpp: 77 (JSC::AssemblyHelpers::restoreCalleeSavesFromEntryFrameCalleeSavesBuffer): 78 (JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer): 79 (JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl): 80 * jit/AssemblyHelpers.h: 81 * jit/JITExceptions.cpp: 82 (JSC::genericUnwind): 83 * jit/JSInterfaceJIT.h: 84 (JSC::JSInterfaceJIT::convertCalleeToVM): 85 * llint/LLIntData.h: 86 (JSC::LLInt::getCodeRef): 87 (JSC::LLInt::getWide16CodeRef): 88 (JSC::LLInt::getWide32CodeRef): 89 * llint/LLIntExceptions.cpp: 90 (JSC::LLInt::wasmReturnToThrow): 91 (JSC::LLInt::handleWasmCatch): 92 (JSC::LLInt::handleWasmCatchAll): 93 * llint/LLIntExceptions.h: 94 * llint/LLIntOffsetsExtractor.cpp: 95 * llint/WebAssembly.asm: 96 * runtime/ErrorInstance.cpp: 97 (JSC::ErrorInstance::ErrorInstance): 98 * runtime/ErrorInstance.h: 99 (JSC::ErrorInstance::setCatchableFromWasm): 100 (JSC::ErrorInstance::isCatchableFromWasm const): 101 * runtime/JSGlobalObject.cpp: 102 * runtime/JSGlobalObject.h: 103 * runtime/OptionsList.h: 104 * runtime/VM.cpp: 105 (JSC::VM::VM): 106 * runtime/VM.h: 107 (JSC::VM::calleeForWasmCatchOffset): 108 * wasm/WasmAirIRGenerator.cpp: 109 (JSC::Wasm::AirIRGenerator::ControlData::isTry): 110 (JSC::Wasm::AirIRGenerator::ControlData::isCatch): 111 (JSC::Wasm::AirIRGenerator::ControlData::isAnyCatch): 112 (JSC::Wasm::AirIRGenerator::ControlData::isLoop): 113 (JSC::Wasm::AirIRGenerator::ControlData::isBlock): 114 (JSC::Wasm::AirIRGenerator::ControlData::dump const): 115 (JSC::Wasm::AirIRGenerator::addTry): 116 (JSC::Wasm::AirIRGenerator::addCatch): 117 (JSC::Wasm::AirIRGenerator::addCatchToUnreachable): 118 (JSC::Wasm::AirIRGenerator::addCatchAll): 119 (JSC::Wasm::AirIRGenerator::addCatchAllToUnreachable): 120 (JSC::Wasm::AirIRGenerator::addDelegate): 121 (JSC::Wasm::AirIRGenerator::addDelegateToUnreachable): 122 (JSC::Wasm::AirIRGenerator::addThrow): 123 (JSC::Wasm::AirIRGenerator::addRethrow): 124 * wasm/WasmB3IRGenerator.cpp: 125 (JSC::Wasm::B3IRGenerator::ControlData::ControlData): 126 (JSC::Wasm::B3IRGenerator::ControlData::isTry): 127 (JSC::Wasm::B3IRGenerator::ControlData::isAnyCatch): 128 (JSC::Wasm::B3IRGenerator::ControlData::isLoop): 129 (JSC::Wasm::B3IRGenerator::ControlData::isBlock): 130 (JSC::Wasm::B3IRGenerator::ControlData::isCatch): 131 (JSC::Wasm::B3IRGenerator::ControlData::dump const): 132 (JSC::Wasm::B3IRGenerator::ControlData::convertTryToCatch): 133 (JSC::Wasm::B3IRGenerator::ControlData::convertTryToCatchAll): 134 (JSC::Wasm::B3IRGenerator::ControlData::tryStart const): 135 (JSC::Wasm::B3IRGenerator::ControlData::tryEnd const): 136 (JSC::Wasm::B3IRGenerator::ControlData::tryDepth const): 137 (JSC::Wasm::B3IRGenerator::ControlData::catchKind const): 138 (JSC::Wasm::B3IRGenerator::ControlData::exception const): 139 (JSC::Wasm::B3IRGenerator::ControlData::stackSize const): 140 (JSC::Wasm::B3IRGenerator::didPopValueFromStack): 141 (JSC::Wasm::B3IRGenerator::addStackMap): 142 (JSC::Wasm::B3IRGenerator::takeStackmaps): 143 (JSC::Wasm::B3IRGenerator::takeExceptionHandlers): 144 (JSC::Wasm::B3IRGenerator::push): 145 (JSC::Wasm::B3IRGenerator::get): 146 (JSC::Wasm::B3IRGenerator::set): 147 (JSC::Wasm::PatchpointExceptionHandle::generate const): 148 (JSC::Wasm::B3IRGenerator::fixupPointerPlusOffset): 149 (JSC::Wasm::B3IRGenerator::B3IRGenerator): 150 (JSC::Wasm::B3IRGenerator::restoreWebAssemblyGlobalState): 151 (JSC::Wasm::B3IRGenerator::insertEntrySwitch): 152 (JSC::Wasm::B3IRGenerator::insertConstants): 153 (JSC::Wasm::B3IRGenerator::addRefIsNull): 154 (JSC::Wasm::B3IRGenerator::addTableGet): 155 (JSC::Wasm::B3IRGenerator::addTableSet): 156 (JSC::Wasm::B3IRGenerator::addRefFunc): 157 (JSC::Wasm::B3IRGenerator::addTableInit): 158 (JSC::Wasm::B3IRGenerator::addTableSize): 159 (JSC::Wasm::B3IRGenerator::addTableGrow): 160 (JSC::Wasm::B3IRGenerator::addTableFill): 161 (JSC::Wasm::B3IRGenerator::addTableCopy): 162 (JSC::Wasm::B3IRGenerator::getLocal): 163 (JSC::Wasm::B3IRGenerator::emitIndirectCall): 164 (JSC::Wasm::B3IRGenerator::addGrowMemory): 165 (JSC::Wasm::B3IRGenerator::addCurrentMemory): 166 (JSC::Wasm::B3IRGenerator::addMemoryFill): 167 (JSC::Wasm::B3IRGenerator::addMemoryInit): 168 (JSC::Wasm::B3IRGenerator::addMemoryCopy): 169 (JSC::Wasm::B3IRGenerator::setLocal): 170 (JSC::Wasm::B3IRGenerator::getGlobal): 171 (JSC::Wasm::B3IRGenerator::setGlobal): 172 (JSC::Wasm::B3IRGenerator::emitCheckAndPreparePointer): 173 (JSC::Wasm::B3IRGenerator::emitLoadOp): 174 (JSC::Wasm::B3IRGenerator::load): 175 (JSC::Wasm::B3IRGenerator::emitStoreOp): 176 (JSC::Wasm::B3IRGenerator::store): 177 (JSC::Wasm::B3IRGenerator::sanitizeAtomicResult): 178 (JSC::Wasm::B3IRGenerator::fixupPointerPlusOffsetForAtomicOps): 179 (JSC::Wasm::B3IRGenerator::emitAtomicLoadOp): 180 (JSC::Wasm::B3IRGenerator::atomicLoad): 181 (JSC::Wasm::B3IRGenerator::emitAtomicStoreOp): 182 (JSC::Wasm::B3IRGenerator::atomicStore): 183 (JSC::Wasm::B3IRGenerator::emitAtomicBinaryRMWOp): 184 (JSC::Wasm::B3IRGenerator::atomicBinaryRMW): 185 (JSC::Wasm::B3IRGenerator::emitAtomicCompareExchange): 186 (JSC::Wasm::B3IRGenerator::atomicCompareExchange): 187 (JSC::Wasm::B3IRGenerator::atomicWait): 188 (JSC::Wasm::B3IRGenerator::atomicNotify): 189 (JSC::Wasm::B3IRGenerator::truncSaturated): 190 (JSC::Wasm::B3IRGenerator::addSelect): 191 (JSC::Wasm::B3IRGenerator::addConstant): 192 (JSC::Wasm::B3IRGenerator::emitLoopTierUpCheck): 193 (JSC::Wasm::B3IRGenerator::loadFromScratchBuffer): 194 (JSC::Wasm::B3IRGenerator::connectControlEntry): 195 (JSC::Wasm::B3IRGenerator::addLoop): 196 (JSC::Wasm::B3IRGenerator::addTopLevel): 197 (JSC::Wasm::B3IRGenerator::addBlock): 198 (JSC::Wasm::B3IRGenerator::addIf): 199 (JSC::Wasm::B3IRGenerator::addElse): 200 (JSC::Wasm::B3IRGenerator::addElseToUnreachable): 201 (JSC::Wasm::B3IRGenerator::addTry): 202 (JSC::Wasm::B3IRGenerator::addCatch): 203 (JSC::Wasm::B3IRGenerator::preparePatchpointForExceptions): 204 (JSC::Wasm::B3IRGenerator::addCatchToUnreachable): 205 (JSC::Wasm::B3IRGenerator::addCatchAll): 206 (JSC::Wasm::B3IRGenerator::addCatchAllToUnreachable): 207 (JSC::Wasm::B3IRGenerator::emitCatchImpl): 208 (JSC::Wasm::B3IRGenerator::addDelegate): 209 (JSC::Wasm::B3IRGenerator::addDelegateToUnreachable): 210 (JSC::Wasm::B3IRGenerator::addThrow): 211 (JSC::Wasm::B3IRGenerator::addRethrow): 212 (JSC::Wasm::B3IRGenerator::addReturn): 213 (JSC::Wasm::B3IRGenerator::addBranch): 214 (JSC::Wasm::B3IRGenerator::addSwitch): 215 (JSC::Wasm::B3IRGenerator::endBlock): 216 (JSC::Wasm::B3IRGenerator::addEndToUnreachable): 217 (JSC::Wasm::B3IRGenerator::createCallPatchpoint): 218 (JSC::Wasm::B3IRGenerator::addCall): 219 (JSC::Wasm::B3IRGenerator::addCallIndirect): 220 (JSC::Wasm::B3IRGenerator::addCallRef): 221 (JSC::Wasm::B3IRGenerator::unify): 222 (JSC::Wasm::B3IRGenerator::unifyValuesWithBlock): 223 (JSC::Wasm::parseAndCompile): 224 (JSC::Wasm::computeExceptionHandlerLocations): 225 (JSC::Wasm::B3IRGenerator::emitChecksForModOrDiv): 226 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32DivS>): 227 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32RemS>): 228 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32DivU>): 229 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32RemU>): 230 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64DivS>): 231 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64RemS>): 232 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64DivU>): 233 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64RemU>): 234 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32Ctz>): 235 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64Ctz>): 236 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32Popcnt>): 237 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64Popcnt>): 238 (JSC::Wasm::B3IRGenerator::addOp<F64ConvertUI64>): 239 (JSC::Wasm::B3IRGenerator::addOp<OpType::F32ConvertUI64>): 240 (JSC::Wasm::B3IRGenerator::addOp<OpType::F64Nearest>): 241 (JSC::Wasm::B3IRGenerator::addOp<OpType::F32Nearest>): 242 (JSC::Wasm::B3IRGenerator::addOp<OpType::F64Trunc>): 243 (JSC::Wasm::B3IRGenerator::addOp<OpType::F32Trunc>): 244 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncSF64>): 245 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncSF32>): 246 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncUF64>): 247 (JSC::Wasm::B3IRGenerator::addOp<OpType::I32TruncUF32>): 248 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncSF64>): 249 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncUF64>): 250 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncSF32>): 251 (JSC::Wasm::B3IRGenerator::addOp<OpType::I64TruncUF32>): 252 * wasm/WasmB3IRGenerator.h: 253 * wasm/WasmBBQPlan.cpp: 254 (JSC::Wasm::BBQPlan::prepareImpl): 255 (JSC::Wasm::BBQPlan::work): 256 (JSC::Wasm::BBQPlan::compileFunction): 257 (JSC::Wasm::BBQPlan::didCompleteCompilation): 258 (JSC::Wasm::BBQPlan::initializeCallees): 259 * wasm/WasmBBQPlan.h: 260 * wasm/WasmCallee.cpp: 261 (JSC::Wasm::Callee::handlerForIndex): 262 (JSC::Wasm::LLIntCallee::LLIntCallee): 263 (JSC::Wasm::LLIntCallee::linkExceptionHandlers): 264 (JSC::Wasm::OptimizingJITCallee::linkExceptionHandlers): 265 (JSC::Wasm::OptimizingJITCallee::stackmap const): 266 * wasm/WasmCallee.h: 267 (JSC::Wasm::Callee::hasExceptionHandlers const): 268 (JSC::Wasm::Callee::functionCodeBlock const): 269 (JSC::Wasm::OptimizingJITCallee::OptimizingJITCallee): 270 * wasm/WasmCallingConvention.h: 271 (JSC::Wasm::WasmCallingConvention::callInformationFor const): 272 * wasm/WasmFormat.h: 273 (JSC::Wasm::typeToString): 274 (JSC::Wasm::isValidExternalKind): 275 (JSC::Wasm::makeString): 276 * wasm/WasmFunctionCodeBlock.h: 277 (JSC::Wasm::FunctionCodeBlock::numberOfExceptionHandlers const): 278 (JSC::Wasm::FunctionCodeBlock::exceptionHandler): 279 (JSC::Wasm::FunctionCodeBlock::addExceptionHandler): 280 * wasm/WasmFunctionParser.h: 281 (JSC::Wasm::isTryOrCatch): 282 (JSC::Wasm::FunctionParser<Context>::parseExceptionIndex): 283 (JSC::Wasm::FunctionParser<Context>::parseExpression): 284 (JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression): 285 * wasm/WasmHandlerInfo.cpp: Added. 286 (JSC::Wasm::HandlerInfo::initialize): 287 (JSC::Wasm::HandlerInfo::handlerForIndex): 288 * wasm/WasmHandlerInfo.h: Added. 289 (JSC::Wasm::UnlinkedHandlerInfo::UnlinkedHandlerInfo): 290 (JSC::Wasm::HandlerInfo::tag const): 291 (JSC::Wasm::HandlerInfo::delegateTarget const): 292 * wasm/WasmInstance.cpp: 293 (JSC::Wasm::Instance::~Instance): 294 * wasm/WasmInstance.h: 295 (JSC::Wasm::Instance::addTag): 296 (JSC::Wasm::Instance::tag const): 297 * wasm/WasmLLIntGenerator.cpp: 298 (JSC::Wasm::LLIntGenerator::ControlType::try_): 299 (JSC::Wasm::LLIntGenerator::ControlType::catch_): 300 (JSC::Wasm::LLIntGenerator::ControlType::isLoop): 301 (JSC::Wasm::LLIntGenerator::ControlType::isBlock): 302 (JSC::Wasm::LLIntGenerator::ControlType::isIf): 303 (JSC::Wasm::LLIntGenerator::ControlType::isTry): 304 (JSC::Wasm::LLIntGenerator::ControlType::isAnyCatch): 305 (JSC::Wasm::LLIntGenerator::ControlType::isCatch): 306 (JSC::Wasm::LLIntGenerator::unifyValuesWithBlock): 307 (JSC::Wasm::LLIntGenerator::walkExpressionStack): 308 (JSC::Wasm::LLIntGenerator::materializeConstantsAndLocals): 309 (JSC::Wasm::parseAndCompileBytecode): 310 (JSC::Wasm::LLIntGenerator::LLIntGenerator): 311 (JSC::Wasm::LLIntGenerator::repatch): 312 (JSC::Wasm::LLIntGenerator::finalize): 313 (JSC::Wasm::LLIntGenerator::callInformationForCaller): 314 (JSC::Wasm::LLIntGenerator::callInformationForCallee): 315 (JSC::Wasm::LLIntGenerator::addArguments): 316 (JSC::Wasm::LLIntGenerator::addLoop): 317 (JSC::Wasm::LLIntGenerator::addTry): 318 (JSC::Wasm::LLIntGenerator::finalizePreviousBlockForCatch): 319 (JSC::Wasm::LLIntGenerator::addCatch): 320 (JSC::Wasm::LLIntGenerator::addCatchToUnreachable): 321 (JSC::Wasm::LLIntGenerator::addCatchAll): 322 (JSC::Wasm::LLIntGenerator::addCatchAllToUnreachable): 323 (JSC::Wasm::LLIntGenerator::addDelegate): 324 (JSC::Wasm::LLIntGenerator::addDelegateToUnreachable): 325 (JSC::Wasm::LLIntGenerator::addThrow): 326 (JSC::Wasm::LLIntGenerator::addRethrow): 327 (JSC::Wasm::LLIntGenerator::endBlock): 328 (JSC::Wasm::LLIntGenerator::addEndToUnreachable): 329 * wasm/WasmLLIntGenerator.h: 330 * wasm/WasmLimits.h: 331 * wasm/WasmModuleInformation.cpp: 332 * wasm/WasmModuleInformation.h: 333 (JSC::Wasm::ModuleInformation::exceptionIndexSpaceSize const): 334 (JSC::Wasm::ModuleInformation::isImportedExceptionFromExceptionIndexSpace const): 335 (JSC::Wasm::ModuleInformation::signatureIndexFromExceptionIndexSpace const): 336 (JSC::Wasm::ModuleInformation::importExceptionCount const): 337 (JSC::Wasm::ModuleInformation::isDeclaredException const): 338 (JSC::Wasm::ModuleInformation::addDeclaredException): 339 * wasm/WasmOMGForOSREntryPlan.cpp: 340 (JSC::Wasm::OMGForOSREntryPlan::work): 341 * wasm/WasmOMGPlan.cpp: 342 (JSC::Wasm::OMGPlan::work): 343 * wasm/WasmOSREntryData.h: 344 (JSC::Wasm::OSREntryData::values): 345 * wasm/WasmOperations.cpp: 346 (JSC::Wasm::loadValuesIntoBuffer): 347 (JSC::Wasm::doOSREntry): 348 (JSC::Wasm::JSC_DEFINE_JIT_OPERATION): 349 * wasm/WasmOperations.h: 350 * wasm/WasmSectionParser.cpp: 351 (JSC::Wasm::SectionParser::parseImport): 352 (JSC::Wasm::SectionParser::parseExport): 353 (JSC::Wasm::SectionParser::parseException): 354 * wasm/WasmSections.h: 355 (JSC::Wasm::validateOrder): 356 * wasm/WasmSignature.cpp: 357 (JSC::Wasm::SignatureInformation::SignatureInformation): 358 (JSC::Wasm::SignatureInformation::signatureFor): 359 * wasm/WasmSlowPaths.cpp: 360 (JSC::LLInt::WASM_SLOW_PATH_DECL): 361 * wasm/WasmSlowPaths.h: 362 * wasm/WasmStreamingParser.cpp: 363 (JSC::Wasm::StreamingParser::parseCodeSectionSize): 364 * wasm/WasmTag.cpp: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h. 365 * wasm/WasmTag.h: Copied from Source/JavaScriptCore/wasm/WasmLLIntGenerator.h. 366 (JSC::Wasm::Tag::create): 367 (JSC::Wasm::Tag::parameterCount const): 368 (JSC::Wasm::Tag::parameter const): 369 (JSC::Wasm::Tag::operator== const): 370 (JSC::Wasm::Tag::operator!= const): 371 (JSC::Wasm::Tag::signature const): 372 (JSC::Wasm::Tag::Tag): 373 * wasm/WasmThunks.cpp: 374 * wasm/WasmThunks.h: 375 * wasm/generateWasmB3IRGeneratorInlinesHeader.py: 376 (CodeGenerator.generateOpcode): 377 (CodeGenerator.makeResult): 378 (CodeGenerator.generate): 379 * wasm/generateWasmOpsHeader.py: 380 (typeMacroizer): 381 * wasm/js/JSWebAssembly.cpp: 382 * wasm/js/JSWebAssemblyException.cpp: Added. 383 (JSC::JSWebAssemblyException::JSWebAssemblyException): 384 (JSC::JSWebAssemblyException::finishCreation): 385 (JSC::JSWebAssemblyException::visitChildrenImpl): 386 (JSC::JSWebAssemblyException::destroy): 387 (JSC::JSWebAssemblyException::getArg const): 388 * wasm/js/JSWebAssemblyException.h: Added. 389 (JSC::JSWebAssemblyException::subspaceFor): 390 (JSC::JSWebAssemblyException::createStructure): 391 (JSC::JSWebAssemblyException::create): 392 (JSC::JSWebAssemblyException::tag const): 393 (JSC::JSWebAssemblyException::payload const): 394 * wasm/js/JSWebAssemblyHelpers.h: 395 (JSC::toJSValue): 396 (JSC::fromJSValue): 397 * wasm/js/JSWebAssemblyInstance.cpp: 398 (JSC::JSWebAssemblyInstance::tryCreate): 399 * wasm/js/JSWebAssemblyInstance.h: 400 * wasm/js/JSWebAssemblyRuntimeError.cpp: 401 (JSC::createJSWebAssemblyRuntimeError): 402 * wasm/js/JSWebAssemblyRuntimeError.h: 403 * wasm/js/JSWebAssemblyTag.cpp: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.cpp. 404 (JSC::JSWebAssemblyTag::create): 405 (JSC::JSWebAssemblyTag::createStructure): 406 (JSC::JSWebAssemblyTag::JSWebAssemblyTag): 407 * wasm/js/JSWebAssemblyTag.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h. 408 * wasm/js/WasmToJS.cpp: 409 (JSC::Wasm::wasmToJS): 410 * wasm/js/WebAssemblyExceptionConstructor.cpp: Added. 411 (JSC::JSC_DEFINE_HOST_FUNCTION): 412 (JSC::WebAssemblyExceptionConstructor::create): 413 (JSC::WebAssemblyExceptionConstructor::createStructure): 414 (JSC::WebAssemblyExceptionConstructor::finishCreation): 415 (JSC::WebAssemblyExceptionConstructor::WebAssemblyExceptionConstructor): 416 * wasm/js/WebAssemblyExceptionConstructor.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h. 417 * wasm/js/WebAssemblyExceptionPrototype.cpp: Added. 418 (JSC::WebAssemblyExceptionPrototype::create): 419 (JSC::WebAssemblyExceptionPrototype::createStructure): 420 (JSC::WebAssemblyExceptionPrototype::finishCreation): 421 (JSC::WebAssemblyExceptionPrototype::WebAssemblyExceptionPrototype): 422 (JSC::getException): 423 (JSC::getTag): 424 (JSC::JSC_DEFINE_HOST_FUNCTION): 425 * wasm/js/WebAssemblyExceptionPrototype.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h. 426 * wasm/js/WebAssemblyFunction.cpp: 427 (JSC::JSC_DEFINE_HOST_FUNCTION): 428 * wasm/js/WebAssemblyModuleRecord.cpp: 429 (JSC::WebAssemblyModuleRecord::linkImpl): 430 * wasm/js/WebAssemblyTagConstructor.cpp: Added. 431 (JSC::JSC_DEFINE_HOST_FUNCTION): 432 (JSC::WebAssemblyTagConstructor::createTag): 433 (JSC::WebAssemblyTagConstructor::create): 434 (JSC::WebAssemblyTagConstructor::createStructure): 435 (JSC::WebAssemblyTagConstructor::finishCreation): 436 (JSC::WebAssemblyTagConstructor::WebAssemblyTagConstructor): 437 * wasm/js/WebAssemblyTagConstructor.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h. 438 * wasm/js/WebAssemblyTagPrototype.cpp: Added. 439 (JSC::WebAssemblyTagPrototype::create): 440 (JSC::WebAssemblyTagPrototype::createStructure): 441 (JSC::WebAssemblyTagPrototype::finishCreation): 442 (JSC::WebAssemblyTagPrototype::WebAssemblyTagPrototype): 443 (JSC::getTag): 444 (JSC::JSC_DEFINE_HOST_FUNCTION): 445 * wasm/js/WebAssemblyTagPrototype.h: Copied from Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h. 446 * wasm/wasm.json: 447 1 448 2021-10-08 Jer Noble <jer.noble@apple.com> 2 449 -
trunk/Source/JavaScriptCore/DerivedSources-input.xcfilelist
r282125 r283852 198 198 $(PROJECT_DIR)/wasm/js/WebAssemblyCompileErrorConstructor.cpp 199 199 $(PROJECT_DIR)/wasm/js/WebAssemblyCompileErrorPrototype.cpp 200 $(PROJECT_DIR)/wasm/js/WebAssemblyExceptionConstructor.cpp 201 $(PROJECT_DIR)/wasm/js/WebAssemblyExceptionPrototype.cpp 200 202 $(PROJECT_DIR)/wasm/js/WebAssemblyGlobalConstructor.cpp 201 203 $(PROJECT_DIR)/wasm/js/WebAssemblyGlobalPrototype.cpp … … 212 214 $(PROJECT_DIR)/wasm/js/WebAssemblyTableConstructor.cpp 213 215 $(PROJECT_DIR)/wasm/js/WebAssemblyTablePrototype.cpp 216 $(PROJECT_DIR)/wasm/js/WebAssemblyTagConstructor.cpp 217 $(PROJECT_DIR)/wasm/js/WebAssemblyTagPrototype.cpp 214 218 $(PROJECT_DIR)/wasm/wasm.json 215 219 $(PROJECT_DIR)/yarr/create_regex_tables -
trunk/Source/JavaScriptCore/DerivedSources-output.xcfilelist
r282125 r283852 83 83 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyCompileErrorConstructor.lut.h 84 84 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyCompileErrorPrototype.lut.h 85 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyExceptionConstructor.lut.h 86 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyExceptionPrototype.lut.h 85 87 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyGlobalConstructor.lut.h 86 88 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyGlobalPrototype.lut.h … … 97 99 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyTableConstructor.lut.h 98 100 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyTablePrototype.lut.h 101 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyTagConstructor.lut.h 102 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/WebAssemblyTagPrototype.lut.h 99 103 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/inspector/InspectorAlternateBackendDispatchers.h 100 104 $(BUILT_PRODUCTS_DIR)/DerivedSources/JavaScriptCore/inspector/InspectorBackendCommands.js -
trunk/Source/JavaScriptCore/DerivedSources.make
r282125 r283852 204 204 WebAssemblyCompileErrorConstructor.lut.h \ 205 205 WebAssemblyCompileErrorPrototype.lut.h \ 206 WebAssemblyExceptionConstructor.lut.h \ 207 WebAssemblyExceptionPrototype.lut.h \ 206 208 WebAssemblyGlobalConstructor.lut.h \ 207 209 WebAssemblyGlobalPrototype.lut.h \ … … 218 220 WebAssemblyTableConstructor.lut.h \ 219 221 WebAssemblyTablePrototype.lut.h \ 222 WebAssemblyTagConstructor.lut.h \ 223 WebAssemblyTagPrototype.lut.h \ 220 224 # 221 225 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r283851 r283852 664 664 0FEC85421BDACDAC0080FF74 /* B3Validate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84F81BDACDAC0080FF74 /* B3Validate.h */; }; 665 665 0FEC85441BDACDAC0080FF74 /* B3Value.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FA1BDACDAC0080FF74 /* B3Value.h */; }; 666 0FEC85471BDACDAC0080FF74 /* B3ValueRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FD1BDACDAC0080FF74 /* B3ValueRep.h */; };666 0FEC85471BDACDAC0080FF74 /* B3ValueRep.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC84FD1BDACDAC0080FF74 /* B3ValueRep.h */; settings = {ATTRIBUTES = (Private, ); }; }; 667 667 0FEC856E1BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC85491BDACDC70080FF74 /* AirAllocateStackByGraphColoring.h */; }; 668 668 0FEC85701BDACDC70080FF74 /* AirArg.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC854B1BDACDC70080FF74 /* AirArg.h */; }; … … 797 797 147B83AC0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B83AA0E6DB8C9004775A4 /* BatchedTransitionOptimizer.h */; settings = {ATTRIBUTES = (Private, ); }; }; 798 798 147B84630E6DE6B1004775A4 /* PutPropertySlot.h in Headers */ = {isa = PBXBuildFile; fileRef = 147B84620E6DE6B1004775A4 /* PutPropertySlot.h */; settings = {ATTRIBUTES = (Private, ); }; }; 799 148521D826EAEBFE00CC1D1A /* WasmHandlerInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 148521D726EAEBFE00CC1D1A /* WasmHandlerInfo.h */; settings = {ATTRIBUTES = (Private, ); }; }; 799 800 1486A8C024ABED480073922D /* JSLockRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1486A8BF24ABED3C0073922D /* JSLockRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; }; 800 801 14874AE615EBDE4A002E3587 /* JSScope.h in Headers */ = {isa = PBXBuildFile; fileRef = 14874AE215EBDE4A002E3587 /* JSScope.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 828 829 14CA958D16AB50FA00938A06 /* ObjectAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 14CA958C16AB50FA00938A06 /* ObjectAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; }; 829 830 14D01A7721FB351F00BC54E9 /* JSScriptSourceProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01A7621FB350300BC54E9 /* JSScriptSourceProvider.h */; }; 831 14D01BE626DEEF3800CAE0D0 /* WebAssemblyTagConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01BDA26DEEF3700CAE0D0 /* WebAssemblyTagConstructor.h */; }; 832 14D01BE726DEEF3800CAE0D0 /* WebAssemblyTagPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01BDB26DEEF3700CAE0D0 /* WebAssemblyTagPrototype.h */; }; 833 14D01BE926DEEF3800CAE0D0 /* WebAssemblyExceptionPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01BDD26DEEF3700CAE0D0 /* WebAssemblyExceptionPrototype.h */; }; 834 14D01BEC26DEEF3800CAE0D0 /* JSWebAssemblyTag.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01BE026DEEF3700CAE0D0 /* JSWebAssemblyTag.h */; }; 835 14D01BED26DEEF3800CAE0D0 /* JSWebAssemblyException.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01BE126DEEF3800CAE0D0 /* JSWebAssemblyException.h */; }; 836 14D01BEF26DEEF3800CAE0D0 /* WebAssemblyExceptionConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01BE326DEEF3800CAE0D0 /* WebAssemblyExceptionConstructor.h */; }; 837 14D01BF526DEEF5300CAE0D0 /* WasmTag.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D01BF326DEEF5200CAE0D0 /* WasmTag.h */; }; 830 838 14D2F3DB139F4BE200491031 /* MarkedSpace.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D2F3D9139F4BE200491031 /* MarkedSpace.h */; settings = {ATTRIBUTES = (Private, ); }; }; 831 839 14DF04DA16B3996D0016A513 /* StaticPropertyAnalysis.h in Headers */ = {isa = PBXBuildFile; fileRef = 14DF04D916B3996D0016A513 /* StaticPropertyAnalysis.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 1265 1273 86281EF425B61AF000367004 /* CheckPrivateBrandStatus.h in Headers */ = {isa = PBXBuildFile; fileRef = 86281EF325B61AF000367004 /* CheckPrivateBrandStatus.h */; }; 1266 1274 863B23E00FC6118900703AA4 /* MacroAssemblerCodeRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 863B23DF0FC60E6200703AA4 /* MacroAssemblerCodeRef.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1267 863FBC5A25B093B900F6C930 /* WasmValueLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 863FBC5825B093B900F6C930 /* WasmValueLocation.h */; };1275 863FBC5A25B093B900F6C930 /* WasmValueLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 863FBC5825B093B900F6C930 /* WasmValueLocation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1268 1276 865A30F1135007E100CDB49E /* JSCJSValueInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 865A30F0135007E100CDB49E /* JSCJSValueInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1269 1277 865DA0C525B8957400875772 /* SetPrivateBrandVariant.h in Headers */ = {isa = PBXBuildFile; fileRef = 865DA0C425B8957400875772 /* SetPrivateBrandVariant.h */; }; … … 1940 1948 E3BFD0BC1DAF808E0065DEA2 /* AccessCaseSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BFD0BA1DAF807C0065DEA2 /* AccessCaseSnippetParams.h */; }; 1941 1949 E3C295DD1ED2CBDA00D3016F /* ObjectPropertyChangeAdaptiveWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C295DC1ED2CBAA00D3016F /* ObjectPropertyChangeAdaptiveWatchpoint.h */; }; 1942 E3C694B323026877006FBE42 /* WasmOSREntryData.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C694B123026873006FBE42 /* WasmOSREntryData.h */; };1950 E3C694B323026877006FBE42 /* WasmOSREntryData.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C694B123026873006FBE42 /* WasmOSREntryData.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1943 1951 E3C73A9125BFA73B00EFE303 /* WasmStreamingPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C73A9025BFA73400EFE303 /* WasmStreamingPlan.h */; }; 1944 1952 E3C79CAB1DB9A4DC00D1ECA4 /* DOMJITEffect.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C79CAA1DB9A4D600D1ECA4 /* DOMJITEffect.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 3464 3472 1482B7E10A43076000517CFC /* JSObjectRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSObjectRef.h; sourceTree = "<group>"; }; 3465 3473 1482B7E20A43076000517CFC /* JSObjectRef.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSObjectRef.cpp; sourceTree = "<group>"; }; 3474 148521D526EAEBDF00CC1D1A /* WasmHandlerInfo.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = WasmHandlerInfo.cpp; sourceTree = "<group>"; }; 3475 148521D726EAEBFE00CC1D1A /* WasmHandlerInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmHandlerInfo.h; sourceTree = "<group>"; }; 3466 3476 1486A8BE24ABED3B0073922D /* JSLockRef.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSLockRef.cpp; sourceTree = "<group>"; }; 3467 3477 1486A8BF24ABED3C0073922D /* JSLockRefPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSLockRefPrivate.h; sourceTree = "<group>"; }; … … 3547 3557 14D01A7521FB350300BC54E9 /* JSScriptSourceProvider.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = JSScriptSourceProvider.mm; sourceTree = "<group>"; }; 3548 3558 14D01A7621FB350300BC54E9 /* JSScriptSourceProvider.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSScriptSourceProvider.h; sourceTree = "<group>"; }; 3559 14D01BDA26DEEF3700CAE0D0 /* WebAssemblyTagConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyTagConstructor.h; path = js/WebAssemblyTagConstructor.h; sourceTree = "<group>"; }; 3560 14D01BDB26DEEF3700CAE0D0 /* WebAssemblyTagPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyTagPrototype.h; path = js/WebAssemblyTagPrototype.h; sourceTree = "<group>"; }; 3561 14D01BDC26DEEF3700CAE0D0 /* JSWebAssemblyException.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyException.cpp; path = js/JSWebAssemblyException.cpp; sourceTree = "<group>"; }; 3562 14D01BDD26DEEF3700CAE0D0 /* WebAssemblyExceptionPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyExceptionPrototype.h; path = js/WebAssemblyExceptionPrototype.h; sourceTree = "<group>"; }; 3563 14D01BDE26DEEF3700CAE0D0 /* WebAssemblyTagConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyTagConstructor.cpp; path = js/WebAssemblyTagConstructor.cpp; sourceTree = "<group>"; }; 3564 14D01BDF26DEEF3700CAE0D0 /* WebAssemblyTagPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyTagPrototype.cpp; path = js/WebAssemblyTagPrototype.cpp; sourceTree = "<group>"; }; 3565 14D01BE026DEEF3700CAE0D0 /* JSWebAssemblyTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyTag.h; path = js/JSWebAssemblyTag.h; sourceTree = "<group>"; }; 3566 14D01BE126DEEF3800CAE0D0 /* JSWebAssemblyException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyException.h; path = js/JSWebAssemblyException.h; sourceTree = "<group>"; }; 3567 14D01BE226DEEF3800CAE0D0 /* WebAssemblyExceptionPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyExceptionPrototype.cpp; path = js/WebAssemblyExceptionPrototype.cpp; sourceTree = "<group>"; }; 3568 14D01BE326DEEF3800CAE0D0 /* WebAssemblyExceptionConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyExceptionConstructor.h; path = js/WebAssemblyExceptionConstructor.h; sourceTree = "<group>"; }; 3569 14D01BE426DEEF3800CAE0D0 /* JSWebAssemblyTag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyTag.cpp; path = js/JSWebAssemblyTag.cpp; sourceTree = "<group>"; }; 3570 14D01BE526DEEF3800CAE0D0 /* WebAssemblyExceptionConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyExceptionConstructor.cpp; path = js/WebAssemblyExceptionConstructor.cpp; sourceTree = "<group>"; }; 3571 14D01BF226DEEF5200CAE0D0 /* WasmTag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmTag.cpp; sourceTree = "<group>"; }; 3572 14D01BF326DEEF5200CAE0D0 /* WasmTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmTag.h; sourceTree = "<group>"; }; 3549 3573 14D2F3D9139F4BE200491031 /* MarkedSpace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarkedSpace.h; sourceTree = "<group>"; }; 3550 3574 14D792640DAA03FB001A9F05 /* CLoopStack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CLoopStack.h; sourceTree = "<group>"; }; … … 7162 7186 E38350082390D9370036316D /* WasmGlobal.cpp */, 7163 7187 E38350092390D9370036316D /* WasmGlobal.h */, 7188 148521D526EAEBDF00CC1D1A /* WasmHandlerInfo.cpp */, 7189 148521D726EAEBFE00CC1D1A /* WasmHandlerInfo.h */, 7164 7190 AD8FF3961EB5BD850087FF82 /* WasmIndexOrName.cpp */, 7165 7191 AD8FF3951EB5BD850087FF82 /* WasmIndexOrName.h */, … … 7219 7245 AD5C36E31F69EC8B000BCAAF /* WasmTable.cpp */, 7220 7246 AD5C36E41F69EC8B000BCAAF /* WasmTable.h */, 7247 14D01BF226DEEF5200CAE0D0 /* WasmTag.cpp */, 7248 14D01BF326DEEF5200CAE0D0 /* WasmTag.h */, 7221 7249 5250D2CF1E8DA05A0029A932 /* WasmThunks.cpp */, 7222 7250 5250D2D01E8DA05A0029A932 /* WasmThunks.h */, … … 9104 9132 AD2FCBA61DB58DA400B3E736 /* JSWebAssemblyCompileError.cpp */, 9105 9133 AD2FCBA71DB58DA400B3E736 /* JSWebAssemblyCompileError.h */, 9134 14D01BDC26DEEF3700CAE0D0 /* JSWebAssemblyException.cpp */, 9135 14D01BE126DEEF3800CAE0D0 /* JSWebAssemblyException.h */, 9106 9136 E3BF3C4C2390D1E3008BC752 /* JSWebAssemblyGlobal.cpp */, 9107 9137 E3BF3C4B2390D1E2008BC752 /* JSWebAssemblyGlobal.h */, … … 9119 9149 AD2FCBAE1DB58DA400B3E736 /* JSWebAssemblyTable.cpp */, 9120 9150 AD2FCBAF1DB58DA400B3E736 /* JSWebAssemblyTable.h */, 9151 14D01BE426DEEF3800CAE0D0 /* JSWebAssemblyTag.cpp */, 9152 14D01BE026DEEF3700CAE0D0 /* JSWebAssemblyTag.h */, 9121 9153 ADD09AEF1F5F623F001313C2 /* WasmToJS.cpp */, 9122 9154 ADD09AEE1F5F623F001313C2 /* WasmToJS.h */, … … 9125 9157 AD2FCBB21DB58DA400B3E736 /* WebAssemblyCompileErrorPrototype.cpp */, 9126 9158 AD2FCBB31DB58DA400B3E736 /* WebAssemblyCompileErrorPrototype.h */, 9159 14D01BE526DEEF3800CAE0D0 /* WebAssemblyExceptionConstructor.cpp */, 9160 14D01BE326DEEF3800CAE0D0 /* WebAssemblyExceptionConstructor.h */, 9161 14D01BE226DEEF3800CAE0D0 /* WebAssemblyExceptionPrototype.cpp */, 9162 14D01BDD26DEEF3700CAE0D0 /* WebAssemblyExceptionPrototype.h */, 9127 9163 AD4937C91DDD27340077C807 /* WebAssemblyFunction.cpp */, 9128 9164 AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */, … … 9159 9195 AD2FCBC21DB58DA400B3E736 /* WebAssemblyTablePrototype.cpp */, 9160 9196 AD2FCBC31DB58DA400B3E736 /* WebAssemblyTablePrototype.h */, 9197 14D01BDE26DEEF3700CAE0D0 /* WebAssemblyTagConstructor.cpp */, 9198 14D01BDA26DEEF3700CAE0D0 /* WebAssemblyTagConstructor.h */, 9199 14D01BDF26DEEF3700CAE0D0 /* WebAssemblyTagPrototype.cpp */, 9200 14D01BDB26DEEF3700CAE0D0 /* WebAssemblyTagPrototype.h */, 9161 9201 52F6C35B1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp */, 9162 9202 52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */, … … 10410 10450 AD9E852F1E8A0C7C008DE39E /* JSWebAssemblyCodeBlock.h in Headers */, 10411 10451 AD2FCBE31DB58DAD00B3E736 /* JSWebAssemblyCompileError.h in Headers */, 10452 14D01BED26DEEF3800CAE0D0 /* JSWebAssemblyException.h in Headers */, 10412 10453 E3BF3C4D2390D1E8008BC752 /* JSWebAssemblyGlobal.h in Headers */, 10413 10454 796FB43A1DFF8C3F0039C95D /* JSWebAssemblyHelpers.h in Headers */, … … 10418 10459 AD2FCBE91DB58DAD00B3E736 /* JSWebAssemblyRuntimeError.h in Headers */, 10419 10460 AD2FCBEB1DB58DAD00B3E736 /* JSWebAssemblyTable.h in Headers */, 10461 14D01BEC26DEEF3800CAE0D0 /* JSWebAssemblyTag.h in Headers */, 10420 10462 1442566215EDE98D0066A49B /* JSWithScope.h in Headers */, 10421 10463 86E3C619167BABEE006D760A /* JSWrapperMap.h in Headers */, … … 10846 10888 53F40E8B1D5901BB0099A1B6 /* WasmFunctionParser.h in Headers */, 10847 10889 E383500A2390D93B0036316D /* WasmGlobal.h in Headers */, 10890 148521D826EAEBFE00CC1D1A /* WasmHandlerInfo.h in Headers */, 10848 10891 AD8FF3981EB5BDB20087FF82 /* WasmIndexOrName.h in Headers */, 10849 10892 AD5C36E21F699EC0000BCAAF /* WasmInstance.h in Headers */, … … 10876 10919 E3C73A9125BFA73B00EFE303 /* WasmStreamingPlan.h in Headers */, 10877 10920 AD5C36E61F69EC91000BCAAF /* WasmTable.h in Headers */, 10921 14D01BF526DEEF5300CAE0D0 /* WasmTag.h in Headers */, 10878 10922 5250D2D21E8DA05A0029A932 /* WasmThunks.h in Headers */, 10879 10923 53E9E0AF1EAEC45700FEE251 /* WasmTierUpCount.h in Headers */, … … 10907 10951 AD2FCBEF1DB58DAD00B3E736 /* WebAssemblyCompileErrorPrototype.h in Headers */, 10908 10952 AD2FCC171DB59CB200B3E736 /* WebAssemblyCompileErrorPrototype.lut.h in Headers */, 10953 14D01BEF26DEEF3800CAE0D0 /* WebAssemblyExceptionConstructor.h in Headers */, 10954 14D01BE926DEEF3800CAE0D0 /* WebAssemblyExceptionPrototype.h in Headers */, 10909 10955 AD4937D41DDD27DE0077C807 /* WebAssemblyFunction.h in Headers */, 10910 10956 521322461ECBCE8200F65615 /* WebAssemblyFunctionBase.h in Headers */, … … 10934 10980 AD2FCBFF1DB58DAD00B3E736 /* WebAssemblyTablePrototype.h in Headers */, 10935 10981 AD2FCC211DB59CB200B3E736 /* WebAssemblyTablePrototype.lut.h in Headers */, 10982 14D01BE626DEEF3800CAE0D0 /* WebAssemblyTagConstructor.h in Headers */, 10983 14D01BE726DEEF3800CAE0D0 /* WebAssemblyTagPrototype.h in Headers */, 10936 10984 52F6C35E1E71EB080081F4CC /* WebAssemblyWrapperFunction.h in Headers */, 10937 10985 BC18C47A0E16F5CD00B34460 /* WebKitAvailability.h in Headers */, -
trunk/Source/JavaScriptCore/Sources.txt
r283139 r283852 1080 1080 wasm/WasmFunctionCodeBlock.cpp 1081 1081 wasm/WasmGlobal.cpp 1082 wasm/WasmHandlerInfo.cpp 1082 1083 wasm/WasmIndexOrName.cpp 1083 1084 wasm/WasmInstance.cpp … … 1106 1107 wasm/WasmStreamingPlan.cpp 1107 1108 wasm/WasmTable.cpp 1109 wasm/WasmTag.cpp 1108 1110 wasm/WasmThunks.cpp 1109 1111 wasm/WasmTierUpCount.cpp … … 1117 1119 wasm/js/JSWebAssemblyCodeBlock.cpp 1118 1120 wasm/js/JSWebAssemblyCompileError.cpp 1121 wasm/js/JSWebAssemblyException.cpp 1119 1122 wasm/js/JSWebAssemblyGlobal.cpp 1120 1123 wasm/js/JSWebAssemblyInstance.cpp … … 1124 1127 wasm/js/JSWebAssemblyRuntimeError.cpp 1125 1128 wasm/js/JSWebAssemblyTable.cpp 1129 wasm/js/JSWebAssemblyTag.cpp 1126 1130 wasm/js/WasmToJS.cpp 1127 1131 wasm/js/WasmToJS.h 1128 1132 wasm/js/WebAssemblyCompileErrorConstructor.cpp 1129 1133 wasm/js/WebAssemblyCompileErrorPrototype.cpp 1134 wasm/js/WebAssemblyExceptionConstructor.cpp 1135 wasm/js/WebAssemblyExceptionPrototype.cpp 1130 1136 wasm/js/WebAssemblyFunction.cpp 1131 1137 wasm/js/WebAssemblyFunctionBase.cpp … … 1145 1151 wasm/js/WebAssemblyTableConstructor.cpp 1146 1152 wasm/js/WebAssemblyTablePrototype.cpp 1153 wasm/js/WebAssemblyTagConstructor.cpp 1154 wasm/js/WebAssemblyTagPrototype.cpp 1147 1155 wasm/js/WebAssemblyWrapperFunction.cpp 1148 1156 -
trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb
r283168 r283852 1840 1840 } 1841 1841 1842 op :throw, 1843 args: { 1844 exceptionIndex: unsigned, 1845 firstValue: VirtualRegister, 1846 } 1847 1848 op :rethrow, 1849 args: { 1850 exception: VirtualRegister, 1851 } 1852 1853 op_group :Catch, 1854 [ 1855 :catch, 1856 :catch_no_tls, 1857 ], 1858 args: { 1859 exceptionIndex: unsigned, 1860 exception: VirtualRegister, 1861 argumentCount: unsigned, 1862 startOffset: unsigned, 1863 } 1864 1865 op_group :CatchAll, 1866 [ 1867 :catch_all, 1868 :catch_all_no_tls, 1869 ], 1870 args: { 1871 exception: VirtualRegister, 1872 } 1873 1842 1874 end_section :Wasm -
trunk/Source/JavaScriptCore/bytecode/HandlerInfo.h
r255687 r283852 31 31 namespace JSC { 32 32 33 enum class HandlerType {33 enum class HandlerType : uint8_t { 34 34 Catch = 0, 35 35 Finally = 1, -
trunk/Source/JavaScriptCore/bytecode/Instruction.h
r281694 r283852 90 90 const char* name() const 91 91 { 92 return Traits::opcodeNames[opcodeID ()];92 return Traits::opcodeNames[opcodeID<Traits>()]; 93 93 } 94 94 -
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r283410 r283852 131 131 BytecodeIndex CallFrame::bytecodeIndex() const 132 132 { 133 ASSERT(!callee().isWasm()); 133 if (callee().isWasm()) 134 return callSiteIndex().bytecodeIndex(); 134 135 if (!codeBlock()) 135 136 return BytecodeIndex(0); -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r280858 r283852 45 45 public: 46 46 CallSiteIndex() = default; 47 48 CallSiteIndex(WTF::HashTableDeletedValueType) 49 : m_bits(deletedValue().bits()) 50 { 51 } 47 52 48 53 explicit CallSiteIndex(BytecodeIndex bytecodeIndex) … … 58 63 bool operator==(const CallSiteIndex& other) const { return m_bits == other.m_bits; } 59 64 65 unsigned hash() const { return intHash(m_bits); } 66 static CallSiteIndex deletedValue() { return fromBits(s_invalidIndex - 1); } 67 bool isHashTableDeletedValue() const { return *this == deletedValue(); } 68 60 69 uint32_t bits() const { return m_bits; } 61 70 static CallSiteIndex fromBits(uint32_t bits) { return CallSiteIndex(bits); } … … 64 73 65 74 private: 66 uint32_t m_bits { BytecodeIndex().offset() }; 75 static constexpr uint32_t s_invalidIndex = std::numeric_limits<uint32_t>::max(); 76 77 uint32_t m_bits { s_invalidIndex }; 78 }; 79 80 struct CallSiteIndexHash { 81 static unsigned hash(const CallSiteIndex& key) { return key.hash(); } 82 static bool equal(const CallSiteIndex& a, const CallSiteIndex& b) { return a == b; } 83 static constexpr bool safeToCompareToEmptyOrDeleted = true; 67 84 }; 68 85 … … 333 350 334 351 } // namespace JSC 352 353 namespace WTF { 354 355 template<typename T> struct DefaultHash; 356 template<> struct DefaultHash<JSC::CallSiteIndex> : JSC::CallSiteIndexHash { }; 357 358 template<typename T> struct HashTraits; 359 template<> struct HashTraits<JSC::CallSiteIndex> : SimpleClassHashTraits<JSC::CallSiteIndex> { 360 static constexpr bool emptyValueIsZero = false; 361 }; 362 363 } // namespace WTF -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r283566 r283852 53 53 #include "JSModuleRecord.h" 54 54 #include "JSString.h" 55 #include "JSWebAssemblyException.h" 55 56 #include "LLIntThunks.h" 56 57 #include "LiteralParser.h" … … 513 514 } 514 515 516 CatchInfo::CatchInfo(const HandlerInfo* handler, CodeBlock* codeBlock) 517 { 518 m_valid = !!handler; 519 if (m_valid) { 520 m_type = handler->type(); 521 #if ENABLE(JIT) 522 m_nativeCode = handler->nativeCode; 523 #endif 524 525 // handler->target is meaningless for getting a code offset when catching 526 // the exception in a DFG/FTL frame. This bytecode target offset could be 527 // something that's in an inlined frame, which means an array access 528 // with this bytecode offset in the machine frame is utterly meaningless 529 // and can cause an overflow. OSR exit properly exits to handler->target 530 // in the proper frame. 531 if (!JITCode::isOptimizingJIT(codeBlock->jitType())) 532 m_catchPCForInterpreter = codeBlock->instructions().at(handler->target).ptr(); 533 else 534 m_catchPCForInterpreter = nullptr; 535 } 536 } 537 538 #if ENABLE(WEBASSEMBLY) 539 CatchInfo::CatchInfo(const Wasm::HandlerInfo* handler, const Wasm::Callee* callee) 540 { 541 m_valid = !!handler; 542 if (m_valid) { 543 m_type = HandlerType::Catch; 544 m_nativeCode = handler->m_nativeCode; 545 if (const Wasm::FunctionCodeBlock* codeBlock = callee->functionCodeBlock()) 546 m_catchPCForInterpreter = codeBlock->instructions().at(handler->m_target).ptr(); 547 else 548 m_catchPCForInterpreter = nullptr; 549 } 550 } 551 #endif 552 515 553 class UnwindFunctor { 516 554 public: 517 UnwindFunctor(VM& vm, CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler)555 UnwindFunctor(VM& vm, CallFrame*& callFrame, bool isTermination, JSValue thrownValue, CodeBlock*& codeBlock, CatchInfo& handler) 518 556 : m_vm(vm) 519 557 , m_callFrame(callFrame) … … 522 560 , m_handler(handler) 523 561 { 562 #if ENABLE(WEBASSEMBLY) 563 if (!m_isTermination) { 564 if (JSWebAssemblyException* wasmException = jsDynamicCast<JSWebAssemblyException*>(m_vm, thrownValue)) { 565 m_catchableFromWasm = true; 566 m_wasmTag = &wasmException->tag(); 567 } else if (ErrorInstance* error = jsDynamicCast<ErrorInstance*>(m_vm, thrownValue)) 568 m_catchableFromWasm = error->isCatchableFromWasm(); 569 } 570 #else 571 UNUSED_PARAM(thrownValue); 572 #endif 524 573 } 525 574 … … 530 579 m_codeBlock = visitor->codeBlock(); 531 580 532 m_handler = nullptr;581 m_handler.m_valid = false; 533 582 if (m_codeBlock) { 534 583 if (!m_isTermination) { 535 m_handler = findExceptionHandler(visitor, m_codeBlock, RequiredHandler::AnyHandler);536 if (m_handler )584 m_handler = { findExceptionHandler(visitor, m_codeBlock, RequiredHandler::AnyHandler), m_codeBlock }; 585 if (m_handler.m_valid) 537 586 return StackVisitor::Done; 538 587 } … … 540 589 541 590 #if ENABLE(WEBASSEMBLY) 542 if (visitor->callee().isCell()) { 543 if (auto* jsToWasmICCallee = jsDynamicCast<JSToWasmICCallee*>(m_vm, visitor->callee().asCell())) 591 CalleeBits callee = visitor->callee(); 592 if (callee.isCell()) { 593 if (auto* jsToWasmICCallee = jsDynamicCast<JSToWasmICCallee*>(m_vm, callee.asCell())) 544 594 m_vm.wasmContext.store(jsToWasmICCallee->function()->previousInstance(m_callFrame), m_vm.softStackLimit()); 595 596 } 597 598 if (m_catchableFromWasm && callee.isWasm()) { 599 Wasm::Callee* wasmCallee = callee.asWasmCallee(); 600 if (wasmCallee->hasExceptionHandlers()) { 601 JSWebAssemblyInstance* jsInstance = jsCast<JSWebAssemblyInstance*>(m_callFrame->thisValue()); 602 unsigned exceptionHandlerIndex = m_callFrame->callSiteIndex().bits(); 603 m_handler = { wasmCallee->handlerForIndex(jsInstance->instance(), exceptionHandlerIndex, m_wasmTag), wasmCallee }; 604 if (m_handler.m_valid) 605 return StackVisitor::Done; 606 } 545 607 } 546 608 #endif … … 589 651 bool m_isTermination; 590 652 CodeBlock*& m_codeBlock; 591 HandlerInfo*& m_handler; 653 CatchInfo& m_handler; 654 #if ENABLE(WEBASSEMBLY) 655 const Wasm::Tag* m_wasmTag { nullptr }; 656 bool m_catchableFromWasm { false }; 657 #endif 592 658 }; 593 659 594 NEVER_INLINE HandlerInfo*Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exception* exception)660 NEVER_INLINE CatchInfo Interpreter::unwind(VM& vm, CallFrame*& callFrame, Exception* exception) 595 661 { 596 662 auto scope = DECLARE_CATCH_SCOPE(vm); … … 610 676 611 677 // Calculate an exception handler vPC, unwinding call frames as necessary. 612 HandlerInfo* handler = nullptr;613 UnwindFunctor functor(vm, callFrame, vm.isTerminationException(exception), codeBlock, handler);678 CatchInfo catchInfo; 679 UnwindFunctor functor(vm, callFrame, vm.isTerminationException(exception), exceptionValue, codeBlock, catchInfo); 614 680 StackVisitor::visit<StackVisitor::TerminateIfTopEntryFrameIsEmpty>(callFrame, vm, functor); 615 681 if (vm.hasCheckpointOSRSideState()) 616 682 vm.popAllCheckpointOSRSideStateUntil(callFrame); 617 683 618 if (!handler) 619 return nullptr; 620 621 return handler; 684 return catchInfo; 622 685 } 623 686 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r273225 r283852 44 44 namespace JSC { 45 45 46 #if ENABLE(WEBASSEMBLY) 47 namespace Wasm { 48 class Callee; 49 struct HandlerInfo; 50 } 51 #endif 52 46 53 class CodeBlock; 47 54 class EvalExecutable; … … 59 66 class SourceCode; 60 67 class StackFrame; 68 enum class HandlerType : uint8_t; 61 69 struct CallFrameClosure; 62 70 struct HandlerInfo; … … 82 90 }; 83 91 92 struct CatchInfo { 93 CatchInfo() 94 : m_valid(false) 95 { } 96 97 CatchInfo(const HandlerInfo*, CodeBlock*); 98 #if ENABLE(WEBASSEMBLY) 99 CatchInfo(const Wasm::HandlerInfo*, const Wasm::Callee*); 100 #endif 101 102 bool m_valid; 103 HandlerType m_type; 104 #if ENABLE(JIT) 105 MacroAssemblerCodePtr<ExceptionHandlerPtrTag> m_nativeCode; 106 #endif 107 const Instruction* m_catchPCForInterpreter; 108 }; 109 84 110 class Interpreter { 85 111 WTF_MAKE_FAST_ALLOCATED; … … 113 139 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc); 114 140 115 NEVER_INLINE HandlerInfo*unwind(VM&, CallFrame*&, Exception*);141 NEVER_INLINE CatchInfo unwind(VM&, CallFrame*&, Exception*); 116 142 void notifyDebuggerOfExceptionToBeThrown(VM&, JSGlobalObject*, CallFrame*, Exception*); 117 143 NEVER_INLINE void debug(CallFrame*, DebugHookType); -
trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp
r278253 r283852 167 167 #endif 168 168 169 m_frame.m_codeBlock = callFrame->codeBlock(); 170 m_frame.m_bytecodeIndex = !m_frame.codeBlock() ? BytecodeIndex(0) 171 : codeOrigin ? codeOrigin->bytecodeIndex() 172 : callFrame->bytecodeIndex(); 173 169 174 #if ENABLE(WEBASSEMBLY) 170 175 if (callFrame->isAnyWasmCallee()) { 171 176 m_frame.m_isWasmFrame = true; 172 177 m_frame.m_codeBlock = nullptr; 173 m_frame.m_bytecodeIndex = BytecodeIndex();174 178 175 179 if (m_frame.m_callee.isWasm()) 176 180 m_frame.m_wasmFunctionIndexOrName = m_frame.m_callee.asWasmCallee()->indexOrName(); 177 178 return; 179 } 180 #endif 181 m_frame.m_codeBlock = callFrame->codeBlock(); 182 m_frame.m_bytecodeIndex = !m_frame.codeBlock() ? BytecodeIndex(0) 183 : codeOrigin ? codeOrigin->bytecodeIndex() 184 : callFrame->bytecodeIndex(); 185 181 } 182 #endif 186 183 } 187 184 -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.cpp
r283512 r283852 705 705 706 706 loadPtr(&topEntryFrame, scratch); 707 addPtr(TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), scratch); 708 709 LoadRegSpooler spooler(*this, scratch); 710 711 // Restore all callee saves except for the scratch. 712 unsigned i = 0; 713 for (; i < registerCount; i++) { 714 RegisterAtOffset entry = allCalleeSaves->at(i); 715 if (skipList.contains(entry.reg())) 716 continue; 717 if (!entry.reg().isGPR()) 718 break; 719 spooler.loadGPR(entry); 720 } 721 spooler.finalizeGPR(); 722 for (; i < registerCount; i++) { 723 RegisterAtOffset entry = allCalleeSaves->at(i); 724 if (skipList.contains(entry.reg())) 725 continue; 726 ASSERT(!entry.reg().isGPR()); 727 spooler.loadFPR(entry); 728 } 729 spooler.finalizeFPR(); 707 restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl(scratch, skipList); 730 708 731 709 // Restore the callee save value of the scratch. … … 746 724 #else 747 725 UNUSED_PARAM(topEntryFrame); 726 #endif // NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 727 } 728 729 void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(GPRReg vmGPR, GPRReg scratchGPR) 730 { 731 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 732 loadPtr(Address(vmGPR, VM::topEntryFrameOffset()), scratchGPR); 733 restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl(scratchGPR, RegisterSet::stackRegisters()); 734 #else 735 UNUSED_PARAM(vmGPR); 736 #endif // NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 737 } 738 739 void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl(GPRReg entryFrameGPR, const RegisterSet& skipList) 740 { 741 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 742 addPtr(TrustedImm32(EntryFrame::calleeSaveRegistersBufferOffset()), entryFrameGPR); 743 744 RegisterAtOffsetList* allCalleeSaves = RegisterSet::vmCalleeSaveRegisterOffsets(); 745 unsigned registerCount = allCalleeSaves->size(); 746 747 LoadRegSpooler spooler(*this, entryFrameGPR); 748 749 // Restore all callee saves except for the scratch. 750 unsigned i = 0; 751 for (; i < registerCount; i++) { 752 RegisterAtOffset entry = allCalleeSaves->at(i); 753 if (skipList.contains(entry.reg())) 754 continue; 755 if (!entry.reg().isGPR()) 756 break; 757 spooler.loadGPR(entry); 758 } 759 spooler.finalizeGPR(); 760 for (; i < registerCount; i++) { 761 RegisterAtOffset entry = allCalleeSaves->at(i); 762 if (skipList.contains(entry.reg())) 763 continue; 764 ASSERT(!entry.reg().isGPR()); 765 spooler.loadFPR(entry); 766 } 767 spooler.finalizeFPR(); 768 769 #else 770 UNUSED_PARAM(vmGPR); 771 UNUSED_PARAM(skipList); 748 772 #endif // NUMBER_OF_CALLEE_SAVES_REGISTERS > 0 749 773 } -
trunk/Source/JavaScriptCore/jit/AssemblyHelpers.h
r283512 r283852 414 414 415 415 void restoreCalleeSavesFromEntryFrameCalleeSavesBuffer(EntryFrame*&); 416 void restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(GPRReg vmGPR, GPRReg scratchGPR); 417 void restoreCalleeSavesFromVMEntryFrameCalleeSavesBufferImpl(GPRReg entryFrame, const RegisterSet& skipList); 416 418 417 419 void copyLLIntBaselineCalleeSavesFromFrameOrRegisterToEntryFrameCalleeSavesBuffer(EntryFrame*&, const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() }); -
trunk/Source/JavaScriptCore/jit/JITExceptions.cpp
r268247 r283852 55 55 Exception* exception = scope.exception(); 56 56 RELEASE_ASSERT(exception); 57 HandlerInfo*handler = vm.interpreter->unwind(vm, callFrame, exception); // This may update callFrame.57 CatchInfo handler = vm.interpreter->unwind(vm, callFrame, exception); // This may update callFrame. 58 58 59 59 void* catchRoutine; 60 60 const Instruction* catchPCForInterpreter = nullptr; 61 if (handler) { 62 // handler->target is meaningless for getting a code offset when catching 63 // the exception in a DFG/FTL frame. This bytecode target offset could be 64 // something that's in an inlined frame, which means an array access 65 // with this bytecode offset in the machine frame is utterly meaningless 66 // and can cause an overflow. OSR exit properly exits to handler->target 67 // in the proper frame. 68 if (!JITCode::isOptimizingJIT(callFrame->codeBlock()->jitType())) 69 catchPCForInterpreter = callFrame->codeBlock()->instructions().at(handler->target).ptr(); 61 if (handler.m_valid) { 62 catchPCForInterpreter = handler.m_catchPCForInterpreter; 70 63 #if ENABLE(JIT) 71 catchRoutine = handler ->nativeCode.executableAddress();64 catchRoutine = handler.m_nativeCode.executableAddress(); 72 65 #else 73 66 if (catchPCForInterpreter->isWide32()) -
trunk/Source/JavaScriptCore/jit/JSInterfaceJIT.h
r263824 r283852 58 58 void emitPutToCallFrameHeader(void* value, VirtualRegister entry); 59 59 void emitPutCellToCallFrameHeader(RegisterID from, VirtualRegister entry); 60 void convertCalleeToVM(RegisterID callee); 60 61 61 62 VM* vm() const { return m_vm; } … … 159 160 } 160 161 162 ALWAYS_INLINE void JSInterfaceJIT::convertCalleeToVM(RegisterID callee) 163 { 164 auto preciseAllocationCase = branchTestPtr(CCallHelpers::NonZero, callee, CCallHelpers::TrustedImm32(PreciseAllocation::halfAlignment)); 165 andPtr(CCallHelpers::TrustedImmPtr(MarkedBlock::blockMask), callee); 166 loadPtr(CCallHelpers::Address(callee, MarkedBlock::offsetOfFooter + MarkedBlock::Footer::offsetOfVM()), callee); 167 auto loadedCase = jump(); 168 169 preciseAllocationCase.link(this); 170 loadPtr(CCallHelpers::Address(callee, PreciseAllocation::offsetOfWeakSet() + WeakSet::offsetOfVM() - PreciseAllocation::headerSize()), callee); 171 172 loadedCase.link(this); 173 } 174 161 175 } // namespace JSC 162 176 -
trunk/Source/JavaScriptCore/llint/LLIntData.h
r281757 r283852 324 324 325 325 template<PtrTag tag> 326 ALWAYS_INLINE MacroAssemblerCodeRef<tag> getCodeRef(WasmOpcodeID opcodeID) 327 { 328 return MacroAssemblerCodeRef<tag>::createSelfManagedCodeRef(getCodePtr<tag>(opcodeID)); 329 } 330 331 template<PtrTag tag> 332 ALWAYS_INLINE MacroAssemblerCodeRef<tag> getWide16CodeRef(WasmOpcodeID opcodeID) 333 { 334 return MacroAssemblerCodeRef<tag>::createSelfManagedCodeRef(getWide16CodePtr<tag>(opcodeID)); 335 } 336 337 template<PtrTag tag> 338 ALWAYS_INLINE MacroAssemblerCodeRef<tag> getWide32CodeRef(WasmOpcodeID opcodeID) 339 { 340 return MacroAssemblerCodeRef<tag>::createSelfManagedCodeRef(getWide32CodePtr<tag>(opcodeID)); 341 } 342 343 template<PtrTag tag> 326 344 ALWAYS_INLINE LLIntCode getCodeFunctionPtr(WasmOpcodeID opcodeID) 327 345 { -
trunk/Source/JavaScriptCore/llint/LLIntExceptions.cpp
r268485 r283852 30 30 #include "LLIntData.h" 31 31 #include "LLIntThunks.h" 32 #include "WasmContext.h" 32 33 33 34 #if LLINT_TRACING … … 48 49 #endif 49 50 return LLInt::exceptionInstructions(); 51 } 52 53 Instruction* wasmReturnToThrow(VM& vm) 54 { 55 UNUSED_PARAM(vm); 56 #if LLINT_TRACING 57 if (UNLIKELY(Options::traceLLIntSlowPath())) { 58 auto scope = DECLARE_CATCH_SCOPE(vm); 59 dataLog("Throwing exception ", JSValue(scope.exception()), " (returnToThrow).\n"); 60 } 61 #endif 62 return LLInt::wasmExceptionInstructions(); 50 63 } 51 64 … … 93 106 } 94 107 108 #if ENABLE(WEBASSEMBLY) 109 MacroAssemblerCodeRef<ExceptionHandlerPtrTag> handleWasmCatch(OpcodeSize size) 110 { 111 WasmOpcodeID opcode = Wasm::Context::useFastTLS() ? wasm_catch : wasm_catch_no_tls; 112 switch (size) { 113 case OpcodeSize::Narrow: 114 return LLInt::getCodeRef<ExceptionHandlerPtrTag>(opcode); 115 case OpcodeSize::Wide16: 116 return LLInt::getWide16CodeRef<ExceptionHandlerPtrTag>(opcode); 117 case OpcodeSize::Wide32: 118 return LLInt::getWide32CodeRef<ExceptionHandlerPtrTag>(opcode); 119 } 120 RELEASE_ASSERT_NOT_REACHED(); 121 return { }; 122 } 123 124 MacroAssemblerCodeRef<ExceptionHandlerPtrTag> handleWasmCatchAll(OpcodeSize size) 125 { 126 WasmOpcodeID opcode = Wasm::Context::useFastTLS() ? wasm_catch_all : wasm_catch_all_no_tls; 127 switch (size) { 128 case OpcodeSize::Narrow: 129 return LLInt::getCodeRef<ExceptionHandlerPtrTag>(opcode); 130 case OpcodeSize::Wide16: 131 return LLInt::getWide16CodeRef<ExceptionHandlerPtrTag>(opcode); 132 case OpcodeSize::Wide32: 133 return LLInt::getWide32CodeRef<ExceptionHandlerPtrTag>(opcode); 134 } 135 RELEASE_ASSERT_NOT_REACHED(); 136 return { }; 137 } 138 #endif // ENABLE(WEBASSEMBLY) 139 95 140 } } // namespace JSC::LLInt -
trunk/Source/JavaScriptCore/llint/LLIntExceptions.h
r268485 r283852 43 43 // interpreter's exception handler. 44 44 Instruction* returnToThrow(VM&); 45 Instruction* wasmReturnToThrow(VM&); 45 46 46 47 // Use this when you're throwing to a call thunk. … … 50 51 MacroAssemblerCodeRef<ExceptionHandlerPtrTag> handleCatch(OpcodeSize); 51 52 53 #if ENABLE(WEBASSEMBLY) 54 MacroAssemblerCodeRef<ExceptionHandlerPtrTag> handleWasmCatch(OpcodeSize); 55 MacroAssemblerCodeRef<ExceptionHandlerPtrTag> handleWasmCatchAll(OpcodeSize); 56 #endif // ENABLE(WEBASSEMBLY) 57 52 58 } } // namespace JSC::LLInt -
trunk/Source/JavaScriptCore/llint/LLIntOffsetsExtractor.cpp
r275542 r283852 54 54 #include "JSString.h" 55 55 #include "JSTypeInfo.h" 56 #include "JSWebAssemblyInstance.h" 56 57 #include "JumpTable.h" 57 58 #include "LLIntData.h" -
trunk/Source/JavaScriptCore/llint/WebAssembly.asm
r276896 r283852 257 257 258 258 macro callWasmSlowPath(slowPath) 259 storei PC, ArgumentCountIncludingThis + TagOffset[cfr] 259 260 prepareStateForCCall() 260 261 move cfr, a0 … … 275 276 end 276 277 278 macro restoreStackPointerAfterCall() 279 loadp CodeBlock[cfr], ws1 280 loadi Wasm::FunctionCodeBlock::m_numCalleeLocals[ws1], ws1 281 lshiftp 3, ws1 282 addp maxFrameExtentForSlowPathCall, ws1 283 subp cfr, ws1, sp 284 end 285 277 286 macro wasmPrologue(codeBlockGetter, codeBlockSetter, loadWasmInstance) 278 287 # Set up the call frame and check if we should OSR. … … 281 290 loadWasmInstance() 282 291 reloadMemoryRegistersFromInstance(wasmInstance, ws0, ws1) 292 293 loadp Wasm::Instance::m_owner[wasmInstance], ws0 294 storep ws0, ThisArgumentOffset[cfr] 283 295 284 296 codeBlockGetter(ws0) … … 334 346 end 335 347 336 # Less convenient, but required for opcodes that collide with reserved instructions (e.g. wasm_nop) 337 macro unprefixedWasmOp(opcodeName, opcodeStruct, fn) 338 commonOp(opcodeName, traceExecution, macro(size) 348 macro commonWasmOp(opcodeName, opcodeStruct, prologue, fn) 349 commonOp(opcodeName, prologue, macro(size) 339 350 fn(macro(fn2) 340 351 fn2(opcodeName, opcodeStruct, size) 341 352 end) 342 353 end) 354 end 355 356 # Less convenient, but required for opcodes that collide with reserved instructions (e.g. wasm_nop) 357 macro unprefixedWasmOp(opcodeName, opcodeStruct, fn) 358 commonWasmOp(opcodeName, opcodeStruct, traceExecution, fn) 343 359 end 344 360 … … 513 529 end) 514 530 515 op(wasm_throw_from_slow_path_trampoline, macro () 516 loadp Wasm::Instance::m_pointerToTopEntryFrame[wasmInstance], t5 517 loadp [t5], t5 518 copyCalleeSavesToEntryFrameCalleeSavesBuffer(t5) 519 520 move cfr, a0 521 addp PB, PC, a1 522 move wasmInstance, a2 523 # Slow paths and the throwException macro store the exception code in the ArgumentCountIncludingThis slot 524 loadi ArgumentCountIncludingThis + PayloadOffset[cfr], a3 525 cCall4(_slow_path_wasm_throw_exception) 526 531 macro jumpToException() 527 532 if ARM64E 528 533 move r0, a0 … … 532 537 jmp r0, ExceptionHandlerPtrTag 533 538 end 539 end 540 541 op(wasm_throw_from_slow_path_trampoline, macro () 542 loadp Wasm::Instance::m_pointerToTopEntryFrame[wasmInstance], t5 543 loadp [t5], t5 544 copyCalleeSavesToEntryFrameCalleeSavesBuffer(t5) 545 546 move cfr, a0 547 addp PB, PC, a1 548 move wasmInstance, a2 549 # Slow paths and the throwException macro store the exception code in the ArgumentCountIncludingThis slot 550 loadi ArgumentCountIncludingThis + PayloadOffset[cfr], a3 551 cCall4(_slow_path_wasm_throw_exception) 552 jumpToException() 534 553 end) 535 554 … … 544 563 move cfr, a0 545 564 cCall4(_slow_path_wasm_throw_exception) 546 547 if ARM64E 548 move r0, a0 549 leap JSCConfig + constexpr JSC::offsetOfJSCConfigGateMap + (constexpr Gate::exceptionHandler) * PtrSize, a1 550 jmp [a1], NativeToJITGatePtrTag # ExceptionHandlerPtrTag 551 else 552 jmp r0, ExceptionHandlerPtrTag 553 end 565 jumpToException() 554 566 end 555 567 … … 771 783 # Load registers from stack 772 784 forEachArgumentGPR(macro (offset, gpr) 773 loadq CallFrameHeaderSize + offset[sp, ws1, 8], gpr785 loadq CallFrameHeaderSize + 8 + offset[sp, ws1, 8], gpr 774 786 end) 775 787 776 788 forEachArgumentFPR(macro (offset, fpr) 777 loadd CallFrameHeaderSize + offset[sp, ws1, 8], fpr789 loadd CallFrameHeaderSize + 8 + offset[sp, ws1, 8], fpr 778 790 end) 779 791 … … 812 824 end) 813 825 814 loadp CodeBlock[cfr], ws1 815 loadi Wasm::FunctionCodeBlock::m_numCalleeLocals[ws1], ws1 816 lshiftp 3, ws1 817 addp maxFrameExtentForSlowPathCall, ws1 818 subp cfr, ws1, sp 826 restoreStackPointerAfterCall() 819 827 820 828 # We need to set PC to load information from the instruction stream, but we … … 837 845 move memoryBase, PC 838 846 forEachArgumentGPR(macro (offset, gpr) 839 storeq gpr, CallFrameHeaderSize + offset[ws1, ws0, 8]847 storeq gpr, CallFrameHeaderSize + 8 + offset[ws1, ws0, 8] 840 848 end) 841 849 842 850 forEachArgumentFPR(macro (offset, fpr) 843 stored fpr, CallFrameHeaderSize + offset[ws1, ws0, 8]851 stored fpr, CallFrameHeaderSize + 8 + offset[ws1, ws0, 8] 844 852 end) 845 853 … … 2805 2813 dispatch(ctx) 2806 2814 end) 2815 2816 wasmOp(throw, WasmThrow, macro(ctx) 2817 loadp Wasm::Instance::m_pointerToTopEntryFrame[wasmInstance], t5 2818 loadp [t5], t5 2819 copyCalleeSavesToEntryFrameCalleeSavesBuffer(t5) 2820 2821 callWasmSlowPath(_slow_path_wasm_throw) 2822 jumpToException() 2823 end) 2824 2825 wasmOp(rethrow, WasmRethrow, macro(ctx) 2826 callWasmSlowPath(_slow_path_wasm_rethrow) 2827 jumpToException() 2828 end) 2829 2830 macro catchImpl(ctx, storeWasmInstance) 2831 loadp Callee[cfr], t3 2832 convertCalleeToVM(t3) 2833 restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0) 2834 2835 loadp VM::calleeForWasmCatch[t3], ws1 2836 storep 0, VM::calleeForWasmCatch[t3] 2837 storep ws1, Callee[cfr] 2838 2839 loadp VM::callFrameForCatch[t3], cfr 2840 storep 0, VM::callFrameForCatch[t3] 2841 2842 restoreStackPointerAfterCall() 2843 2844 loadp ThisArgumentOffset[cfr], wasmInstance 2845 loadp JSWebAssemblyInstance::m_instance[wasmInstance], wasmInstance 2846 storeWasmInstance(wasmInstance) 2847 reloadMemoryRegistersFromInstance(wasmInstance, ws0, ws1) 2848 2849 loadp CodeBlock[cfr], PB 2850 loadp Wasm::FunctionCodeBlock::m_instructionsRawPointer[PB], PB 2851 loadp VM::targetInterpreterPCForThrow[t3], PC 2852 subp PB, PC 2853 2854 callWasmSlowPath(_slow_path_wasm_retrieve_and_clear_exception) 2855 move r1, t1 2856 2857 wgetu(ctx, m_startOffset, t2) 2858 wgetu(ctx, m_argumentCount, t3) 2859 2860 lshifti 3, t2 2861 subp cfr, t2, t2 2862 2863 .copyLoop: 2864 btiz t3, .done 2865 loadq [t1], t6 2866 storeq t6, [t2] 2867 subi 1, t3 2868 # FIXME: Use arm store-add/sub instructions in wasm LLInt catch 2869 # https://bugs.webkit.org/show_bug.cgi?id=231210 2870 subp 8, t2 2871 addp 8, t1 2872 jmp .copyLoop 2873 2874 .done: 2875 traceExecution() 2876 2877 dispatch(ctx) 2878 end 2879 2880 commonWasmOp(wasm_catch, WasmCatch, macro() end, macro(ctx) 2881 catchImpl(ctx, storeWasmInstanceToTLS) 2882 end) 2883 2884 commonWasmOp(wasm_catch_no_tls, WasmCatch, macro() end, macro(ctx) 2885 catchImpl(ctx, macro(instance) end) 2886 end) 2887 2888 macro catchAllImpl(ctx, storeWasmInstance) 2889 loadp Callee[cfr], t3 2890 convertCalleeToVM(t3) 2891 restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(t3, t0) 2892 2893 loadp VM::calleeForWasmCatch[t3], ws1 2894 storep 0, VM::calleeForWasmCatch[t3] 2895 storep ws1, Callee[cfr] 2896 2897 loadp VM::callFrameForCatch[t3], cfr 2898 storep 0, VM::callFrameForCatch[t3] 2899 2900 restoreStackPointerAfterCall() 2901 2902 loadp ThisArgumentOffset[cfr], wasmInstance 2903 loadp JSWebAssemblyInstance::m_instance[wasmInstance], wasmInstance 2904 storeWasmInstance(wasmInstance) 2905 reloadMemoryRegistersFromInstance(wasmInstance, ws0, ws1) 2906 2907 loadp CodeBlock[cfr], PB 2908 loadp Wasm::FunctionCodeBlock::m_instructionsRawPointer[PB], PB 2909 loadp VM::targetInterpreterPCForThrow[t3], PC 2910 subp PB, PC 2911 2912 callWasmSlowPath(_slow_path_wasm_retrieve_and_clear_exception) 2913 2914 traceExecution() 2915 2916 dispatch(ctx) 2917 end 2918 2919 commonWasmOp(wasm_catch_all, WasmCatchAll, macro() end, macro(ctx) 2920 catchAllImpl(ctx, storeWasmInstanceToTLS) 2921 end) 2922 2923 commonWasmOp(wasm_catch_all_no_tls, WasmCatchAll, macro() end, macro(ctx) 2924 catchAllImpl(ctx, macro(instance) end) 2925 end) -
trunk/Source/JavaScriptCore/runtime/ErrorInstance.cpp
r277967 r283852 41 41 , m_errorInfoMaterialized(false) 42 42 , m_nativeGetterTypeError(false) 43 #if ENABLE(WEBASSEMBLY) 44 , m_catchableFromWasm(true) 45 #endif // ENABLE(WEBASSEMBLY) 43 46 { 44 47 } -
trunk/Source/JavaScriptCore/runtime/ErrorInstance.h
r278589 r283852 81 81 bool isNativeGetterTypeError() const { return m_nativeGetterTypeError; } 82 82 83 #if ENABLE(WEBASSEMBLY) 84 void setCatchableFromWasm(bool flag) { m_catchableFromWasm = flag; } 85 bool isCatchableFromWasm() const { return m_catchableFromWasm; } 86 #endif 87 83 88 JS_EXPORT_PRIVATE String sanitizedToString(JSGlobalObject*); 84 89 JS_EXPORT_PRIVATE String sanitizedMessageString(JSGlobalObject*); … … 117 122 bool m_errorInfoMaterialized : 1; 118 123 bool m_nativeGetterTypeError : 1; 124 #if ENABLE(WEBASSEMBLY) 125 bool m_catchableFromWasm : 1; 126 #endif 119 127 }; 120 128 -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp
r283566 r283852 154 154 #include "JSWebAssembly.h" 155 155 #include "JSWebAssemblyCompileError.h" 156 #include "JSWebAssemblyException.h" 156 157 #include "JSWebAssemblyGlobal.h" 157 158 #include "JSWebAssemblyInstance.h" … … 161 162 #include "JSWebAssemblyRuntimeError.h" 162 163 #include "JSWebAssemblyTable.h" 164 #include "JSWebAssemblyTag.h" 163 165 #include "JSWithScope.h" 164 166 #include "LazyClassStructureInlines.h" … … 221 223 #include "WebAssemblyCompileErrorConstructor.h" 222 224 #include "WebAssemblyCompileErrorPrototype.h" 225 #include "WebAssemblyExceptionConstructor.h" 226 #include "WebAssemblyExceptionPrototype.h" 223 227 #include "WebAssemblyFunction.h" 224 228 #include "WebAssemblyGlobalConstructor.h" … … 237 241 #include "WebAssemblyTableConstructor.h" 238 242 #include "WebAssemblyTablePrototype.h" 243 #include "WebAssemblyTagConstructor.h" 244 #include "WebAssemblyTagPrototype.h" 239 245 #include <wtf/RandomNumber.h> 240 246 #include <wtf/SystemTracing.h> -
trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h
r283566 r283852 170 170 #if ENABLE(WEBASSEMBLY) 171 171 #define FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(macro) \ 172 macro(WebAssemblyCompileError, webAssemblyCompileError, webAssemblyCompileError, ErrorInstance, CompileError, error, typeExposedByDefault) \ 172 macro(WebAssemblyCompileError, webAssemblyCompileError, webAssemblyCompileError, ErrorInstance, CompileError, error, typeExposedByDefault) \ 173 macro(WebAssemblyException, webAssemblyException, webAssemblyException, JSWebAssemblyException, Exception, object, typeExposedByDefault) \ 173 174 macro(WebAssemblyGlobal, webAssemblyGlobal, webAssemblyGlobal, JSWebAssemblyGlobal, Global, object, typeExposedByDefault) \ 174 175 macro(WebAssemblyInstance, webAssemblyInstance, webAssemblyInstance, JSWebAssemblyInstance, Instance, object, typeExposedByDefault) \ 175 macro(WebAssemblyLinkError, webAssemblyLinkError, webAssemblyLinkError, ErrorInstance, LinkError, error, typeExposedByDefault) \176 macro(WebAssemblyLinkError, webAssemblyLinkError, webAssemblyLinkError, ErrorInstance, LinkError, error, typeExposedByDefault) \ 176 177 macro(WebAssemblyMemory, webAssemblyMemory, webAssemblyMemory, JSWebAssemblyMemory, Memory, object, typeExposedByDefault) \ 177 178 macro(WebAssemblyModule, webAssemblyModule, webAssemblyModule, JSWebAssemblyModule, Module, object, typeExposedByDefault) \ 178 macro(WebAssemblyRuntimeError, webAssemblyRuntimeError, webAssemblyRuntimeError, ErrorInstance, RuntimeError, error, typeExposedByDefault) \ 179 macro(WebAssemblyTable, webAssemblyTable, webAssemblyTable, JSWebAssemblyTable, Table, object, typeExposedByDefault) 179 macro(WebAssemblyRuntimeError, webAssemblyRuntimeError, webAssemblyRuntimeError, ErrorInstance, RuntimeError, error, typeExposedByDefault) \ 180 macro(WebAssemblyTable, webAssemblyTable, webAssemblyTable, JSWebAssemblyTable, Table, object, typeExposedByDefault) \ 181 macro(WebAssemblyTag, webAssemblyTag, webAssemblyTag, JSWebAssemblyTag, Tag, object, typeExposedByDefault) 180 182 #else 181 183 #define FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(macro) -
trunk/Source/JavaScriptCore/runtime/OptionsList.h
r283139 r283852 544 544 v(Bool, useWebAssemblyThreading, true, Normal, "Allow instructions from the wasm threading spec.") \ 545 545 v(Bool, useWebAssemblyTypedFunctionReferences, false, Normal, "Allow function types from the wasm typed function references spec.") \ 546 v(Bool, useWebAssemblyExceptions, true, Normal, "Allow the new section and instructions from the wasm exception handling spec.") \ 546 547 547 548 -
trunk/Source/JavaScriptCore/runtime/VM.cpp
r282860 r283852 130 130 #include "JSWeakSet.h" 131 131 #include "JSWebAssemblyCodeBlock.h" 132 #include "JSWebAssemblyException.h" 132 133 #include "JSWebAssemblyGlobal.h" 133 134 #include "JSWebAssemblyInstance.h" … … 135 136 #include "JSWebAssemblyModule.h" 136 137 #include "JSWebAssemblyTable.h" 138 #include "JSWebAssemblyTag.h" 137 139 #include "JSWithScope.h" 138 140 #include "LLIntData.h" … … 335 337 #if ENABLE(WEBASSEMBLY) 336 338 , webAssemblyCodeBlockHeapCellType(IsoHeapCellType::create<JSWebAssemblyCodeBlock>()) 339 , webAssemblyExceptionHeapCellType(IsoHeapCellType::create<JSWebAssemblyException>()) 337 340 , webAssemblyFunctionHeapCellType(IsoHeapCellType::create<WebAssemblyFunction>()) 338 341 , webAssemblyGlobalHeapCellType(IsoHeapCellType::create<JSWebAssemblyGlobal>()) … … 342 345 , webAssemblyModuleRecordHeapCellType(IsoHeapCellType::create<WebAssemblyModuleRecord>()) 343 346 , webAssemblyTableHeapCellType(IsoHeapCellType::create<JSWebAssemblyTable>()) 347 , webAssemblyTagHeapCellType(IsoHeapCellType::create<JSWebAssemblyTag>()) 344 348 #endif 345 349 , primitiveGigacageAuxiliarySpace("Primitive Gigacage Auxiliary", heap, auxiliaryHeapCellType.get(), primitiveGigacageAllocator.get()) // Hash:0x3e7cd762 … … 1630 1634 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(jsToWasmICCalleeSpace, cellHeapCellType.get(), JSToWasmICCallee) 1631 1635 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyCodeBlockSpace, webAssemblyCodeBlockHeapCellType.get(), JSWebAssemblyCodeBlock) // Hash:0x9ad995cd 1636 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyExceptionSpace, webAssemblyExceptionHeapCellType.get(), JSWebAssemblyException) 1632 1637 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyFunctionSpace, webAssemblyFunctionHeapCellType.get(), WebAssemblyFunction) // Hash:0x8b7c32db 1633 1638 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyGlobalSpace, webAssemblyGlobalHeapCellType.get(), JSWebAssemblyGlobal) … … 1637 1642 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyModuleRecordSpace, webAssemblyModuleRecordHeapCellType.get(), WebAssemblyModuleRecord) 1638 1643 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyTableSpace, webAssemblyTableHeapCellType.get(), JSWebAssemblyTable) 1644 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyTagSpace, webAssemblyTagHeapCellType.get(), JSWebAssemblyTag) 1639 1645 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(webAssemblyWrapperFunctionSpace, cellHeapCellType.get(), WebAssemblyWrapperFunction) // Hash:0xd4a5ff01 1640 1646 #endif -
trunk/Source/JavaScriptCore/runtime/VM.h
r282565 r283852 30 30 31 31 #include "CallData.h" 32 #include "CalleeBits.h" 32 33 #include "CodeSpecializationKind.h" 33 34 #include "CompleteSubspace.h" … … 451 452 #if ENABLE(WEBASSEMBLY) 452 453 std::unique_ptr<IsoHeapCellType> webAssemblyCodeBlockHeapCellType; 454 std::unique_ptr<IsoHeapCellType> webAssemblyExceptionHeapCellType; 453 455 std::unique_ptr<IsoHeapCellType> webAssemblyFunctionHeapCellType; 454 456 std::unique_ptr<IsoHeapCellType> webAssemblyGlobalHeapCellType; … … 458 460 std::unique_ptr<IsoHeapCellType> webAssemblyModuleRecordHeapCellType; 459 461 std::unique_ptr<IsoHeapCellType> webAssemblyTableHeapCellType; 462 std::unique_ptr<IsoHeapCellType> webAssemblyTagHeapCellType; 460 463 #endif 461 464 … … 627 630 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(jsToWasmICCalleeSpace) 628 631 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyCodeBlockSpace) 632 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyExceptionSpace) 629 633 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyFunctionSpace) 630 634 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyGlobalSpace) … … 634 638 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyModuleRecordSpace) 635 639 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyTableSpace) 640 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyTagSpace) 636 641 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(webAssemblyWrapperFunctionSpace) 637 642 #endif … … 897 902 } 898 903 904 static ptrdiff_t calleeForWasmCatchOffset() 905 { 906 return OBJECT_OFFSETOF(VM, calleeForWasmCatch); 907 } 908 899 909 static ptrdiff_t topEntryFrameOffset() 900 910 { … … 991 1001 CallFrame* newCallFrameReturnValue; 992 1002 CallFrame* callFrameForCatch; 1003 CalleeBits calleeForWasmCatch; 993 1004 void* targetMachinePCForThrow; 994 1005 const Instruction* targetInterpreterPCForThrow; -
trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp
r280507 r283852 148 148 149 149 static bool isIf(const ControlData& control) { return control.blockType() == BlockType::If; } 150 static bool isTry(const ControlData& control) { return control.blockType() == BlockType::Try; } 151 static bool isCatch(const ControlData& control) { return control.blockType() == BlockType::Catch; } 152 static bool isAnyCatch(const ControlData& control) { return control.blockType() == BlockType::Catch; } 150 153 static bool isTopLevel(const ControlData& control) { return control.blockType() == BlockType::TopLevel; } 154 static bool isLoop(const ControlData& control) { return control.blockType() == BlockType::Loop; } 155 static bool isBlock(const ControlData& control) { return control.blockType() == BlockType::Block; } 151 156 152 157 void dump(PrintStream& out) const … … 165 170 out.print("TopLevel: "); 166 171 break; 172 case BlockType::Try: 173 out.print("Try: "); 174 break; 175 case BlockType::Catch: 176 out.print("Catch: "); 177 break; 167 178 } 168 179 out.print("Continuation: ", *continuation, ", Special: "); … … 314 325 PartialResult WARN_UNUSED_RETURN addElse(ControlData&, const Stack&); 315 326 PartialResult WARN_UNUSED_RETURN addElseToUnreachable(ControlData&); 327 328 PartialResult WARN_UNUSED_RETURN addTry(BlockSignature, Stack& enclosingStack, ControlType& result, Stack& newStack); 329 PartialResult WARN_UNUSED_RETURN addCatch(unsigned exceptionIndex, const Signature&, Stack&, ControlType&, ResultList&); 330 PartialResult WARN_UNUSED_RETURN addCatchToUnreachable(unsigned exceptionIndex, const Signature&, ControlType&, ResultList&); 331 PartialResult WARN_UNUSED_RETURN addCatchAll(Stack&, ControlType&); 332 PartialResult WARN_UNUSED_RETURN addCatchAllToUnreachable(ControlType&); 333 PartialResult WARN_UNUSED_RETURN addDelegate(ControlType&, ControlType&); 334 PartialResult WARN_UNUSED_RETURN addDelegateToUnreachable(ControlType&, ControlType&); 335 PartialResult WARN_UNUSED_RETURN addThrow(unsigned exceptionIndex, Vector<ExpressionType>& args, Stack&); 336 PartialResult WARN_UNUSED_RETURN addRethrow(unsigned, ControlType&); 316 337 317 338 PartialResult WARN_UNUSED_RETURN addReturn(const ControlData&, const Stack& returnValues); … … 2983 3004 } 2984 3005 3006 // FIXME: Add support for Wasm exceptions in the Air generator 3007 // https://bugs.webkit.org/show_bug.cgi?id=231211 3008 auto AirIRGenerator::addTry(BlockSignature, Stack&, ControlType&, Stack&) -> PartialResult 3009 { 3010 return { }; 3011 } 3012 3013 auto AirIRGenerator::addCatch(unsigned, const Signature&, Stack&, ControlType&, ResultList&) -> PartialResult 3014 { 3015 RELEASE_ASSERT_NOT_REACHED(); 3016 return { }; 3017 } 3018 3019 auto AirIRGenerator::addCatchToUnreachable(unsigned, const Signature&, ControlType&, ResultList&) -> PartialResult 3020 { 3021 RELEASE_ASSERT_NOT_REACHED(); 3022 return { }; 3023 } 3024 3025 auto AirIRGenerator::addCatchAll(Stack&, ControlType&) -> PartialResult 3026 { 3027 RELEASE_ASSERT_NOT_REACHED(); 3028 return { }; 3029 } 3030 3031 auto AirIRGenerator::addCatchAllToUnreachable(ControlType&) -> PartialResult 3032 { 3033 RELEASE_ASSERT_NOT_REACHED(); 3034 return { }; 3035 } 3036 3037 auto AirIRGenerator::addDelegate(ControlType&, ControlType&) -> PartialResult 3038 { 3039 RELEASE_ASSERT_NOT_REACHED(); 3040 return { }; 3041 } 3042 3043 auto AirIRGenerator::addDelegateToUnreachable(ControlType&, ControlType&) -> PartialResult 3044 { 3045 RELEASE_ASSERT_NOT_REACHED(); 3046 return { }; 3047 } 3048 3049 auto AirIRGenerator::addThrow(unsigned exceptionIndex, Vector<ExpressionType>&, Stack&) -> PartialResult 3050 { 3051 UNUSED_PARAM(exceptionIndex); 3052 return { }; 3053 } 3054 3055 auto AirIRGenerator::addRethrow(unsigned, ControlType&) -> PartialResult 3056 { 3057 return { }; 3058 } 3059 2985 3060 auto AirIRGenerator::addReturn(const ControlData& data, const Stack& returnValues) -> PartialResult 2986 3061 { -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r280507 r283852 49 49 #include "JSCJSValueInlines.h" 50 50 #include "JSWebAssemblyInstance.h" 51 #include "ProbeContext.h" 52 #include "ScratchRegisterAllocator.h" 51 53 #include "ScratchRegisterAllocator.h" 52 54 #include "WasmCallingConvention.h" … … 84 86 } 85 87 88 class B3IRGenerator; 89 struct PatchpointExceptionHandle { 90 void generate(CCallHelpers&, const B3::StackmapGenerationParams&, B3IRGenerator*) const; 91 92 static constexpr unsigned s_invalidCallSiteIndex = std::numeric_limits<unsigned>::max(); 93 94 unsigned m_callSiteIndex { s_invalidCallSiteIndex }; 95 unsigned m_offset; 96 }; 97 86 98 class B3IRGenerator { 87 99 public: 88 using ExpressionType = Va lue*;100 using ExpressionType = Variable*; 89 101 using ResultList = Vector<ExpressionType, 8>; 90 102 91 103 struct ControlData { 92 ControlData(Procedure& proc, Origin origin, BlockSignature signature, BlockType type, BasicBlock* continuation, BasicBlock* special = nullptr)104 ControlData(Procedure& proc, Origin origin, BlockSignature signature, BlockType type, unsigned stackSize, BasicBlock* continuation, BasicBlock* special = nullptr) 93 105 : controlBlockType(type) 94 106 , m_signature(signature) 107 , m_stackSize(stackSize) 95 108 , continuation(continuation) 96 109 , special(special) 97 110 { 111 ASSERT(type != BlockType::Try && type != BlockType::Catch); 112 if (type != BlockType::TopLevel) 113 m_stackSize -= signature->argumentCount(); 114 98 115 if (type == BlockType::Loop) { 99 116 for (unsigned i = 0; i < signature->argumentCount(); ++i) … … 105 122 } 106 123 124 ControlData(Procedure& proc, Origin origin, BlockSignature signature, BlockType type, unsigned stackSize, BasicBlock* continuation, unsigned tryStart, unsigned tryDepth) 125 : controlBlockType(type) 126 , m_signature(signature) 127 , m_stackSize(stackSize) 128 , continuation(continuation) 129 , special(nullptr) 130 , m_tryStart(tryStart) 131 , m_tryDepth(tryDepth) 132 { 133 UNUSED_PARAM(proc); 134 UNUSED_PARAM(origin); 135 for (unsigned i = 0; i < signature->returnCount(); ++i) 136 phis.append(proc.add<Value>(Phi, toB3Type(signature->returnType(i)), origin)); 137 } 138 107 139 ControlData() 108 140 { … … 110 142 111 143 static bool isIf(const ControlData& control) { return control.blockType() == BlockType::If; } 144 static bool isTry(const ControlData& control) { return control.blockType() == BlockType::Try; } 145 static bool isAnyCatch(const ControlData& control) { return control.blockType() == BlockType::Catch; } 112 146 static bool isTopLevel(const ControlData& control) { return control.blockType() == BlockType::TopLevel; } 147 static bool isLoop(const ControlData& control) { return control.blockType() == BlockType::Loop; } 148 static bool isBlock(const ControlData& control) { return control.blockType() == BlockType::Block; } 149 static bool isCatch(const ControlData& control) 150 { 151 if (control.blockType() != BlockType::Catch) 152 return false; 153 return control.catchKind() == CatchKind::Catch; 154 } 113 155 114 156 void dump(PrintStream& out) const … … 127 169 out.print("TopLevel: "); 128 170 break; 171 case BlockType::Try: 172 out.print("Try: "); 173 break; 174 case BlockType::Catch: 175 out.print("Catch: "); 176 break; 129 177 } 130 178 out.print("Continuation: ", *continuation, ", Special: "); … … 155 203 } 156 204 205 void convertTryToCatch(unsigned tryEndCallSiteIndex, Variable* exception) 206 { 207 ASSERT(blockType() == BlockType::Try); 208 controlBlockType = BlockType::Catch; 209 m_catchKind = CatchKind::Catch; 210 m_tryEnd = tryEndCallSiteIndex; 211 m_exception = exception; 212 } 213 214 void convertTryToCatchAll(unsigned tryEndCallSiteIndex, Variable* exception) 215 { 216 ASSERT(blockType() == BlockType::Try); 217 controlBlockType = BlockType::Catch; 218 m_catchKind = CatchKind::CatchAll; 219 m_tryEnd = tryEndCallSiteIndex; 220 m_exception = exception; 221 } 222 157 223 SignatureArgCount branchTargetArity() const 158 224 { … … 170 236 } 171 237 238 unsigned tryStart() const 239 { 240 ASSERT(controlBlockType == BlockType::Try || controlBlockType == BlockType::Catch); 241 return m_tryStart; 242 } 243 244 unsigned tryEnd() const 245 { 246 ASSERT(controlBlockType == BlockType::Catch); 247 return m_tryEnd; 248 } 249 250 unsigned tryDepth() const 251 { 252 ASSERT(controlBlockType == BlockType::Try || controlBlockType == BlockType::Catch); 253 return m_tryDepth; 254 } 255 256 CatchKind catchKind() const 257 { 258 ASSERT(controlBlockType == BlockType::Catch); 259 return m_catchKind; 260 } 261 262 Variable* exception() const 263 { 264 ASSERT(controlBlockType == BlockType::Catch); 265 return m_exception; 266 } 267 268 unsigned stackSize() const { return m_stackSize; } 269 172 270 private: 271 // FIXME: Compress B3IRGenerator::ControlData fields using an union 272 // https://bugs.webkit.org/show_bug.cgi?id=231212 173 273 friend class B3IRGenerator; 174 274 BlockType controlBlockType; 175 275 BlockSignature m_signature; 276 unsigned m_stackSize; 176 277 BasicBlock* continuation; 177 278 BasicBlock* special; 178 ResultList phis; 279 Vector<Value*> phis; 280 unsigned m_tryStart; 281 unsigned m_tryEnd; 282 unsigned m_tryDepth; 283 CatchKind m_catchKind; 284 Variable* m_exception; 179 285 }; 180 286 … … 274 380 PartialResult WARN_UNUSED_RETURN addElseToUnreachable(ControlData&); 275 381 382 PartialResult WARN_UNUSED_RETURN addTry(BlockSignature, Stack& enclosingStack, ControlType& result, Stack& newStack); 383 PartialResult WARN_UNUSED_RETURN addCatch(unsigned exceptionIndex, const Signature&, Stack&, ControlType&, ResultList&); 384 PartialResult WARN_UNUSED_RETURN addCatchToUnreachable(unsigned exceptionIndex, const Signature&, ControlType&, ResultList&); 385 PartialResult WARN_UNUSED_RETURN addCatchAll(Stack&, ControlType&); 386 PartialResult WARN_UNUSED_RETURN addCatchAllToUnreachable(ControlType&); 387 PartialResult WARN_UNUSED_RETURN addDelegate(ControlType&, ControlType&); 388 PartialResult WARN_UNUSED_RETURN addDelegateToUnreachable(ControlType&, ControlType&); 389 PartialResult WARN_UNUSED_RETURN addThrow(unsigned exceptionIndex, Vector<ExpressionType>& args, Stack&); 390 PartialResult WARN_UNUSED_RETURN addRethrow(unsigned, ControlType&); 391 276 392 PartialResult WARN_UNUSED_RETURN addReturn(const ControlData&, const Stack& returnValues); 277 393 PartialResult WARN_UNUSED_RETURN addBranch(ControlData&, ExpressionType condition, const Stack& returnValues); … … 287 403 PartialResult WARN_UNUSED_RETURN addCallRef(const Signature&, Vector<ExpressionType>& args, ResultList& results); 288 404 PartialResult WARN_UNUSED_RETURN addUnreachable(); 289 PartialResult WARN_UNUSED_RETURN emitIndirectCall(Value* calleeInstance, ExpressionTypecalleeCode, const Signature&, Vector<ExpressionType>& args, ResultList&);405 PartialResult WARN_UNUSED_RETURN emitIndirectCall(Value* calleeInstance, Value* calleeCode, const Signature&, Vector<ExpressionType>& args, ResultList&); 290 406 B3::Value* createCallPatchpoint(BasicBlock*, Origin, const Signature&, Vector<ExpressionType>& args, const ScopedLambda<void(PatchpointValue*)>& patchpointFunctor); 291 407 … … 293 409 void setParser(FunctionParser<B3IRGenerator>* parser) { m_parser = parser; }; 294 410 void didFinishParsingLocals() { } 295 void didPopValueFromStack() { }411 void didPopValueFromStack() { --m_stackSize; } 296 412 297 413 Value* constant(B3::Type, uint64_t bits, std::optional<Origin> = std::nullopt); 298 414 Value* framePointer(); 415 void insertEntrySwitch(); 299 416 void insertConstants(); 300 417 301 418 B3::Type toB3ResultType(BlockSignature); 419 420 void addStackMap(unsigned callSiteIndex, StackMap&& stackmap) 421 { 422 m_stackmaps.add(CallSiteIndex(callSiteIndex), WTFMove(stackmap)); 423 } 424 425 StackMaps&& takeStackmaps() 426 { 427 return WTFMove(m_stackmaps); 428 } 429 430 Vector<UnlinkedHandlerInfo>&& takeExceptionHandlers() 431 { 432 return WTFMove(m_exceptionHandlers); 433 } 302 434 303 435 private: … … 308 440 309 441 void emitWriteBarrierForJSWrapper(); 310 ExpressionType emitCheckAndPreparePointer(ExpressionTypepointer, uint32_t offset, uint32_t sizeOfOp);442 Value* emitCheckAndPreparePointer(Value* pointer, uint32_t offset, uint32_t sizeOfOp); 311 443 B3::Kind memoryKind(B3::Opcode memoryOp); 312 ExpressionType emitLoadOp(LoadOpType, ExpressionTypepointer, uint32_t offset);313 void emitStoreOp(StoreOpType, ExpressionType pointer, ExpressionType value, uint32_t offset);314 315 ExpressionType sanitizeAtomicResult(ExtAtomicOpType, Type, ExpressionTyperesult);316 ExpressionType emitAtomicLoadOp(ExtAtomicOpType, Type, ExpressionTypepointer, uint32_t offset);317 void emitAtomicStoreOp(ExtAtomicOpType, Type, ExpressionType pointer, ExpressionType value, uint32_t offset);318 ExpressionType emitAtomicBinaryRMWOp(ExtAtomicOpType, Type, ExpressionType pointer, ExpressionType value, uint32_t offset);319 ExpressionType emitAtomicCompareExchange(ExtAtomicOpType, Type, ExpressionType pointer, ExpressionType expected, ExpressionType value, uint32_t offset);320 321 void unify( const ExpressionTypephi, const ExpressionType source);322 void unifyValuesWithBlock(const Stack& resultStack, const ResultList& stack);323 324 void emitChecksForModOrDiv(B3::Opcode, ExpressionType left, ExpressionTyperight);325 326 int32_t WARN_UNUSED_RETURN fixupPointerPlusOffset( ExpressionType&, uint32_t);327 ExpressionType WARN_UNUSED_RETURN fixupPointerPlusOffsetForAtomicOps(ExtAtomicOpType, ExpressionType, uint32_t);444 Value* emitLoadOp(LoadOpType, Value* pointer, uint32_t offset); 445 void emitStoreOp(StoreOpType, Value* pointer, Value*, uint32_t offset); 446 447 Value* sanitizeAtomicResult(ExtAtomicOpType, Type, Value* result); 448 Value* emitAtomicLoadOp(ExtAtomicOpType, Type, Value* pointer, uint32_t offset); 449 void emitAtomicStoreOp(ExtAtomicOpType, Type, Value* pointer, Value*, uint32_t offset); 450 Value* emitAtomicBinaryRMWOp(ExtAtomicOpType, Type, Value* pointer, Value*, uint32_t offset); 451 Value* emitAtomicCompareExchange(ExtAtomicOpType, Type, Value* pointer, Value* expected, Value*, uint32_t offset); 452 453 void unify(Value* phi, const ExpressionType source); 454 void unifyValuesWithBlock(const Stack& resultStack, const ControlData& block); 455 456 void emitChecksForModOrDiv(B3::Opcode, Value* left, Value* right); 457 458 int32_t WARN_UNUSED_RETURN fixupPointerPlusOffset(Value*&, uint32_t); 459 Value* WARN_UNUSED_RETURN fixupPointerPlusOffsetForAtomicOps(ExtAtomicOpType, Value*, uint32_t); 328 460 329 461 void restoreWasmContextInstance(Procedure&, BasicBlock*, Value*); 330 462 enum class RestoreCachedStackLimit { No, Yes }; 331 void restoreWebAssemblyGlobalState(RestoreCachedStackLimit, const MemoryInformation&, Value* instance, Procedure&, BasicBlock*); 463 void restoreWebAssemblyGlobalState(RestoreCachedStackLimit, const MemoryInformation&, Value* instance, Procedure&, BasicBlock*, bool restoreInstance = true); 464 465 Value* loadFromScratchBuffer(unsigned& indexInBuffer, Value* pointer, B3::Type); 466 void connectControlEntry(unsigned& indexInBuffer, Value* pointer, ControlData&, Stack& expressionStack, ControlData& currentData, bool fillLoopPhis = false); 467 Value* emitCatchImpl(CatchKind, ControlType&, unsigned exceptionIndex = 0); 468 PatchpointExceptionHandle preparePatchpointForExceptions(BasicBlock*, PatchpointValue*); 332 469 333 470 Origin origin(); … … 338 475 return UINT32_MAX; 339 476 return m_outerLoops.last(); 477 } 478 479 ExpressionType push(Type type) 480 { 481 return push(toB3Type(type)); 482 } 483 484 ExpressionType push(B3::Type type) 485 { 486 ++m_stackSize; 487 if (m_stackSize > m_maxStackSize) { 488 m_maxStackSize = m_stackSize; 489 Variable* var = m_proc.addVariable(type); 490 m_stack.append(var); 491 return var; 492 } 493 494 Variable* var = m_stack[m_stackSize - 1]; 495 if (var->type() == type) 496 return var; 497 498 var = m_proc.addVariable(type); 499 m_stack[m_stackSize - 1] = var; 500 return var; 501 } 502 503 ExpressionType push(Value* value) 504 { 505 Variable* var = push(value->type()); 506 set(var, value); 507 return var; 508 } 509 510 Value* get(BasicBlock* block, Variable* variable) 511 { 512 return block->appendNew<VariableValue>(m_proc, B3::Get, origin(), variable); 513 } 514 515 Value* get(Variable* variable) 516 { 517 return get(m_currentBlock, variable); 518 } 519 520 Value* set(BasicBlock* block, Variable* dst, Value* src) 521 { 522 return block->appendNew<VariableValue>(m_proc, B3::Set, origin(), dst, src); 523 } 524 525 Value* set(Variable* dst, Value* src) 526 { 527 return set(m_currentBlock, dst, src); 528 } 529 530 Value* set(Variable* dst, Variable* src) 531 { 532 return set(dst, get(src)); 340 533 } 341 534 … … 349 542 350 543 Procedure& m_proc; 351 BasicBlock* m_rootBlock { nullptr }; 544 Vector<BasicBlock*> m_rootBlocks; 545 BasicBlock* m_topLevelBlock; 352 546 BasicBlock* m_currentBlock { nullptr }; 353 547 Vector<uint32_t> m_outerLoops; 354 548 Vector<Variable*> m_locals; 549 Vector<Variable*> m_stack; 355 550 Vector<UnlinkedWasmToWasmCall>& m_unlinkedWasmToWasmCalls; // List each call site and the function index whose address it should be patched with. 356 551 unsigned& m_osrEntryScratchBufferSize; … … 366 561 Value* m_instanceValue { nullptr }; // Always use the accessor below to ensure the instance value is materialized when used. 367 562 bool m_usesInstanceValue { false }; 563 bool m_hasCatch { false }; 368 564 Value* instanceValue() 369 565 { … … 374 570 uint32_t m_maxNumJSCallArguments { 0 }; 375 571 unsigned m_numImportFunctions; 572 573 Checked<unsigned> m_tryDepth { 0 }; 574 Checked<unsigned> m_callSiteIndex { 0 }; 575 Checked<unsigned> m_stackSize { 0 }; 576 Checked<unsigned> m_maxStackSize { 0 }; 577 StackMaps m_stackmaps; 578 Vector<UnlinkedHandlerInfo> m_exceptionHandlers; 376 579 }; 377 580 581 void PatchpointExceptionHandle::generate(CCallHelpers& jit, const B3::StackmapGenerationParams& params, B3IRGenerator* generator) const 582 { 583 if (m_callSiteIndex == s_invalidCallSiteIndex) 584 return; 585 586 StackMap values; 587 for (unsigned i = m_offset; i < params.value()->numChildren(); ++i) 588 values.constructAndAppend(params[i], params.value()->child(i)->type()); 589 generator->addStackMap(m_callSiteIndex, WTFMove(values)); 590 jit.store32(CCallHelpers::TrustedImm32(m_callSiteIndex), CCallHelpers::tagFor(CallFrameSlot::argumentCountIncludingThis)); 591 } 592 378 593 // Memory accesses in WebAssembly have unsigned 32-bit offsets, whereas they have signed 32-bit offsets in B3. 379 int32_t B3IRGenerator::fixupPointerPlusOffset( ExpressionType& ptr, uint32_t offset)594 int32_t B3IRGenerator::fixupPointerPlusOffset(Value*& ptr, uint32_t offset) 380 595 { 381 596 if (static_cast<uint64_t>(offset) > static_cast<uint64_t>(std::numeric_limits<int32_t>::max())) { … … 429 644 , m_numImportFunctions(info.importFunctionCount()) 430 645 { 431 m_rootBlock = m_proc.addBlock(); 432 m_currentBlock = m_rootBlock; 646 m_topLevelBlock = m_proc.addBlock(); 647 m_rootBlocks.append(m_proc.addBlock()); 648 m_currentBlock = m_rootBlocks[0]; 433 649 434 650 // FIXME we don't really need to pin registers here if there's no memory. It makes wasm -> wasm thunks simpler for now. https://bugs.webkit.org/show_bug.cgi?id=166623 … … 460 676 this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsMemoryAccess); 461 677 }); 678 } 679 680 { 681 B3::PatchpointValue* getInstance = m_topLevelBlock->appendNew<B3::PatchpointValue>(m_proc, pointerType(), Origin()); 682 if (Context::useFastTLS()) 683 getInstance->clobber(RegisterSet::macroScratchRegisters()); 684 else { 685 // FIXME: Because WasmToWasm call clobbers wasmContextInstance register and does not restore it, we need to restore it in the caller side. 686 // This prevents us from using ArgumentReg to this (logically) immutable pinned register. 687 getInstance->effects.writesPinned = false; 688 getInstance->effects.readsPinned = true; 689 getInstance->resultConstraints = { ValueRep::reg(m_wasmContextInstanceGPR) }; 690 } 691 getInstance->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 692 if (Context::useFastTLS()) { 693 AllowMacroScratchRegisterUsageIf allowScratch(jit, CCallHelpers::loadWasmContextInstanceNeedsMacroScratchRegister()); 694 jit.loadWasmContextInstance(params[0].gpr()); 695 } 696 }); 697 m_instanceValue = getInstance; 462 698 } 463 699 … … 495 731 496 732 { 497 B3::PatchpointValue* stackOverflowCheck = m_currentBlock->appendNew<B3::PatchpointValue>(m_proc, pointerType(), Origin());498 m_instanceValue = stackOverflowCheck;733 B3::PatchpointValue* stackOverflowCheck = m_currentBlock->appendNew<B3::PatchpointValue>(m_proc, Void, Origin()); 734 stackOverflowCheck->appendSomeRegister(instanceValue()); 499 735 stackOverflowCheck->appendSomeRegister(framePointer()); 500 736 stackOverflowCheck->clobber(RegisterSet::macroScratchRegisters()); 501 if (!Context::useFastTLS()) {502 // FIXME: Because WasmToWasm call clobbers wasmContextInstance register and does not restore it, we need to restore it in the caller side.503 // This prevents us from using ArgumentReg to this (logically) immutable pinned register.504 stackOverflowCheck->effects.writesPinned = false;505 stackOverflowCheck->effects.readsPinned = true;506 stackOverflowCheck->resultConstraints = { ValueRep::reg(m_wasmContextInstanceGPR) };507 }508 737 stackOverflowCheck->numGPScratchRegisters = 2; 509 738 stackOverflowCheck->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { … … 527 756 bool needsOverflowCheck = m_makesCalls || wasmFrameSize >= static_cast<int32_t>(minimumParentCheckSize) || needUnderflowCheck; 528 757 529 GPRReg contextInstance = Context::useFastTLS() ? params[0].gpr() : m_wasmContextInstanceGPR;530 531 758 // This allows leaf functions to not do stack checks if their frame size is within 532 759 // certain limits since their caller would have already done the check. 533 760 if (needsOverflowCheck) { 534 761 AllowMacroScratchRegisterUsage allowScratch(jit); 762 GPRReg contextInstance = params[0].gpr(); 535 763 GPRReg fp = params[1].gpr(); 536 764 GPRReg scratch1 = params.gpScratch(0); 537 765 GPRReg scratch2 = params.gpScratch(1); 538 539 if (Context::useFastTLS())540 jit.loadWasmContextInstance(contextInstance);541 766 542 767 jit.loadPtr(CCallHelpers::Address(contextInstance, Instance::offsetOfCachedStackLimit()), scratch2); … … 549 774 linkBuffer.link(overflow, CodeLocationLabel<JITThunkPtrTag>(Thunks::singleton().stub(throwStackOverflowFromWasmThunkGenerator).code())); 550 775 }); 551 } else if (m_usesInstanceValue && Context::useFastTLS()) {552 // No overflow check is needed, but the instance values still needs to be correct.553 AllowMacroScratchRegisterUsageIf allowScratch(jit, CCallHelpers::loadWasmContextInstanceNeedsMacroScratchRegister());554 jit.loadWasmContextInstance(contextInstance);555 } else {556 // We said we'd return a pointer. We don't actually need to because it isn't used, but the patchpoint conservatively said it had effects (potential stack check) which prevent it from getting removed.557 776 } 558 777 }); … … 565 784 } 566 785 567 void B3IRGenerator::restoreWebAssemblyGlobalState(RestoreCachedStackLimit restoreCachedStackLimit, const MemoryInformation& memory, Value* instance, Procedure& proc, BasicBlock* block) 568 { 569 restoreWasmContextInstance(proc, block, instance); 786 void B3IRGenerator::restoreWebAssemblyGlobalState(RestoreCachedStackLimit restoreCachedStackLimit, const MemoryInformation& memory, Value* instance, Procedure& proc, BasicBlock* block, bool restoreInstance) 787 { 788 if (restoreInstance) 789 restoreWasmContextInstance(proc, block, instance); 570 790 571 791 if (restoreCachedStackLimit == RestoreCachedStackLimit::Yes) { … … 635 855 } 636 856 857 static void buildEntryBufferForCatch(Probe::Context& context) 858 { 859 CallFrame* callFrame = context.fp<CallFrame*>(); 860 CallSiteIndex callSiteIndex = callFrame->callSiteIndex(); 861 OptimizingJITCallee* callee = bitwise_cast<OptimizingJITCallee*>(callFrame->callee().asWasmCallee()); 862 const StackMap& stackmap = callee->stackmap(callSiteIndex); 863 VM* vm = context.gpr<VM*>(GPRInfo::regT0); 864 uint64_t* buffer = vm->wasmContext.scratchBufferForSize(stackmap.size() * 8); 865 loadValuesIntoBuffer(context, stackmap, buffer); 866 867 context.gpr(GPRInfo::argumentGPR0) = bitwise_cast<uintptr_t>(buffer); 868 } 869 870 void B3IRGenerator::insertEntrySwitch() 871 { 872 m_proc.setNumEntrypoints(m_rootBlocks.size()); 873 874 Ref<B3::Air::PrologueGenerator> catchPrologueGenerator = createSharedTask<B3::Air::PrologueGeneratorFunction>([] (CCallHelpers& jit, B3::Air::Code& code) { 875 AllowMacroScratchRegisterUsage allowScratch(jit); 876 877 jit.emitGetFromCallFrameHeaderPtr(CallFrameSlot::callee, GPRInfo::regT0); 878 { 879 // FIXME: Handling precise allocations in WasmB3IRGenerator catch entrypoints might be unnecessary 880 // https://bugs.webkit.org/show_bug.cgi?id=231213 881 auto preciseAllocationCase = jit.branchTestPtr(CCallHelpers::NonZero, GPRInfo::regT0, CCallHelpers::TrustedImm32(PreciseAllocation::halfAlignment)); 882 jit.andPtr(CCallHelpers::TrustedImmPtr(MarkedBlock::blockMask), GPRInfo::regT0); 883 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT0, MarkedBlock::offsetOfFooter + MarkedBlock::Footer::offsetOfVM()), GPRInfo::regT0); 884 auto loadedCase = jit.jump(); 885 886 preciseAllocationCase.link(&jit); 887 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT0, PreciseAllocation::offsetOfWeakSet() + WeakSet::offsetOfVM() - PreciseAllocation::headerSize()), GPRInfo::regT0); 888 889 loadedCase.link(&jit); 890 } 891 jit.restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(GPRInfo::regT0, GPRInfo::regT3); 892 893 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT0, VM::calleeForWasmCatchOffset()), GPRInfo::regT3); 894 jit.storePtr(CCallHelpers::TrustedImmPtr(nullptr), CCallHelpers::Address(GPRInfo::regT0, VM::calleeForWasmCatchOffset())); 895 jit.emitPutToCallFrameHeader(GPRInfo::regT3, CallFrameSlot::callee); 896 897 jit.load64(CCallHelpers::Address(GPRInfo::regT0, VM::callFrameForCatchOffset()), GPRInfo::callFrameRegister); 898 jit.storePtr(CCallHelpers::TrustedImmPtr(nullptr), CCallHelpers::Address(GPRInfo::regT0, VM::callFrameForCatchOffset())); 899 900 jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, CallFrameSlot::thisArgument * sizeof(Register)), GPRInfo::regT3); 901 jit.loadPtr(CCallHelpers::Address(GPRInfo::regT3, JSWebAssemblyInstance::offsetOfInstance()), GPRInfo::regT3); 902 jit.storeWasmContextInstance(GPRInfo::regT3); 903 904 jit.probe(tagCFunction<JITProbePtrTag>(buildEntryBufferForCatch), nullptr); 905 906 jit.addPtr(CCallHelpers::TrustedImm32(-code.frameSize()), GPRInfo::callFrameRegister, CCallHelpers::stackPointerRegister); 907 }); 908 909 for (unsigned i = 1; i < m_rootBlocks.size(); ++i) 910 m_proc.code().setPrologueForEntrypoint(i, catchPrologueGenerator.copyRef()); 911 912 m_currentBlock = m_topLevelBlock; 913 m_currentBlock->appendNew<Value>(m_proc, EntrySwitch, Origin()); 914 for (BasicBlock* block : m_rootBlocks) 915 m_currentBlock->appendSuccessor(FrequentedBlock(block)); 916 } 917 637 918 void B3IRGenerator::insertConstants() 638 919 { 639 920 m_constantInsertionValues.execute(m_proc.at(0)); 921 922 if (!m_hasCatch) 923 return; 924 925 Value* jsInstance = m_proc.add<MemoryValue>(Load, pointerType(), Origin(), instanceValue(), safeCast<int32_t>(Instance::offsetOfOwner())); 926 Value* store = m_proc.add<B3::MemoryValue>(B3::Store, Origin(), jsInstance, framePointer(), safeCast<int32_t>(CallFrameSlot::thisArgument * sizeof(Register))); 927 928 BasicBlock* block = m_rootBlocks[0]; 929 m_constantInsertionValues.insertValue(0, jsInstance); 930 m_constantInsertionValues.insertValue(0, store); 931 m_constantInsertionValues.execute(block); 640 932 } 641 933 … … 706 998 auto B3IRGenerator::addRefIsNull(ExpressionType value, ExpressionType& result) -> PartialResult 707 999 { 708 result = m_currentBlock->appendNew<Value>(m_proc, B3::Equal, origin(), value, m_currentBlock->appendNew<Const64Value>(m_proc, origin(), JSValue::encode(jsNull())));1000 result = push(m_currentBlock->appendNew<Value>(m_proc, B3::Equal, origin(), get(value), m_currentBlock->appendNew<Const64Value>(m_proc, origin(), JSValue::encode(jsNull())))); 709 1001 return { }; 710 1002 } … … 713 1005 { 714 1006 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 715 result= m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::Externref), origin(),1007 Value* resultValue = m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::Externref), origin(), 716 1008 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationGetWasmTableElement)), 717 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), index);1009 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), get(index)); 718 1010 719 1011 { 1012 result = push(resultValue); 720 1013 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 721 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), result , m_currentBlock->appendNew<Const64Value>(m_proc, origin(), 0)));1014 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew<Const64Value>(m_proc, origin(), 0))); 722 1015 723 1016 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 734 1027 auto shouldThrow = m_currentBlock->appendNew<CCallValue>(m_proc, B3::Int32, origin(), 735 1028 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationSetWasmTableElement)), 736 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), index, value);1029 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), get(index), get(value)); 737 1030 738 1031 { … … 752 1045 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 753 1046 754 result = m_currentBlock->appendNew<CCallValue>(m_proc, B3::Int64, origin(),1047 result = push(m_currentBlock->appendNew<CCallValue>(m_proc, B3::Int64, origin(), 755 1048 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmRefFunc)), 756 instanceValue(), addConstant(Types::I32, index));1049 instanceValue(), constant(toB3Type(Types::I32), index))); 757 1050 758 1051 return { }; … … 761 1054 auto B3IRGenerator::addTableInit(unsigned elementIndex, unsigned tableIndex, ExpressionType dstOffset, ExpressionType srcOffset, ExpressionType length) -> PartialResult 762 1055 { 763 auto result= m_currentBlock->appendNew<CCallValue>(1056 Value* resultValue = m_currentBlock->appendNew<CCallValue>( 764 1057 m_proc, toB3Type(Types::I32), origin(), 765 1058 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmTableInit)), … … 767 1060 m_currentBlock->appendNew<Const32Value>(m_proc, origin(), elementIndex), 768 1061 m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), 769 dstOffset, srcOffset, length);1062 get(dstOffset), get(srcOffset), get(length)); 770 1063 771 1064 { 772 1065 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 773 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));1066 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 774 1067 775 1068 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 795 1088 { 796 1089 // FIXME: Emit this inline <https://bugs.webkit.org/show_bug.cgi?id=198506>. 797 result = m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::I32), origin(),1090 result = push(m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::I32), origin(), 798 1091 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationGetWasmTableSize)), 799 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex)) ;1092 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex))); 800 1093 801 1094 return { }; … … 804 1097 auto B3IRGenerator::addTableGrow(unsigned tableIndex, ExpressionType fill, ExpressionType delta, ExpressionType& result) -> PartialResult 805 1098 { 806 result = m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::I32), origin(),1099 result = push(m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::I32), origin(), 807 1100 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmTableGrow)), 808 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), fill, delta);1101 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), get(fill), get(delta))); 809 1102 810 1103 return { }; … … 813 1106 auto B3IRGenerator::addTableFill(unsigned tableIndex, ExpressionType offset, ExpressionType fill, ExpressionType count) -> PartialResult 814 1107 { 815 auto result= m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::I32), origin(),1108 Value* resultValue = m_currentBlock->appendNew<CCallValue>(m_proc, toB3Type(Types::I32), origin(), 816 1109 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmTableFill)), 817 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), offset, fill, count);1110 instanceValue(), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), tableIndex), get(offset), get(fill), get(count)); 818 1111 819 1112 { 820 1113 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 821 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));1114 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 822 1115 823 1116 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 831 1124 auto B3IRGenerator::addTableCopy(unsigned dstTableIndex, unsigned srcTableIndex, ExpressionType dstOffset, ExpressionType srcOffset, ExpressionType length) -> PartialResult 832 1125 { 833 auto result= m_currentBlock->appendNew<CCallValue>(1126 Value* resultValue = m_currentBlock->appendNew<CCallValue>( 834 1127 m_proc, toB3Type(Types::I32), origin(), 835 1128 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmTableCopy)), … … 837 1130 m_currentBlock->appendNew<Const32Value>(m_proc, origin(), dstTableIndex), 838 1131 m_currentBlock->appendNew<Const32Value>(m_proc, origin(), srcTableIndex), 839 dstOffset, srcOffset, length);1132 get(dstOffset), get(srcOffset), get(length)); 840 1133 841 1134 { 842 1135 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 843 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));1136 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 844 1137 845 1138 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 854 1147 { 855 1148 ASSERT(m_locals[index]); 856 result = m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, origin(), m_locals[index]);1149 result = push(m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, origin(), m_locals[index])); 857 1150 return { }; 858 1151 } … … 868 1161 } 869 1162 870 auto B3IRGenerator::emitIndirectCall(Value* calleeInstance, ExpressionTypecalleeCode, const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult1163 auto B3IRGenerator::emitIndirectCall(Value* calleeInstance, Value* calleeCode, const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult 871 1164 { 872 1165 // Do a context switch if needed. … … 917 1210 918 1211 B3::Type returnType = toB3ResultType(&signature); 919 ExpressionTypecallResult = createCallPatchpoint(m_currentBlock, origin(), signature, args,1212 Value* callResult = createCallPatchpoint(m_currentBlock, origin(), signature, args, 920 1213 scopedLambdaRef<void(PatchpointValue*)>([=] (PatchpointValue* patchpoint) -> void { 921 1214 patchpoint->effects.writesPinned = true; … … 929 1222 930 1223 patchpoint->append(calleeCode, ValueRep::SomeRegister); 1224 PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patchpoint); 931 1225 patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 932 1226 AllowMacroScratchRegisterUsage allowScratch(jit); 1227 handle.generate(jit, params, this); 933 1228 jit.call(params[params.proc().resultCount(returnType)].gpr(), WasmEntryPtrTag); 934 1229 }); … … 942 1237 const Vector<B3::Type>& tuple = m_proc.tupleForType(returnType); 943 1238 for (unsigned i = 0; i < signature.returnCount(); ++i) 944 results.append( m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), tuple[i], callResult, i));1239 results.append(push(m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), tuple[i], callResult, i))); 945 1240 break; 946 1241 } 947 1242 default: { 948 results.append( callResult);1243 results.append(push(callResult)); 949 1244 break; 950 1245 } … … 959 1254 auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType& result) -> PartialResult 960 1255 { 961 result = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(),1256 result = push(m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(), 962 1257 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationGrowMemory)), 963 framePointer(), instanceValue(), delta);1258 framePointer(), instanceValue(), get(delta))); 964 1259 965 1260 restoreWebAssemblyGlobalState(RestoreCachedStackLimit::No, m_info.memory, instanceValue(), m_proc, m_currentBlock); … … 981 1276 size, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), shiftValue)); 982 1277 983 result = m_currentBlock->appendNew<Value>(m_proc, Trunc, origin(), numPages);1278 result = push(m_currentBlock->appendNew<Value>(m_proc, Trunc, origin(), numPages)); 984 1279 985 1280 return { }; … … 988 1283 auto B3IRGenerator::addMemoryFill(ExpressionType dstAddress, ExpressionType targetValue, ExpressionType count) -> PartialResult 989 1284 { 990 auto result= m_currentBlock->appendNew<CCallValue>(1285 Value* resultValue = m_currentBlock->appendNew<CCallValue>( 991 1286 m_proc, toB3Type(Types::I32), origin(), 992 1287 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmMemoryFill)), 993 1288 instanceValue(), 994 dstAddress, targetValue, count);1289 get(dstAddress), get(targetValue), get(count)); 995 1290 996 1291 { 997 1292 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 998 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));1293 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 999 1294 1000 1295 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 1008 1303 auto B3IRGenerator::addMemoryInit(unsigned dataSegmentIndex, ExpressionType dstAddress, ExpressionType srcAddress, ExpressionType length) -> PartialResult 1009 1304 { 1010 auto result= m_currentBlock->appendNew<CCallValue>(1305 Value* resultValue = m_currentBlock->appendNew<CCallValue>( 1011 1306 m_proc, toB3Type(Types::I32), origin(), 1012 1307 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmMemoryInit)), 1013 1308 instanceValue(), 1014 1309 m_currentBlock->appendNew<Const32Value>(m_proc, origin(), dataSegmentIndex), 1015 dstAddress, srcAddress, length);1310 get(dstAddress), get(srcAddress), get(length)); 1016 1311 1017 1312 { 1018 1313 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 1019 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));1314 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 1020 1315 1021 1316 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 1029 1324 auto B3IRGenerator::addMemoryCopy(ExpressionType dstAddress, ExpressionType srcAddress, ExpressionType count) -> PartialResult 1030 1325 { 1031 auto result= m_currentBlock->appendNew<CCallValue>(1326 Value* resultValue = m_currentBlock->appendNew<CCallValue>( 1032 1327 m_proc, toB3Type(Types::I32), origin(), 1033 1328 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationWasmMemoryCopy)), 1034 1329 instanceValue(), 1035 dstAddress, srcAddress, count);1330 get(dstAddress), get(srcAddress), get(count)); 1036 1331 1037 1332 { 1038 1333 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 1039 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));1334 m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 1040 1335 1041 1336 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 1061 1356 { 1062 1357 ASSERT(m_locals[index]); 1063 m_currentBlock->appendNew<VariableValue>(m_proc, B3::Set, origin(), m_locals[index], value);1358 m_currentBlock->appendNew<VariableValue>(m_proc, B3::Set, origin(), m_locals[index], get(value)); 1064 1359 return { }; 1065 1360 } … … 1071 1366 switch (global.bindingMode) { 1072 1367 case Wasm::GlobalInformation::BindingMode::EmbeddedInInstance: 1073 result = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, toB3Type(global.type), origin(), globalsArray, safeCast<int32_t>(index * sizeof(Register)));1368 result = push(m_currentBlock->appendNew<MemoryValue>(m_proc, Load, toB3Type(global.type), origin(), globalsArray, safeCast<int32_t>(index * sizeof(Register)))); 1074 1369 break; 1075 1370 case Wasm::GlobalInformation::BindingMode::Portable: { 1076 1371 ASSERT(global.mutability == Wasm::GlobalInformation::Mutability::Mutable); 1077 1372 Value* pointer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Int64, origin(), globalsArray, safeCast<int32_t>(index * sizeof(Register))); 1078 result = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, toB3Type(global.type), origin(), pointer);1373 result = push(m_currentBlock->appendNew<MemoryValue>(m_proc, Load, toB3Type(global.type), origin(), pointer)); 1079 1374 break; 1080 1375 } … … 1090 1385 switch (global.bindingMode) { 1091 1386 case Wasm::GlobalInformation::BindingMode::EmbeddedInInstance: 1092 m_currentBlock->appendNew<MemoryValue>(m_proc, Store, origin(), value, globalsArray, safeCast<int32_t>(index * sizeof(Register)));1387 m_currentBlock->appendNew<MemoryValue>(m_proc, Store, origin(), get(value), globalsArray, safeCast<int32_t>(index * sizeof(Register))); 1093 1388 if (isRefType(global.type)) 1094 1389 emitWriteBarrierForJSWrapper(); … … 1097 1392 ASSERT(global.mutability == Wasm::GlobalInformation::Mutability::Mutable); 1098 1393 Value* pointer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, B3::Int64, origin(), globalsArray, safeCast<int32_t>(index * sizeof(Register))); 1099 m_currentBlock->appendNew<MemoryValue>(m_proc, Store, origin(), value, pointer);1394 m_currentBlock->appendNew<MemoryValue>(m_proc, Store, origin(), get(value), pointer); 1100 1395 // We emit a write-barrier onto JSWebAssemblyGlobal, not JSWebAssemblyInstance. 1101 1396 if (isRefType(global.type)) { … … 1200 1495 } 1201 1496 1202 inline Value* B3IRGenerator::emitCheckAndPreparePointer( ExpressionTypepointer, uint32_t offset, uint32_t sizeOfOperation)1497 inline Value* B3IRGenerator::emitCheckAndPreparePointer(Value* pointer, uint32_t offset, uint32_t sizeOfOperation) 1203 1498 { 1204 1499 ASSERT(m_memoryBaseGPR); … … 1269 1564 } 1270 1565 1271 inline Value* B3IRGenerator::emitLoadOp(LoadOpType op, ExpressionTypepointer, uint32_t uoffset)1566 inline Value* B3IRGenerator::emitLoadOp(LoadOpType op, Value* pointer, uint32_t uoffset) 1272 1567 { 1273 1568 int32_t offset = fixupPointerPlusOffset(pointer, uoffset); … … 1339 1634 } 1340 1635 1341 auto B3IRGenerator::load(LoadOpType op, ExpressionType pointer, ExpressionType& result, uint32_t offset) -> PartialResult 1342 { 1636 auto B3IRGenerator::load(LoadOpType op, ExpressionType pointerVar, ExpressionType& result, uint32_t offset) -> PartialResult 1637 { 1638 Value* pointer = get(pointerVar); 1343 1639 ASSERT(pointer->type() == Int32); 1344 1640 … … 1357 1653 case LoadOpType::I32Load16U: 1358 1654 case LoadOpType::I32Load8U: 1359 result = constant(Int32, 0);1655 result = push(constant(Int32, 0)); 1360 1656 break; 1361 1657 case LoadOpType::I64Load8S: … … 1366 1662 case LoadOpType::I64Load: 1367 1663 case LoadOpType::I64Load16U: 1368 result = constant(Int64, 0);1664 result = push(constant(Int64, 0)); 1369 1665 break; 1370 1666 case LoadOpType::F32Load: 1371 result = constant(Float, 0);1667 result = push(constant(Float, 0)); 1372 1668 break; 1373 1669 case LoadOpType::F64Load: 1374 result = constant(Double, 0);1670 result = push(constant(Double, 0)); 1375 1671 break; 1376 1672 } 1377 1673 1378 1674 } else 1379 result = emitLoadOp(op, emitCheckAndPreparePointer(pointer, offset, sizeOfLoadOp(op)), offset);1675 result = push(emitLoadOp(op, emitCheckAndPreparePointer(pointer, offset, sizeOfLoadOp(op)), offset)); 1380 1676 1381 1677 return { }; … … 1403 1699 1404 1700 1405 inline void B3IRGenerator::emitStoreOp(StoreOpType op, ExpressionType pointer, ExpressionTypevalue, uint32_t uoffset)1701 inline void B3IRGenerator::emitStoreOp(StoreOpType op, Value* pointer, Value* value, uint32_t uoffset) 1406 1702 { 1407 1703 int32_t offset = fixupPointerPlusOffset(pointer, uoffset); … … 1438 1734 } 1439 1735 1440 auto B3IRGenerator::store(StoreOpType op, ExpressionType pointer, ExpressionType value, uint32_t offset) -> PartialResult 1441 { 1736 auto B3IRGenerator::store(StoreOpType op, ExpressionType pointerVar, ExpressionType valueVar, uint32_t offset) -> PartialResult 1737 { 1738 Value* pointer = get(pointerVar); 1739 Value* value = get(valueVar); 1442 1740 ASSERT(pointer->type() == Int32); 1443 1741 … … 1465 1763 } 1466 1764 1467 inline Value* B3IRGenerator::sanitizeAtomicResult(ExtAtomicOpType op, Type valueType, ExpressionTyperesult)1468 { 1469 auto sanitize32 = [&]( ExpressionTyperesult) {1765 inline Value* B3IRGenerator::sanitizeAtomicResult(ExtAtomicOpType op, Type valueType, Value* result) 1766 { 1767 auto sanitize32 = [&](Value* result) { 1470 1768 switch (accessWidth(op)) { 1471 1769 case B3::Width8: … … 1492 1790 } 1493 1791 1494 Value* B3IRGenerator::fixupPointerPlusOffsetForAtomicOps(ExtAtomicOpType op, ExpressionTypeptr, uint32_t offset)1792 Value* B3IRGenerator::fixupPointerPlusOffsetForAtomicOps(ExtAtomicOpType op, Value* ptr, uint32_t offset) 1495 1793 { 1496 1794 auto pointer = m_currentBlock->appendNew<Value>(m_proc, Add, origin(), ptr, m_currentBlock->appendNew<Const64Value>(m_proc, origin(), offset)); … … 1505 1803 } 1506 1804 1507 inline Value* B3IRGenerator::emitAtomicLoadOp(ExtAtomicOpType op, Type valueType, ExpressionTypepointer, uint32_t uoffset)1805 inline Value* B3IRGenerator::emitAtomicLoadOp(ExtAtomicOpType op, Type valueType, Value* pointer, uint32_t uoffset) 1508 1806 { 1509 1807 pointer = fixupPointerPlusOffsetForAtomicOps(op, pointer, uoffset); 1510 1808 1511 ExpressionTypevalue = nullptr;1809 Value* value = nullptr; 1512 1810 switch (accessWidth(op)) { 1513 1811 case B3::Width8: … … 1538 1836 switch (valueType.kind) { 1539 1837 case TypeKind::I32: 1540 result = constant(Int32, 0);1838 result = push(constant(Int32, 0)); 1541 1839 break; 1542 1840 case TypeKind::I64: 1543 result = constant(Int64, 0);1841 result = push(constant(Int64, 0)); 1544 1842 break; 1545 1843 default: … … 1548 1846 } 1549 1847 } else 1550 result = emitAtomicLoadOp(op, valueType, emitCheckAndPreparePointer(pointer, offset, sizeOfAtomicOpMemoryAccess(op)), offset);1551 1552 return { }; 1553 } 1554 1555 inline void B3IRGenerator::emitAtomicStoreOp(ExtAtomicOpType op, Type valueType, ExpressionType pointer, ExpressionTypevalue, uint32_t uoffset)1848 result = push(emitAtomicLoadOp(op, valueType, emitCheckAndPreparePointer(get(pointer), offset, sizeOfAtomicOpMemoryAccess(op)), offset)); 1849 1850 return { }; 1851 } 1852 1853 inline void B3IRGenerator::emitAtomicStoreOp(ExtAtomicOpType op, Type valueType, Value* pointer, Value* value, uint32_t uoffset) 1556 1854 { 1557 1855 pointer = fixupPointerPlusOffsetForAtomicOps(op, pointer, uoffset); … … 1574 1872 }); 1575 1873 } else 1576 emitAtomicStoreOp(op, valueType, emitCheckAndPreparePointer( pointer, offset, sizeOfAtomicOpMemoryAccess(op)), value, offset);1577 1578 return { }; 1579 } 1580 1581 inline Value* B3IRGenerator::emitAtomicBinaryRMWOp(ExtAtomicOpType op, Type valueType, ExpressionType pointer, ExpressionTypevalue, uint32_t uoffset)1874 emitAtomicStoreOp(op, valueType, emitCheckAndPreparePointer(get(pointer), offset, sizeOfAtomicOpMemoryAccess(op)), get(value), offset); 1875 1876 return { }; 1877 } 1878 1879 inline Value* B3IRGenerator::emitAtomicBinaryRMWOp(ExtAtomicOpType op, Type valueType, Value* pointer, Value* value, uint32_t uoffset) 1582 1880 { 1583 1881 pointer = fixupPointerPlusOffsetForAtomicOps(op, pointer, uoffset); … … 1664 1962 switch (valueType.kind) { 1665 1963 case TypeKind::I32: 1666 result = constant(Int32, 0);1964 result = push(constant(Int32, 0)); 1667 1965 break; 1668 1966 case TypeKind::I64: 1669 result = constant(Int64, 0);1967 result = push(constant(Int64, 0)); 1670 1968 break; 1671 1969 default: … … 1674 1972 } 1675 1973 } else 1676 result = emitAtomicBinaryRMWOp(op, valueType, emitCheckAndPreparePointer(pointer, offset, sizeOfAtomicOpMemoryAccess(op)), value, offset);1677 1678 return { }; 1679 } 1680 1681 Value* B3IRGenerator::emitAtomicCompareExchange(ExtAtomicOpType op, Type valueType, ExpressionType pointer, ExpressionType expected, ExpressionTypevalue, uint32_t uoffset)1974 result = push(emitAtomicBinaryRMWOp(op, valueType, emitCheckAndPreparePointer(get(pointer), offset, sizeOfAtomicOpMemoryAccess(op)), get(value), offset)); 1975 1976 return { }; 1977 } 1978 1979 Value* B3IRGenerator::emitAtomicCompareExchange(ExtAtomicOpType op, Type valueType, Value* pointer, Value* expected, Value* value, uint32_t uoffset) 1682 1980 { 1683 1981 pointer = fixupPointerPlusOffsetForAtomicOps(op, pointer, uoffset); … … 1789 2087 switch (valueType.kind) { 1790 2088 case TypeKind::I32: 1791 result = constant(Int32, 0);2089 result = push(constant(Int32, 0)); 1792 2090 break; 1793 2091 case TypeKind::I64: 1794 result = constant(Int64, 0);2092 result = push(constant(Int64, 0)); 1795 2093 break; 1796 2094 default: … … 1799 2097 } 1800 2098 } else 1801 result = emitAtomicCompareExchange(op, valueType, emitCheckAndPreparePointer(pointer, offset, sizeOfAtomicOpMemoryAccess(op)), expected, value, offset); 1802 1803 return { }; 1804 } 1805 1806 auto B3IRGenerator::atomicWait(ExtAtomicOpType op, ExpressionType pointer, ExpressionType value, ExpressionType timeout, ExpressionType& result, uint32_t offset) -> PartialResult 1807 { 2099 result = push(emitAtomicCompareExchange(op, valueType, emitCheckAndPreparePointer(get(pointer), offset, sizeOfAtomicOpMemoryAccess(op)), get(expected), get(value), offset)); 2100 2101 return { }; 2102 } 2103 2104 auto B3IRGenerator::atomicWait(ExtAtomicOpType op, ExpressionType pointerVar, ExpressionType valueVar, ExpressionType timeoutVar, ExpressionType& result, uint32_t offset) -> PartialResult 2105 { 2106 Value* pointer = get(pointerVar); 2107 Value* value = get(valueVar); 2108 Value* timeout = get(timeoutVar); 2109 Value* resultValue = nullptr; 1808 2110 if (op == ExtAtomicOpType::MemoryAtomicWait32) { 1809 result = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(),2111 resultValue = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(), 1810 2112 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationMemoryAtomicWait32)), 1811 2113 instanceValue(), pointer, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), offset), value, timeout); 1812 2114 } else { 1813 result = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(),2115 resultValue = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(), 1814 2116 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationMemoryAtomicWait64)), 1815 2117 instanceValue(), pointer, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), offset), value, timeout); … … 1817 2119 1818 2120 { 2121 result = push(resultValue); 1819 2122 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 1820 m_currentBlock->appendNew<Value>(m_proc, LessThan, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));2123 m_currentBlock->appendNew<Value>(m_proc, LessThan, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 1821 2124 1822 2125 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 1830 2133 auto B3IRGenerator::atomicNotify(ExtAtomicOpType, ExpressionType pointer, ExpressionType count, ExpressionType& result, uint32_t offset) -> PartialResult 1831 2134 { 1832 result= m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(),2135 Value* resultValue = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(), 1833 2136 m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationMemoryAtomicNotify)), 1834 instanceValue(), pointer, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), offset), count); 1835 2137 instanceValue(), get(pointer), m_currentBlock->appendNew<Const32Value>(m_proc, origin(), offset), get(count)); 1836 2138 { 2139 result = push(resultValue); 1837 2140 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 1838 m_currentBlock->appendNew<Value>(m_proc, LessThan, origin(), result , m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0)));2141 m_currentBlock->appendNew<Value>(m_proc, LessThan, origin(), resultValue, m_currentBlock->appendNew<Const32Value>(m_proc, origin(), 0))); 1839 2142 1840 2143 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 1852 2155 } 1853 2156 1854 auto B3IRGenerator::truncSaturated(Ext1OpType op, ExpressionType arg, ExpressionType& result, Type returnType, Type) -> PartialResult 1855 { 2157 auto B3IRGenerator::truncSaturated(Ext1OpType op, ExpressionType argVar, ExpressionType& result, Type returnType, Type) -> PartialResult 2158 { 2159 Value* arg = get(argVar); 1856 2160 Value* maxFloat = nullptr; 1857 2161 Value* minFloat = nullptr; … … 2003 2307 } 2004 2308 2005 result = m_currentBlock->appendNew<Value>(m_proc, B3::Select, origin(),2309 result = push(m_currentBlock->appendNew<Value>(m_proc, B3::Select, origin(), 2006 2310 m_currentBlock->appendNew<Value>(m_proc, GreaterThan, origin(), arg, minFloat), 2007 2311 m_currentBlock->appendNew<Value>(m_proc, B3::Select, origin(), 2008 2312 m_currentBlock->appendNew<Value>(m_proc, LessThan, origin(), arg, maxFloat), 2009 2313 patchpoint, maxResult), 2010 requiresNaNCheck ? m_currentBlock->appendNew<Value>(m_proc, B3::Select, origin(), m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), arg, arg), minResult, zero) : minResult) ;2314 requiresNaNCheck ? m_currentBlock->appendNew<Value>(m_proc, B3::Select, origin(), m_currentBlock->appendNew<Value>(m_proc, Equal, origin(), arg, arg), minResult, zero) : minResult)); 2011 2315 2012 2316 return { }; … … 2015 2319 auto B3IRGenerator::addSelect(ExpressionType condition, ExpressionType nonZero, ExpressionType zero, ExpressionType& result) -> PartialResult 2016 2320 { 2017 result = m_currentBlock->appendNew<Value>(m_proc, B3::Select, origin(), condition, nonZero, zero);2321 result = push(m_currentBlock->appendNew<Value>(m_proc, B3::Select, origin(), get(condition), get(nonZero), get(zero))); 2018 2322 return { }; 2019 2323 } … … 2022 2326 { 2023 2327 2024 return constant(toB3Type(type), value);2328 return push(constant(toB3Type(type), value)); 2025 2329 } 2026 2330 … … 2083 2387 Value* countDownLocation = constant(pointerType(), bitwise_cast<uintptr_t>(&m_tierUp->m_counter), origin); 2084 2388 2085 Vector<ExpressionType> stackmap; 2086 for (auto& local : m_locals) { 2087 Value* result = m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, origin, local); 2088 stackmap.append(result); 2089 } 2389 Vector<Value*> stackmap; 2390 for (auto& local : m_locals) 2391 stackmap.append(get(local)); 2090 2392 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 2393 auto& data = m_parser->controlStack()[controlIndex].controlData; 2091 2394 auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 2092 2395 for (TypedExpression value : expressionStack) 2093 stackmap.append(value); 2396 stackmap.append(get(value)); 2397 if (ControlType::isAnyCatch(data)) 2398 stackmap.append(get(data.exception())); 2094 2399 } 2095 2400 for (TypedExpression value : enclosingStack) 2096 stackmap.append( value);2401 stackmap.append(get(value)); 2097 2402 for (TypedExpression value : newStack) 2098 stackmap.append( value);2403 stackmap.append(get(value)); 2099 2404 2100 2405 PatchpointValue* patch = m_currentBlock->appendNew<PatchpointValue>(m_proc, B3::Void, origin); … … 2141 2446 } 2142 2447 2448 Value* B3IRGenerator::loadFromScratchBuffer(unsigned& indexInBuffer, Value* pointer, B3::Type type) 2449 { 2450 size_t offset = sizeof(uint64_t) * indexInBuffer++; 2451 RELEASE_ASSERT(type.isNumeric()); 2452 return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, type, origin(), pointer, offset); 2453 } 2454 2455 void B3IRGenerator::connectControlEntry(unsigned& indexInBuffer, Value* pointer, ControlData& data, Stack& expressionStack, ControlData& currentData, bool fillLoopPhis) 2456 { 2457 // For each stack entry enclosed by this loop we need to replace the value with a phi so we can fill it on OSR entry. 2458 for (unsigned i = 0; i < expressionStack.size(); i++) { 2459 TypedExpression value = expressionStack[i]; 2460 auto* load = loadFromScratchBuffer(indexInBuffer, pointer, value->type()); 2461 if (fillLoopPhis) 2462 m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), load, data.phis[i]); 2463 else 2464 m_currentBlock->appendNew<VariableValue>(m_proc, Set, origin(), value.value(), load); 2465 } 2466 if (ControlType::isAnyCatch(data) && &data != ¤tData) { 2467 auto* load = loadFromScratchBuffer(indexInBuffer, pointer, pointerType()); 2468 m_currentBlock->appendNew<VariableValue>(m_proc, Set, origin(), data.exception(), load); 2469 } 2470 }; 2471 2143 2472 auto B3IRGenerator::addLoop(BlockSignature signature, Stack& enclosingStack, ControlType& block, Stack& newStack, uint32_t loopIndex) -> PartialResult 2144 2473 { … … 2146 2475 BasicBlock* continuation = m_proc.addBlock(); 2147 2476 2148 block = ControlData(m_proc, origin(), signature, BlockType::Loop, continuation, body); 2477 block = ControlData(m_proc, origin(), signature, BlockType::Loop, m_stackSize, continuation, body); 2478 2149 2479 unsigned offset = enclosingStack.size() - signature->argumentCount(); 2150 2480 for (unsigned i = 0; i < signature->argumentCount(); ++i) { 2151 2481 TypedExpression value = enclosingStack.at(offset + i); 2152 auto* upsilon = m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), value);2153 2482 Value* phi = block.phis[i]; 2483 m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), get(value), phi); 2154 2484 body->append(phi); 2155 upsilon->setPhi(phi); 2156 newStack.constructAndAppend(value.type(), phi); 2157 } 2485 set(body, value, phi); 2486 newStack.append(value); 2487 } 2488 enclosingStack.shrink(offset); 2158 2489 2159 2490 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body); … … 2161 2492 dataLogLnIf(WasmB3IRGeneratorInternal::verbose, "Setting up for OSR entry"); 2162 2493 2163 m_currentBlock = m_rootBlock ;2164 Value* pointer = m_rootBlock ->appendNew<ArgumentRegValue>(m_proc, Origin(), GPRInfo::argumentGPR0);2494 m_currentBlock = m_rootBlocks[0]; 2495 Value* pointer = m_rootBlocks[0]->appendNew<ArgumentRegValue>(m_proc, Origin(), GPRInfo::argumentGPR0); 2165 2496 2166 2497 unsigned indexInBuffer = 0; 2167 auto loadFromScratchBuffer = [&] (B3::Type type) {2168 size_t offset = sizeof(uint64_t) * indexInBuffer++;2169 RELEASE_ASSERT(type.isNumeric());2170 return m_currentBlock->appendNew<MemoryValue>(m_proc, Load, type, origin(), pointer, offset);2171 };2172 2498 2173 2499 for (auto& local : m_locals) 2174 m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), local, loadFromScratchBuffer(local->type())); 2175 2176 auto connectControlEntry = [&](const ControlData& data, Stack& expressionStack) { 2177 // For each stack entry enclosed by this loop we need to replace the value with a phi so we can fill it on OSR entry. 2178 BasicBlock* sourceBlock = nullptr; 2179 unsigned blockIndex = 0; 2180 B3::InsertionSet insertionSet(m_proc); 2181 for (unsigned i = 0; i < expressionStack.size(); i++) { 2182 TypedExpression value = expressionStack[i]; 2183 if (value->isConstant()) { 2184 ++indexInBuffer; 2185 continue; 2186 } 2187 2188 if (value->owner != sourceBlock) { 2189 if (sourceBlock) 2190 insertionSet.execute(sourceBlock); 2191 ASSERT(insertionSet.isEmpty()); 2192 dataLogLnIf(WasmB3IRGeneratorInternal::verbose && sourceBlock, "Executed insertion set into: ", *sourceBlock); 2193 blockIndex = 0; 2194 sourceBlock = value->owner; 2195 } 2196 2197 while (sourceBlock->at(blockIndex++) != value) 2198 ASSERT(blockIndex < sourceBlock->size()); 2199 ASSERT(sourceBlock->at(blockIndex - 1) == value); 2200 2201 auto* phi = data.continuation->appendNew<Value>(m_proc, Phi, value->type(), value->origin()); 2202 expressionStack[i] = TypedExpression { value.type(), phi }; 2203 m_currentBlock->appendNew<UpsilonValue>(m_proc, value->origin(), loadFromScratchBuffer(value->type()), phi); 2204 2205 auto* sourceUpsilon = m_proc.add<UpsilonValue>(value->origin(), value, phi); 2206 insertionSet.insertValue(blockIndex, sourceUpsilon); 2207 } 2208 if (sourceBlock) 2209 insertionSet.execute(sourceBlock); 2210 }; 2500 m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), local, loadFromScratchBuffer(indexInBuffer, pointer, local->type())); 2211 2501 2212 2502 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 2213 2503 auto& data = m_parser->controlStack()[controlIndex].controlData; 2214 2504 auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 2215 connectControlEntry(data, expressionStack); 2216 } 2217 for (unsigned i = 0; i < signature->argumentCount(); ++i) { 2218 TypedExpression value = enclosingStack.at(offset + i); 2219 Value* phi = block.phis[i]; 2220 m_currentBlock->appendNew<UpsilonValue>(m_proc, value->origin(), loadFromScratchBuffer(value->type()), phi); 2221 } 2222 enclosingStack.shrink(offset); 2223 connectControlEntry(block, enclosingStack); 2505 connectControlEntry(indexInBuffer, pointer, data, expressionStack, block); 2506 } 2507 connectControlEntry(indexInBuffer, pointer, block, enclosingStack, block); 2508 connectControlEntry(indexInBuffer, pointer, block, newStack, block, true); 2224 2509 2225 2510 m_osrEntryScratchBufferSize = indexInBuffer; 2226 2511 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), body); 2227 2512 body->addPredecessor(m_currentBlock); 2228 } else 2229 enclosingStack.shrink(offset); 2513 } 2230 2514 2231 2515 m_currentBlock = body; … … 2236 2520 B3IRGenerator::ControlData B3IRGenerator::addTopLevel(BlockSignature signature) 2237 2521 { 2238 return ControlData(m_proc, Origin(), signature, BlockType::TopLevel, m_ proc.addBlock());2522 return ControlData(m_proc, Origin(), signature, BlockType::TopLevel, m_stackSize, m_proc.addBlock()); 2239 2523 } 2240 2524 … … 2244 2528 2245 2529 splitStack(signature, enclosingStack, newStack); 2246 newBlock = ControlData(m_proc, origin(), signature, BlockType::Block, continuation);2530 newBlock = ControlData(m_proc, origin(), signature, BlockType::Block, m_stackSize, continuation); 2247 2531 return { }; 2248 2532 } … … 2256 2540 BasicBlock* continuation = m_proc.addBlock(); 2257 2541 2258 m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), condition);2542 m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), get(condition)); 2259 2543 m_currentBlock->setSuccessors(FrequentedBlock(taken), FrequentedBlock(notTaken)); 2260 2544 taken->addPredecessor(m_currentBlock); … … 2263 2547 m_currentBlock = taken; 2264 2548 splitStack(signature, enclosingStack, newStack); 2265 result = ControlData(m_proc, origin(), signature, BlockType::If, continuation, notTaken);2549 result = ControlData(m_proc, origin(), signature, BlockType::If, m_stackSize, continuation, notTaken); 2266 2550 return { }; 2267 2551 } … … 2269 2553 auto B3IRGenerator::addElse(ControlData& data, const Stack& currentStack) -> PartialResult 2270 2554 { 2271 unifyValuesWithBlock(currentStack, data .phis);2555 unifyValuesWithBlock(currentStack, data); 2272 2556 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), data.continuation); 2273 2557 return addElseToUnreachable(data); … … 2277 2561 { 2278 2562 ASSERT(data.blockType() == BlockType::If); 2563 m_stackSize = data.stackSize() + data.m_signature->argumentCount(); 2279 2564 m_currentBlock = data.special; 2280 2565 data.convertIfToBlock(); 2566 return { }; 2567 } 2568 2569 auto B3IRGenerator::addTry(BlockSignature signature, Stack& enclosingStack, ControlType& result, Stack& newStack) -> PartialResult 2570 { 2571 ++m_tryDepth; 2572 2573 BasicBlock* continuation = m_proc.addBlock(); 2574 splitStack(signature, enclosingStack, newStack); 2575 result = ControlData(m_proc, origin(), signature, BlockType::Try, m_stackSize, continuation, ++m_callSiteIndex, m_tryDepth); 2576 return { }; 2577 } 2578 2579 auto B3IRGenerator::addCatch(unsigned exceptionIndex, const Signature& signature, Stack& currentStack, ControlType& data, ResultList& results) -> PartialResult 2580 { 2581 unifyValuesWithBlock(currentStack, data); 2582 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), data.continuation); 2583 return addCatchToUnreachable(exceptionIndex, signature, data, results); 2584 } 2585 2586 PatchpointExceptionHandle B3IRGenerator::preparePatchpointForExceptions(BasicBlock* block, PatchpointValue* patch) 2587 { 2588 ++m_callSiteIndex; 2589 if (!m_tryDepth) 2590 return { }; 2591 2592 Vector<Value*> stackmap; 2593 Origin origin = this->origin(); 2594 for (Variable* local : m_locals) { 2595 Value* result = block->appendNew<VariableValue>(m_proc, B3::Get, origin, local); 2596 stackmap.append(result); 2597 } 2598 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 2599 ControlData& data = m_parser->controlStack()[controlIndex].controlData; 2600 Stack& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 2601 for (Variable* value : expressionStack) 2602 stackmap.append(get(block, value)); 2603 if (ControlType::isAnyCatch(data)) 2604 stackmap.append(get(block, data.exception())); 2605 } 2606 2607 unsigned offset = patch->numChildren(); 2608 if (patch->type() != Void) 2609 offset++; 2610 2611 patch->effects.exitsSideways = true; 2612 patch->appendVectorWithRep(stackmap, ValueRep::LateColdAny); 2613 2614 return PatchpointExceptionHandle { m_callSiteIndex, offset }; 2615 } 2616 2617 auto B3IRGenerator::addCatchToUnreachable(unsigned exceptionIndex, const Signature& signature, ControlType& data, ResultList& results) -> PartialResult 2618 { 2619 Value* operationResult = emitCatchImpl(CatchKind::Catch, data, exceptionIndex); 2620 Value* payload = m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), pointerType(), operationResult, 1); 2621 for (unsigned i = 0; i < signature.argumentCount(); ++i) { 2622 Type type = signature.argument(i); 2623 Value* value = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, toB3Type(type), origin(), payload, i * sizeof(uint64_t)); 2624 results.append(push(value)); 2625 } 2626 return { }; 2627 } 2628 2629 auto B3IRGenerator::addCatchAll(Stack& currentStack, ControlType& data) -> PartialResult 2630 { 2631 unifyValuesWithBlock(currentStack, data); 2632 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), data.continuation); 2633 return addCatchAllToUnreachable(data); 2634 } 2635 2636 auto B3IRGenerator::addCatchAllToUnreachable(ControlType& data) -> PartialResult 2637 { 2638 emitCatchImpl(CatchKind::CatchAll, data); 2639 return { }; 2640 } 2641 2642 Value* B3IRGenerator::emitCatchImpl(CatchKind kind, ControlType& data, unsigned exceptionIndex) 2643 { 2644 m_hasCatch = true; 2645 m_currentBlock = m_proc.addBlock(); 2646 m_rootBlocks.append(m_currentBlock); 2647 m_stackSize = data.stackSize(); 2648 2649 if (ControlType::isTry(data)) { 2650 if (kind == CatchKind::Catch) 2651 data.convertTryToCatch(++m_callSiteIndex, m_proc.addVariable(pointerType())); 2652 else 2653 data.convertTryToCatchAll(++m_callSiteIndex, m_proc.addVariable(pointerType())); 2654 } 2655 2656 HandlerType handlerType = kind == CatchKind::Catch ? HandlerType::Catch : HandlerType::CatchAll; 2657 m_exceptionHandlers.append({ handlerType, data.tryStart(), data.tryEnd(), 0, m_tryDepth, exceptionIndex }); 2658 2659 restoreWebAssemblyGlobalState(RestoreCachedStackLimit::Yes, m_info.memory, instanceValue(), m_proc, m_currentBlock, false); 2660 2661 Value* pointer = m_currentBlock->appendNew<ArgumentRegValue>(m_proc, Origin(), GPRInfo::argumentGPR0); 2662 2663 unsigned indexInBuffer = 0; 2664 2665 for (auto& local : m_locals) 2666 m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), local, loadFromScratchBuffer(indexInBuffer, pointer, local->type())); 2667 2668 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 2669 auto& controlData = m_parser->controlStack()[controlIndex].controlData; 2670 auto& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 2671 connectControlEntry(indexInBuffer, pointer, controlData, expressionStack, data); 2672 } 2673 2674 PatchpointValue* result = m_currentBlock->appendNew<PatchpointValue>(m_proc, m_proc.addTuple({ pointerType(), pointerType() }), origin()); 2675 result->effects.exitsSideways = true; 2676 result->clobber(RegisterSet::macroScratchRegisters()); 2677 RegisterSet clobberLate = RegisterSet::volatileRegistersForJSCall(); 2678 clobberLate.add(GPRInfo::argumentGPR0); 2679 result->clobberLate(clobberLate); 2680 result->append(instanceValue(), ValueRep::SomeRegister); 2681 result->resultConstraints.append(ValueRep::reg(GPRInfo::returnValueGPR)); 2682 result->resultConstraints.append(ValueRep::reg(GPRInfo::returnValueGPR2)); 2683 result->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) { 2684 AllowMacroScratchRegisterUsage allowScratch(jit); 2685 jit.move(params[2].gpr(), GPRInfo::argumentGPR0); 2686 CCallHelpers::Call call = jit.call(OperationPtrTag); 2687 jit.addLinkTask([call] (LinkBuffer& linkBuffer) { 2688 linkBuffer.link(call, FunctionPtr<OperationPtrTag>(operationWasmRetrieveAndClearExceptionIfCatchable)); 2689 }); 2690 }); 2691 2692 Value* exception = m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), pointerType(), result, 0); 2693 set(data.exception(), exception); 2694 2695 return result; 2696 } 2697 2698 auto B3IRGenerator::addDelegate(ControlType& target, ControlType& data) -> PartialResult 2699 { 2700 return addDelegateToUnreachable(target, data); 2701 } 2702 2703 auto B3IRGenerator::addDelegateToUnreachable(ControlType& target, ControlType& data) -> PartialResult 2704 { 2705 unsigned targetDepth = 0; 2706 if (ControlType::isTry(target)) 2707 targetDepth = target.tryDepth(); 2708 2709 m_exceptionHandlers.append({ HandlerType::Delegate, data.tryStart(), ++m_callSiteIndex, 0, m_tryDepth, targetDepth }); 2710 return { }; 2711 } 2712 2713 auto B3IRGenerator::addThrow(unsigned exceptionIndex, Vector<ExpressionType>& args, Stack&) -> PartialResult 2714 { 2715 PatchpointValue* patch = m_proc.add<PatchpointValue>(B3::Void, origin()); 2716 patch->effects.terminal = true; 2717 patch->append(instanceValue(), ValueRep::reg(GPRInfo::argumentGPR0)); 2718 patch->append(framePointer(), ValueRep::reg(GPRInfo::argumentGPR1)); 2719 for (unsigned i = 0; i < args.size(); ++i) 2720 patch->append(get(args[i]), ValueRep::stackArgument(i * sizeof(EncodedJSValue))); 2721 RegisterSet clobber = RegisterSet::macroScratchRegisters(); 2722 clobber.add(GPRInfo::argumentGPR2); 2723 clobber.add(GPRInfo::argumentGPR3); 2724 patch->clobber(clobber); 2725 patch->clobberLate(RegisterSet::volatileRegistersForJSCall()); 2726 patch->numGPScratchRegisters = 1; 2727 PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); 2728 patch->setGenerator([this, exceptionIndex, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 2729 AllowMacroScratchRegisterUsage allowScratch(jit); 2730 GPRReg scratch = params.gpScratch(0); 2731 handle.generate(jit, params, this); 2732 2733 jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, Instance::offsetOfOwner()), scratch); 2734 { 2735 auto preciseAllocationCase = jit.branchTestPtr(CCallHelpers::NonZero, scratch, CCallHelpers::TrustedImm32(PreciseAllocation::halfAlignment)); 2736 jit.andPtr(CCallHelpers::TrustedImmPtr(MarkedBlock::blockMask), scratch); 2737 jit.loadPtr(CCallHelpers::Address(scratch, MarkedBlock::offsetOfFooter + MarkedBlock::Footer::offsetOfVM()), scratch); 2738 auto loadedCase = jit.jump(); 2739 2740 preciseAllocationCase.link(&jit); 2741 jit.loadPtr(CCallHelpers::Address(scratch, PreciseAllocation::offsetOfWeakSet() + WeakSet::offsetOfVM() - PreciseAllocation::headerSize()), scratch); 2742 2743 loadedCase.link(&jit); 2744 } 2745 jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(scratch); 2746 2747 jit.move(MacroAssembler::TrustedImm32(exceptionIndex), GPRInfo::argumentGPR2); 2748 jit.move(MacroAssembler::stackPointerRegister, GPRInfo::argumentGPR3); 2749 CCallHelpers::Call call = jit.call(OperationPtrTag); 2750 jit.farJump(GPRInfo::returnValueGPR, ExceptionHandlerPtrTag); 2751 jit.addLinkTask([call] (LinkBuffer& linkBuffer) { 2752 linkBuffer.link(call, FunctionPtr<OperationPtrTag>(operationWasmThrow)); 2753 }); 2754 }); 2755 m_currentBlock->append(patch); 2756 2757 return { }; 2758 } 2759 2760 auto B3IRGenerator::addRethrow(unsigned, ControlType& data) -> PartialResult 2761 { 2762 PatchpointValue* patch = m_proc.add<PatchpointValue>(B3::Void, origin()); 2763 patch->clobber(RegisterSet::macroScratchRegisters()); 2764 RegisterSet clobberLate; 2765 clobberLate.add(GPRInfo::argumentGPR0); 2766 clobberLate.add(GPRInfo::argumentGPR1); 2767 clobberLate.add(GPRInfo::argumentGPR2); 2768 patch->effects.terminal = true; 2769 patch->append(instanceValue(), ValueRep::reg(GPRInfo::argumentGPR0)); 2770 patch->append(framePointer(), ValueRep::reg(GPRInfo::argumentGPR1)); 2771 patch->append(get(data.exception()), ValueRep::reg(GPRInfo::argumentGPR2)); 2772 patch->numGPScratchRegisters = 1; 2773 PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patch); 2774 patch->setGenerator([this, handle] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 2775 AllowMacroScratchRegisterUsage allowScratch(jit); 2776 2777 GPRReg scratch = params.gpScratch(0); 2778 jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, Instance::offsetOfOwner()), scratch); 2779 { 2780 auto preciseAllocationCase = jit.branchTestPtr(CCallHelpers::NonZero, scratch, CCallHelpers::TrustedImm32(PreciseAllocation::halfAlignment)); 2781 jit.andPtr(CCallHelpers::TrustedImmPtr(MarkedBlock::blockMask), scratch); 2782 jit.loadPtr(CCallHelpers::Address(scratch, MarkedBlock::offsetOfFooter + MarkedBlock::Footer::offsetOfVM()), scratch); 2783 auto loadedCase = jit.jump(); 2784 2785 preciseAllocationCase.link(&jit); 2786 jit.loadPtr(CCallHelpers::Address(scratch, PreciseAllocation::offsetOfWeakSet() + WeakSet::offsetOfVM() - PreciseAllocation::headerSize()), scratch); 2787 2788 loadedCase.link(&jit); 2789 } 2790 jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(scratch); 2791 2792 handle.generate(jit, params, this); 2793 CCallHelpers::Call call = jit.call(OperationPtrTag); 2794 jit.farJump(GPRInfo::returnValueGPR, ExceptionHandlerPtrTag); 2795 jit.addLinkTask([call] (LinkBuffer& linkBuffer) { 2796 linkBuffer.link(call, FunctionPtr<OperationPtrTag>(operationWasmRethrow)); 2797 }); 2798 }); 2799 m_currentBlock->append(patch); 2800 2281 2801 return { }; 2282 2802 } … … 2301 2821 if (rep.isStack()) { 2302 2822 B3::Value* address = m_currentBlock->appendNew<B3::Value>(m_proc, B3::Add, Origin(), framePointer(), constant(pointerType(), rep.offsetFromFP())); 2303 m_currentBlock->appendNew<B3::MemoryValue>(m_proc, B3::Store, Origin(), returnValues[offset + i], address);2823 m_currentBlock->appendNew<B3::MemoryValue>(m_proc, B3::Store, Origin(), get(returnValues[offset + i]), address); 2304 2824 } else { 2305 2825 ASSERT(rep.isReg()); 2306 patch->append( returnValues[offset + i], rep);2826 patch->append(get(returnValues[offset + i]), rep); 2307 2827 } 2308 2828 } … … 2314 2834 auto B3IRGenerator::addBranch(ControlData& data, ExpressionType condition, const Stack& returnValues) -> PartialResult 2315 2835 { 2316 unifyValuesWithBlock(returnValues, data .phis);2836 unifyValuesWithBlock(returnValues, data); 2317 2837 2318 2838 BasicBlock* target = data.targetBlockForBranch(); 2319 2839 if (condition) { 2320 2840 BasicBlock* continuation = m_proc.addBlock(); 2321 m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), condition);2841 m_currentBlock->appendNew<Value>(m_proc, B3::Branch, origin(), get(condition)); 2322 2842 m_currentBlock->setSuccessors(FrequentedBlock(target), FrequentedBlock(continuation)); 2323 2843 target->addPredecessor(m_currentBlock); … … 2334 2854 auto B3IRGenerator::addSwitch(ExpressionType condition, const Vector<ControlData*>& targets, ControlData& defaultTarget, const Stack& expressionStack) -> PartialResult 2335 2855 { 2856 UNUSED_PARAM(expressionStack); 2336 2857 for (size_t i = 0; i < targets.size(); ++i) 2337 unifyValuesWithBlock(expressionStack, targets[i]->phis);2338 unifyValuesWithBlock(expressionStack, defaultTarget .phis);2339 2340 SwitchValue* switchValue = m_currentBlock->appendNew<SwitchValue>(m_proc, origin(), condition);2858 unifyValuesWithBlock(expressionStack, *targets[i]); 2859 unifyValuesWithBlock(expressionStack, defaultTarget); 2860 2861 SwitchValue* switchValue = m_currentBlock->appendNew<SwitchValue>(m_proc, origin(), get(condition)); 2341 2862 switchValue->setFallThrough(FrequentedBlock(defaultTarget.targetBlockForBranch())); 2342 2863 for (size_t i = 0; i < targets.size(); ++i) … … 2352 2873 ASSERT(expressionStack.size() == data.signature()->returnCount()); 2353 2874 if (data.blockType() != BlockType::Loop) 2354 unifyValuesWithBlock(expressionStack, data .phis);2875 unifyValuesWithBlock(expressionStack, data); 2355 2876 2356 2877 m_currentBlock->appendNewControlValue(m_proc, Jump, origin(), data.continuation); … … 2364 2885 ControlData& data = entry.controlData; 2365 2886 m_currentBlock = data.continuation; 2887 m_stackSize = data.stackSize(); 2366 2888 2367 2889 if (data.blockType() == BlockType::If) { 2368 2890 data.special->appendNewControlValue(m_proc, Jump, origin(), m_currentBlock); 2369 2891 m_currentBlock->addPredecessor(data.special); 2370 } 2892 } else if (data.blockType() == BlockType::Try || data.blockType() == BlockType::Catch) 2893 --m_tryDepth; 2371 2894 2372 2895 if (data.blockType() != BlockType::Loop) { … … 2374 2897 Value* result = data.phis[i]; 2375 2898 m_currentBlock->append(result); 2376 entry.enclosedExpressionStack.constructAndAppend(data.signature()->returnType(i), result);2899 entry.enclosedExpressionStack.constructAndAppend(data.signature()->returnType(i), push(result)); 2377 2900 } 2378 2901 } else { 2379 2902 m_outerLoops.removeLast(); 2380 2903 for (unsigned i = 0; i < data.signature()->returnCount(); ++i) { 2381 if (i < expressionStack.size()) 2904 if (i < expressionStack.size()) { 2905 ++m_stackSize; 2382 2906 entry.enclosedExpressionStack.append(expressionStack[i]); 2383 else {2907 } else { 2384 2908 Type returnType = data.signature()->returnType(i); 2385 entry.enclosedExpressionStack.constructAndAppend(returnType, constant(toB3Type(returnType), 0xbbadbeef));2909 entry.enclosedExpressionStack.constructAndAppend(returnType, push(constant(toB3Type(returnType), 0xbbadbeef))); 2386 2910 } 2387 2911 } 2388 2912 } 2913 2389 2914 2390 2915 // TopLevel does not have any code after this so we need to make sure we emit a return here. … … 2401 2926 CallInformation wasmCallInfo = wasmCallingConvention().callInformationFor(signature); 2402 2927 for (unsigned i = 0; i < args.size(); ++i) 2403 constrainedArguments.append(B3::ConstrainedValue( args[i], wasmCallInfo.params[i]));2928 constrainedArguments.append(B3::ConstrainedValue(get(block, args[i]), wasmCallInfo.params[i])); 2404 2929 2405 2930 m_proc.requestCallArgAreaSizeInBytes(WTF::roundUpToMultipleOf(stackAlignmentBytes(), wasmCallInfo.headerAndArgumentStackSizeInBytes)); 2406 2931 2407 2932 B3::Type returnType = toB3ResultType(&signature); 2408 B3::PatchpointValue* patchpoint = block->appendNew<B3::PatchpointValue>(m_proc,returnType, origin);2933 PatchpointValue* patchpoint = m_proc.add<PatchpointValue>(returnType, origin); 2409 2934 patchpoint->clobberEarly(RegisterSet::macroScratchRegisters()); 2410 2935 patchpoint->clobberLate(RegisterSet::volatileRegistersForJSCall()); … … 2418 2943 patchpoint->resultConstraints = WTFMove(resultConstraints); 2419 2944 } 2945 block->append(patchpoint); 2420 2946 return patchpoint; 2421 2947 } … … 2439 2965 ASSERT(signature.returnCount() == tuple.size()); 2440 2966 for (unsigned i = 0; i < signature.returnCount(); ++i) 2441 results.append( m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), tuple[i], callResult, i));2967 results.append(push(m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), tuple[i], callResult, i))); 2442 2968 break; 2443 2969 } 2444 2970 default: { 2445 results.append( callResult);2971 results.append(push(callResult)); 2446 2972 break; 2447 2973 } … … 2472 2998 // FIXME: We shouldn't have to do this: https://bugs.webkit.org/show_bug.cgi?id=172181 2473 2999 patchpoint->clobberLate(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking)); 2474 patchpoint->setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { 3000 PatchpointExceptionHandle handle = preparePatchpointForExceptions(isWasmBlock, patchpoint); 3001 patchpoint->setGenerator([this, handle, unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 2475 3002 AllowMacroScratchRegisterUsage allowScratch(jit); 3003 handle.generate(jit, params, this); 2476 3004 CCallHelpers::Call call = jit.threadSafePatchableNearCall(); 2477 3005 jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndex] (LinkBuffer& linkBuffer) { … … 2499 3027 // FIXME: We shouldn't have to do this: https://bugs.webkit.org/show_bug.cgi?id=172181 2500 3028 patchpoint->clobberLate(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking)); 2501 patchpoint->setGenerator([returnType] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 3029 PatchpointExceptionHandle handle = preparePatchpointForExceptions(isEmbedderBlock, patchpoint); 3030 patchpoint->setGenerator([this, handle, returnType] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 2502 3031 AllowMacroScratchRegisterUsage allowScratch(jit); 3032 handle.generate(jit, params, this); 2503 3033 jit.call(params[params.proc().resultCount(returnType)].gpr(), WasmEntryPtrTag); 2504 3034 }); … … 2528 3058 if (m_mode == MemoryMode::Signaling || m_info.memory.isShared()) 2529 3059 patchpoint->clobberLate(RegisterSet { PinnedRegisterInfo::get().boundsCheckingSizeRegister }); 2530 patchpoint->setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { 3060 PatchpointExceptionHandle handle = preparePatchpointForExceptions(m_currentBlock, patchpoint); 3061 patchpoint->setGenerator([this, handle, unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) { 2531 3062 AllowMacroScratchRegisterUsage allowScratch(jit); 3063 handle.generate(jit, params, this); 2532 3064 CCallHelpers::Call call = jit.threadSafePatchableNearCall(); 2533 3065 jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndex] (LinkBuffer& linkBuffer) { … … 2544 3076 auto B3IRGenerator::addCallIndirect(unsigned tableIndex, const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult 2545 3077 { 2546 ExpressionType calleeIndex = args.takeLast();3078 Value* calleeIndex = get(args.takeLast()); 2547 3079 ASSERT(signature.argumentCount() == args.size()); 2548 3080 … … 2553 3085 m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, static_cast<uint32_t>(args.size())); 2554 3086 2555 ExpressionTypecallableFunctionBuffer;2556 ExpressionTypeinstancesBuffer;2557 ExpressionTypecallableFunctionBufferLength;3087 Value* callableFunctionBuffer; 3088 Value* instancesBuffer; 3089 Value* callableFunctionBufferLength; 2558 3090 { 2559 ExpressionTypetable = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),3091 Value* table = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), 2560 3092 instanceValue(), safeCast<int32_t>(Instance::offsetOfTablePtr(m_numImportFunctions, tableIndex))); 2561 3093 callableFunctionBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), … … 2579 3111 calleeIndex = m_currentBlock->appendNew<Value>(m_proc, ZExt32, origin(), calleeIndex); 2580 3112 2581 ExpressionTypecallableFunction;3113 Value* callableFunction; 2582 3114 { 2583 3115 // Compute the offset in the table index space we are looking for. 2584 ExpressionTypeoffset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(),3116 Value* offset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(), 2585 3117 calleeIndex, constant(pointerType(), sizeof(WasmToWasmImportableFunction))); 2586 3118 callableFunction = m_currentBlock->appendNew<Value>(m_proc, Add, origin(), callableFunctionBuffer, offset); … … 2589 3121 // FIXME: when we have trap handlers, we can just let the call fail because Signature::invalidIndex is 0. https://bugs.webkit.org/show_bug.cgi?id=177210 2590 3122 static_assert(sizeof(WasmToWasmImportableFunction::signatureIndex) == sizeof(uint64_t), "Load codegen assumes i64"); 2591 ExpressionTypecalleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), callableFunction, safeCast<int32_t>(WasmToWasmImportableFunction::offsetOfSignatureIndex()));3123 Value* calleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int64, origin(), callableFunction, safeCast<int32_t>(WasmToWasmImportableFunction::offsetOfSignatureIndex())); 2592 3124 { 2593 3125 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), … … 2603 3135 // Check the signature matches the value we expect. 2604 3136 { 2605 ExpressionTypeexpectedSignatureIndex = m_currentBlock->appendNew<Const64Value>(m_proc, origin(), SignatureInformation::get(signature));3137 Value* expectedSignatureIndex = m_currentBlock->appendNew<Const64Value>(m_proc, origin(), SignatureInformation::get(signature)); 2606 3138 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(), 2607 3139 m_currentBlock->appendNew<Value>(m_proc, NotEqual, origin(), calleeSignatureIndex, expectedSignatureIndex)); … … 2617 3149 Value* calleeInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), 2618 3150 m_currentBlock->appendNew<Value>(m_proc, Add, origin(), instancesBuffer, offset)); 2619 ExpressionTypecalleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),3151 Value* calleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), 2620 3152 m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), callableFunction, 2621 3153 safeCast<int32_t>(WasmToWasmImportableFunction::offsetOfEntrypointLoadLocation()))); … … 2626 3158 auto B3IRGenerator::addCallRef(const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult 2627 3159 { 2628 ExpressionType callee = args.takeLast();3160 Value* callee = get(args.takeLast()); 2629 3161 ASSERT(signature.argumentCount() == args.size()); 2630 3162 m_makesCalls = true; … … 2643 3175 m_currentBlock->appendNew<Value>(m_proc, Add, origin(), jsCalleeInstance, instanceOffset)); 2644 3176 2645 ExpressionTypecalleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),3177 Value* calleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), 2646 3178 m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), callee, 2647 3179 safeCast<int32_t>(WebAssemblyFunctionBase::offsetOfEntrypointLoadLocation()))); … … 2650 3182 } 2651 3183 2652 void B3IRGenerator::unify(const ExpressionType phi, const ExpressionType source) 2653 { 2654 m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), source, phi); 2655 } 2656 2657 void B3IRGenerator::unifyValuesWithBlock(const Stack& resultStack, const ResultList& result) 2658 { 2659 ASSERT(result.size() <= resultStack.size()); 2660 2661 for (size_t i = 0; i < result.size(); ++i) 2662 unify(result[result.size() - 1 - i], resultStack.at(resultStack.size() - 1 - i)); 3184 void B3IRGenerator::unify(Value* phi, const ExpressionType source) 3185 { 3186 m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), get(source), phi); 3187 } 3188 3189 void B3IRGenerator::unifyValuesWithBlock(const Stack& resultStack, const ControlData& block) 3190 { 3191 const Vector<Value*>& phis = block.phis; 3192 size_t resultSize = phis.size(); 3193 3194 ASSERT(resultSize <= resultStack.size()); 3195 3196 for (size_t i = 0; i < resultSize; ++i) 3197 unify(phis[resultSize - 1 - i], resultStack.at(resultStack.size() - 1 - i)); 2663 3198 } 2664 3199 … … 2704 3239 compilationContext.embedderEntrypointJIT = makeUnique<CCallHelpers>(); 2705 3240 compilationContext.wasmEntrypointJIT = makeUnique<CCallHelpers>(); 2706 2707 Procedure procedure; 3241 compilationContext.procedure = makeUnique<Procedure>(); 3242 3243 Procedure& procedure = *compilationContext.procedure; 3244 3245 compilationContext.wasmEntrypointJIT = makeUnique<CCallHelpers>(); 2708 3246 2709 3247 procedure.setOriginPrinter([] (PrintStream& out, Origin origin) { … … 2726 3264 WASM_FAIL_IF_HELPER_FAILS(parser.parse()); 2727 3265 3266 irGenerator.insertEntrySwitch(); 2728 3267 irGenerator.insertConstants(); 2729 3268 … … 2737 3276 2738 3277 { 3278 if (shouldDumpDisassemblyFor(compilationMode)) 3279 procedure.code().setDisassembler(makeUnique<B3::Air::Disassembler>()); 2739 3280 B3::prepareForGeneration(procedure); 2740 3281 B3::generate(procedure, *compilationContext.wasmEntrypointJIT); … … 2743 3284 } 2744 3285 3286 result->stackmaps = irGenerator.takeStackmaps(); 3287 result->exceptionHandlers = irGenerator.takeExceptionHandlers(); 3288 2745 3289 return result; 2746 3290 } 2747 3291 3292 void computeExceptionHandlerLocations(Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>& handlers, const InternalFunction* function, const CompilationContext& context, LinkBuffer& linkBuffer) 3293 { 3294 if (!context.procedure) 3295 return; 3296 3297 unsigned entrypointIndex = 0; 3298 unsigned numEntrypoints = context.procedure->numEntrypoints(); 3299 for (const UnlinkedHandlerInfo& handlerInfo : function->exceptionHandlers) { 3300 RELEASE_ASSERT(entrypointIndex < numEntrypoints); 3301 if (handlerInfo.m_type == HandlerType::Delegate) { 3302 handlers.append({ }); 3303 continue; 3304 } 3305 3306 ++entrypointIndex; 3307 handlers.append(linkBuffer.locationOf<ExceptionHandlerPtrTag>(context.procedure->code().entrypointLabel(entrypointIndex))); 3308 } 3309 RELEASE_ASSERT(entrypointIndex == numEntrypoints - 1); 3310 } 3311 2748 3312 // Custom wasm ops. These are the ones too messy to do in wasm.json. 2749 3313 2750 void B3IRGenerator::emitChecksForModOrDiv(B3::Opcode operation, ExpressionType left, ExpressionTyperight)3314 void B3IRGenerator::emitChecksForModOrDiv(B3::Opcode operation, Value* left, Value* right) 2751 3315 { 2752 3316 ASSERT(operation == Div || operation == Mod || operation == UDiv || operation == UMod); … … 2777 3341 2778 3342 template<> 2779 auto B3IRGenerator::addOp<OpType::I32DivS>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3343 auto B3IRGenerator::addOp<OpType::I32DivS>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2780 3344 { 2781 3345 const B3::Opcode op = Div; 3346 Value* left = get(leftVar); 3347 Value* right = get(rightVar); 2782 3348 emitChecksForModOrDiv(op, left, right); 2783 result = m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right);3349 result = push(m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right)); 2784 3350 return { }; 2785 3351 } 2786 3352 2787 3353 template<> 2788 auto B3IRGenerator::addOp<OpType::I32RemS>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3354 auto B3IRGenerator::addOp<OpType::I32RemS>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2789 3355 { 2790 3356 const B3::Opcode op = Mod; 3357 Value* left = get(leftVar); 3358 Value* right = get(rightVar); 2791 3359 emitChecksForModOrDiv(op, left, right); 2792 result = m_currentBlock->appendNew<Value>(m_proc, chill(op), origin(), left, right);3360 result = push(m_currentBlock->appendNew<Value>(m_proc, chill(op), origin(), left, right)); 2793 3361 return { }; 2794 3362 } 2795 3363 2796 3364 template<> 2797 auto B3IRGenerator::addOp<OpType::I32DivU>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3365 auto B3IRGenerator::addOp<OpType::I32DivU>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2798 3366 { 2799 3367 const B3::Opcode op = UDiv; 3368 Value* left = get(leftVar); 3369 Value* right = get(rightVar); 2800 3370 emitChecksForModOrDiv(op, left, right); 2801 result = m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right);3371 result = push(m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right)); 2802 3372 return { }; 2803 3373 } 2804 3374 2805 3375 template<> 2806 auto B3IRGenerator::addOp<OpType::I32RemU>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3376 auto B3IRGenerator::addOp<OpType::I32RemU>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2807 3377 { 2808 3378 const B3::Opcode op = UMod; 3379 Value* left = get(leftVar); 3380 Value* right = get(rightVar); 2809 3381 emitChecksForModOrDiv(op, left, right); 2810 result = m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right);3382 result = push(m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right)); 2811 3383 return { }; 2812 3384 } 2813 3385 2814 3386 template<> 2815 auto B3IRGenerator::addOp<OpType::I64DivS>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3387 auto B3IRGenerator::addOp<OpType::I64DivS>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2816 3388 { 2817 3389 const B3::Opcode op = Div; 3390 Value* left = get(leftVar); 3391 Value* right = get(rightVar); 2818 3392 emitChecksForModOrDiv(op, left, right); 2819 result = m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right);3393 result = push(m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right)); 2820 3394 return { }; 2821 3395 } 2822 3396 2823 3397 template<> 2824 auto B3IRGenerator::addOp<OpType::I64RemS>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3398 auto B3IRGenerator::addOp<OpType::I64RemS>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2825 3399 { 2826 3400 const B3::Opcode op = Mod; 3401 Value* left = get(leftVar); 3402 Value* right = get(rightVar); 2827 3403 emitChecksForModOrDiv(op, left, right); 2828 result = m_currentBlock->appendNew<Value>(m_proc, chill(op), origin(), left, right);3404 result = push(m_currentBlock->appendNew<Value>(m_proc, chill(op), origin(), left, right)); 2829 3405 return { }; 2830 3406 } 2831 3407 2832 3408 template<> 2833 auto B3IRGenerator::addOp<OpType::I64DivU>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3409 auto B3IRGenerator::addOp<OpType::I64DivU>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2834 3410 { 2835 3411 const B3::Opcode op = UDiv; 3412 Value* left = get(leftVar); 3413 Value* right = get(rightVar); 2836 3414 emitChecksForModOrDiv(op, left, right); 2837 result = m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right);3415 result = push(m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right)); 2838 3416 return { }; 2839 3417 } 2840 3418 2841 3419 template<> 2842 auto B3IRGenerator::addOp<OpType::I64RemU>(ExpressionType left , ExpressionType right, ExpressionType& result) -> PartialResult3420 auto B3IRGenerator::addOp<OpType::I64RemU>(ExpressionType leftVar, ExpressionType rightVar, ExpressionType& result) -> PartialResult 2843 3421 { 2844 3422 const B3::Opcode op = UMod; 3423 Value* left = get(leftVar); 3424 Value* right = get(rightVar); 2845 3425 emitChecksForModOrDiv(op, left, right); 2846 result = m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right);3426 result = push(m_currentBlock->appendNew<Value>(m_proc, op, origin(), left, right)); 2847 3427 return { }; 2848 3428 } 2849 3429 2850 3430 template<> 2851 auto B3IRGenerator::addOp<OpType::I32Ctz>(ExpressionType arg, ExpressionType& result) -> PartialResult 2852 { 3431 auto B3IRGenerator::addOp<OpType::I32Ctz>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3432 { 3433 Value* arg = get(argVar); 2853 3434 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int32, origin()); 2854 3435 patchpoint->append(arg, ValueRep::SomeRegister); … … 2857 3438 }); 2858 3439 patchpoint->effects = Effects::none(); 2859 result = p atchpoint;3440 result = push(patchpoint); 2860 3441 return { }; 2861 3442 } 2862 3443 2863 3444 template<> 2864 auto B3IRGenerator::addOp<OpType::I64Ctz>(ExpressionType arg, ExpressionType& result) -> PartialResult 2865 { 3445 auto B3IRGenerator::addOp<OpType::I64Ctz>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3446 { 3447 Value* arg = get(argVar); 2866 3448 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Int64, origin()); 2867 3449 patchpoint->append(arg, ValueRep::SomeRegister); … … 2870 3452 }); 2871 3453 patchpoint->effects = Effects::none(); 2872 result = p atchpoint;3454 result = push(patchpoint); 2873 3455 return { }; 2874 3456 } 2875 3457 2876 3458 template<> 2877 auto B3IRGenerator::addOp<OpType::I32Popcnt>(ExpressionType arg, ExpressionType& result) -> PartialResult 2878 { 3459 auto B3IRGenerator::addOp<OpType::I32Popcnt>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3460 { 3461 Value* arg = get(argVar); 2879 3462 #if CPU(X86_64) 2880 3463 if (MacroAssembler::supportsCountPopulation()) { … … 2885 3468 }); 2886 3469 patchpoint->effects = Effects::none(); 2887 result = p atchpoint;3470 result = push(patchpoint); 2888 3471 return { }; 2889 3472 } … … 2891 3474 2892 3475 Value* funcAddress = m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationPopcount32)); 2893 result = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(), Effects::none(), funcAddress, arg);3476 result = push(m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(), Effects::none(), funcAddress, arg)); 2894 3477 return { }; 2895 3478 } 2896 3479 2897 3480 template<> 2898 auto B3IRGenerator::addOp<OpType::I64Popcnt>(ExpressionType arg, ExpressionType& result) -> PartialResult 2899 { 3481 auto B3IRGenerator::addOp<OpType::I64Popcnt>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3482 { 3483 Value* arg = get(argVar); 2900 3484 #if CPU(X86_64) 2901 3485 if (MacroAssembler::supportsCountPopulation()) { … … 2906 3490 }); 2907 3491 patchpoint->effects = Effects::none(); 2908 result = p atchpoint;3492 result = push(patchpoint); 2909 3493 return { }; 2910 3494 } … … 2912 3496 2913 3497 Value* funcAddress = m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), tagCFunction<OperationPtrTag>(operationPopcount64)); 2914 result = m_currentBlock->appendNew<CCallValue>(m_proc, Int64, origin(), Effects::none(), funcAddress, arg);3498 result = push(m_currentBlock->appendNew<CCallValue>(m_proc, Int64, origin(), Effects::none(), funcAddress, arg)); 2915 3499 return { }; 2916 3500 } 2917 3501 2918 3502 template<> 2919 auto B3IRGenerator::addOp<F64ConvertUI64>(ExpressionType arg, ExpressionType& result) -> PartialResult 2920 { 3503 auto B3IRGenerator::addOp<F64ConvertUI64>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3504 { 3505 Value* arg = get(argVar); 2921 3506 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Double, origin()); 2922 3507 if (isX86()) … … 2933 3518 }); 2934 3519 patchpoint->effects = Effects::none(); 2935 result = p atchpoint;3520 result = push(patchpoint); 2936 3521 return { }; 2937 3522 } 2938 3523 2939 3524 template<> 2940 auto B3IRGenerator::addOp<OpType::F32ConvertUI64>(ExpressionType arg, ExpressionType& result) -> PartialResult 2941 { 3525 auto B3IRGenerator::addOp<OpType::F32ConvertUI64>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3526 { 3527 Value* arg = get(argVar); 2942 3528 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Float, origin()); 2943 3529 if (isX86()) … … 2954 3540 }); 2955 3541 patchpoint->effects = Effects::none(); 2956 result = p atchpoint;3542 result = push(patchpoint); 2957 3543 return { }; 2958 3544 } 2959 3545 2960 3546 template<> 2961 auto B3IRGenerator::addOp<OpType::F64Nearest>(ExpressionType arg, ExpressionType& result) -> PartialResult 2962 { 3547 auto B3IRGenerator::addOp<OpType::F64Nearest>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3548 { 3549 Value* arg = get(argVar); 2963 3550 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Double, origin()); 2964 3551 patchpoint->append(arg, ValueRep::SomeRegister); … … 2967 3554 }); 2968 3555 patchpoint->effects = Effects::none(); 2969 result = p atchpoint;3556 result = push(patchpoint); 2970 3557 return { }; 2971 3558 } 2972 3559 2973 3560 template<> 2974 auto B3IRGenerator::addOp<OpType::F32Nearest>(ExpressionType arg, ExpressionType& result) -> PartialResult 2975 { 3561 auto B3IRGenerator::addOp<OpType::F32Nearest>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3562 { 3563 Value* arg = get(argVar); 2976 3564 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Float, origin()); 2977 3565 patchpoint->append(arg, ValueRep::SomeRegister); … … 2980 3568 }); 2981 3569 patchpoint->effects = Effects::none(); 2982 result = p atchpoint;3570 result = push(patchpoint); 2983 3571 return { }; 2984 3572 } 2985 3573 2986 3574 template<> 2987 auto B3IRGenerator::addOp<OpType::F64Trunc>(ExpressionType arg, ExpressionType& result) -> PartialResult 2988 { 3575 auto B3IRGenerator::addOp<OpType::F64Trunc>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3576 { 3577 Value* arg = get(argVar); 2989 3578 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Double, origin()); 2990 3579 patchpoint->append(arg, ValueRep::SomeRegister); … … 2993 3582 }); 2994 3583 patchpoint->effects = Effects::none(); 2995 result = p atchpoint;3584 result = push(patchpoint); 2996 3585 return { }; 2997 3586 } 2998 3587 2999 3588 template<> 3000 auto B3IRGenerator::addOp<OpType::F32Trunc>(ExpressionType arg, ExpressionType& result) -> PartialResult 3001 { 3589 auto B3IRGenerator::addOp<OpType::F32Trunc>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3590 { 3591 Value* arg = get(argVar); 3002 3592 PatchpointValue* patchpoint = m_currentBlock->appendNew<PatchpointValue>(m_proc, Float, origin()); 3003 3593 patchpoint->append(arg, ValueRep::SomeRegister); … … 3006 3596 }); 3007 3597 patchpoint->effects = Effects::none(); 3008 result = p atchpoint;3598 result = push(patchpoint); 3009 3599 return { }; 3010 3600 } 3011 3601 3012 3602 template<> 3013 auto B3IRGenerator::addOp<OpType::I32TruncSF64>(ExpressionType arg, ExpressionType& result) -> PartialResult 3014 { 3603 auto B3IRGenerator::addOp<OpType::I32TruncSF64>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3604 { 3605 Value* arg = get(argVar); 3015 3606 Value* max = constant(Double, bitwise_cast<uint64_t>(-static_cast<double>(std::numeric_limits<int32_t>::min()))); 3016 3607 Value* min = constant(Double, bitwise_cast<uint64_t>(static_cast<double>(std::numeric_limits<int32_t>::min()) - 1.0)); … … 3029 3620 }); 3030 3621 patchpoint->effects = Effects::none(); 3031 result = p atchpoint;3622 result = push(patchpoint); 3032 3623 return { }; 3033 3624 } 3034 3625 3035 3626 template<> 3036 auto B3IRGenerator::addOp<OpType::I32TruncSF32>(ExpressionType arg, ExpressionType& result) -> PartialResult 3037 { 3627 auto B3IRGenerator::addOp<OpType::I32TruncSF32>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3628 { 3629 Value* arg = get(argVar); 3038 3630 Value* max = constant(Float, bitwise_cast<uint32_t>(-static_cast<float>(std::numeric_limits<int32_t>::min()))); 3039 3631 Value* min = constant(Float, bitwise_cast<uint32_t>(static_cast<float>(std::numeric_limits<int32_t>::min()))); … … 3052 3644 }); 3053 3645 patchpoint->effects = Effects::none(); 3054 result = p atchpoint;3646 result = push(patchpoint); 3055 3647 return { }; 3056 3648 } … … 3058 3650 3059 3651 template<> 3060 auto B3IRGenerator::addOp<OpType::I32TruncUF64>(ExpressionType arg, ExpressionType& result) -> PartialResult 3061 { 3652 auto B3IRGenerator::addOp<OpType::I32TruncUF64>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3653 { 3654 Value* arg = get(argVar); 3062 3655 Value* max = constant(Double, bitwise_cast<uint64_t>(static_cast<double>(std::numeric_limits<int32_t>::min()) * -2.0)); 3063 3656 Value* min = constant(Double, bitwise_cast<uint64_t>(-1.0)); … … 3076 3669 }); 3077 3670 patchpoint->effects = Effects::none(); 3078 result = p atchpoint;3671 result = push(patchpoint); 3079 3672 return { }; 3080 3673 } 3081 3674 3082 3675 template<> 3083 auto B3IRGenerator::addOp<OpType::I32TruncUF32>(ExpressionType arg, ExpressionType& result) -> PartialResult 3084 { 3676 auto B3IRGenerator::addOp<OpType::I32TruncUF32>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3677 { 3678 Value* arg = get(argVar); 3085 3679 Value* max = constant(Float, bitwise_cast<uint32_t>(static_cast<float>(std::numeric_limits<int32_t>::min()) * static_cast<float>(-2.0))); 3086 3680 Value* min = constant(Float, bitwise_cast<uint32_t>(static_cast<float>(-1.0))); … … 3099 3693 }); 3100 3694 patchpoint->effects = Effects::none(); 3101 result = p atchpoint;3695 result = push(patchpoint); 3102 3696 return { }; 3103 3697 } 3104 3698 3105 3699 template<> 3106 auto B3IRGenerator::addOp<OpType::I64TruncSF64>(ExpressionType arg, ExpressionType& result) -> PartialResult 3107 { 3700 auto B3IRGenerator::addOp<OpType::I64TruncSF64>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3701 { 3702 Value* arg = get(argVar); 3108 3703 Value* max = constant(Double, bitwise_cast<uint64_t>(-static_cast<double>(std::numeric_limits<int64_t>::min()))); 3109 3704 Value* min = constant(Double, bitwise_cast<uint64_t>(static_cast<double>(std::numeric_limits<int64_t>::min()))); … … 3122 3717 }); 3123 3718 patchpoint->effects = Effects::none(); 3124 result = p atchpoint;3719 result = push(patchpoint); 3125 3720 return { }; 3126 3721 } 3127 3722 3128 3723 template<> 3129 auto B3IRGenerator::addOp<OpType::I64TruncUF64>(ExpressionType arg, ExpressionType& result) -> PartialResult 3130 { 3724 auto B3IRGenerator::addOp<OpType::I64TruncUF64>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3725 { 3726 Value* arg = get(argVar); 3131 3727 Value* max = constant(Double, bitwise_cast<uint64_t>(static_cast<double>(std::numeric_limits<int64_t>::min()) * -2.0)); 3132 3728 Value* min = constant(Double, bitwise_cast<uint64_t>(-1.0)); … … 3165 3761 }); 3166 3762 patchpoint->effects = Effects::none(); 3167 result = p atchpoint;3763 result = push(patchpoint); 3168 3764 return { }; 3169 3765 } 3170 3766 3171 3767 template<> 3172 auto B3IRGenerator::addOp<OpType::I64TruncSF32>(ExpressionType arg, ExpressionType& result) -> PartialResult 3173 { 3768 auto B3IRGenerator::addOp<OpType::I64TruncSF32>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3769 { 3770 Value* arg = get(argVar); 3174 3771 Value* max = constant(Float, bitwise_cast<uint32_t>(-static_cast<float>(std::numeric_limits<int64_t>::min()))); 3175 3772 Value* min = constant(Float, bitwise_cast<uint32_t>(static_cast<float>(std::numeric_limits<int64_t>::min()))); … … 3188 3785 }); 3189 3786 patchpoint->effects = Effects::none(); 3190 result = p atchpoint;3787 result = push(patchpoint); 3191 3788 return { }; 3192 3789 } 3193 3790 3194 3791 template<> 3195 auto B3IRGenerator::addOp<OpType::I64TruncUF32>(ExpressionType arg, ExpressionType& result) -> PartialResult 3196 { 3792 auto B3IRGenerator::addOp<OpType::I64TruncUF32>(ExpressionType argVar, ExpressionType& result) -> PartialResult 3793 { 3794 Value* arg = get(argVar); 3197 3795 Value* max = constant(Float, bitwise_cast<uint32_t>(static_cast<float>(std::numeric_limits<int64_t>::min()) * static_cast<float>(-2.0))); 3198 3796 Value* min = constant(Float, bitwise_cast<uint32_t>(static_cast<float>(-1.0))); … … 3231 3829 }); 3232 3830 patchpoint->effects = Effects::none(); 3233 result = p atchpoint;3831 result = push(patchpoint); 3234 3832 return { }; 3235 3833 } -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h
r271775 r283852 41 41 extern "C" void dumpProcedure(void*); 42 42 43 namespace JSC { namespace Wasm { 43 namespace JSC { 44 45 namespace B3 { 46 class Procedure; 47 } 48 49 namespace Wasm { 44 50 45 51 class MemoryInformation; … … 49 55 std::unique_ptr<CCallHelpers> wasmEntrypointJIT; 50 56 std::unique_ptr<OpaqueByproducts> wasmEntrypointByproducts; 57 std::unique_ptr<B3::Procedure> procedure { nullptr }; 51 58 }; 52 59 53 60 Expected<std::unique_ptr<InternalFunction>, String> parseAndCompile(CompilationContext&, const FunctionData&, const Signature&, Vector<UnlinkedWasmToWasmCall>&, unsigned& osrEntryScratchBufferSize, const ModuleInformation&, MemoryMode, CompilationMode, uint32_t functionIndex, uint32_t loopIndexForOSREntry, TierUpCount* = nullptr); 54 61 62 void computeExceptionHandlerLocations(Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>& handlers, const InternalFunction*, const CompilationContext&, LinkBuffer&); 63 55 64 } } // namespace JSC::Wasm 56 65 -
trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.cpp
r278093 r283852 67 67 68 68 m_wasmInternalFunctions.resize(functions.size()); 69 m_exceptionHandlerLocations.resize(functions.size()); 69 70 m_compilationContexts.resize(functions.size()); 70 71 m_tierUpCounts.resize(functions.size()); … … 110 111 } 111 112 113 Vector<CodeLocationLabel<ExceptionHandlerPtrTag>> exceptionHandlerLocations; 114 computeExceptionHandlerLocations(exceptionHandlerLocations, function.get(), context, linkBuffer); 115 112 116 size_t functionIndexSpace = m_functionIndex + m_moduleInformation->importFunctionCount(); 113 117 SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[m_functionIndex]; … … 119 123 MacroAssemblerCodePtr<WasmEntryPtrTag> entrypoint; 120 124 { 121 Ref<BBQCallee> callee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(tierUp), WTFMove(unlinkedWasmToWasmCalls) );125 Ref<BBQCallee> callee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(tierUp), WTFMove(unlinkedWasmToWasmCalls), WTFMove(function->stackmaps), WTFMove(function->exceptionHandlers), WTFMove(exceptionHandlerLocations)); 122 126 MacroAssembler::repatchPointer(function->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr())); 123 127 ASSERT(!m_codeBlock->m_bbqCallees[m_functionIndex]); … … 195 199 if (Options::webAssemblyBBQAirModeThreshold() && m_moduleInformation->codeSectionSize >= Options::webAssemblyBBQAirModeThreshold()) 196 200 forceUsingB3 = true; 197 198 if (!forceUsingB3 && Options::wasmBBQUsesAir()) 201 else if (!m_moduleInformation->m_functionDoesNotUseExceptions.quickGet(functionIndex)) 202 forceUsingB3 = true; 203 else if (!Options::wasmBBQUsesAir()) 204 forceUsingB3 = true; 205 206 if (forceUsingB3) 207 parseAndCompileResult = parseAndCompile(context, function, signature, unlinkedWasmToWasmCalls, osrEntryScratchBufferSize, m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, UINT32_MAX, tierUp); 208 else 199 209 parseAndCompileResult = parseAndCompileAir(context, function, signature, unlinkedWasmToWasmCalls, m_moduleInformation.get(), m_mode, functionIndex, tierUp); 200 else201 parseAndCompileResult = parseAndCompile(context, function, signature, unlinkedWasmToWasmCalls, osrEntryScratchBufferSize, m_moduleInformation.get(), m_mode, CompilationMode::BBQMode, functionIndex, UINT32_MAX, tierUp);202 210 203 211 if (UNLIKELY(!parseAndCompileResult)) { … … 223 231 ASSERT(functionIndexSpace < m_moduleInformation->functionIndexSpaceSize()); 224 232 { 233 InternalFunction* function = m_wasmInternalFunctions[functionIndex].get(); 225 234 LinkBuffer linkBuffer(*context.wasmEntrypointJIT, nullptr, LinkBuffer::Profile::Wasm, JITCompilationCanFail); 226 235 if (UNLIKELY(linkBuffer.didFailToAllocate())) { … … 229 238 } 230 239 231 m_wasmInternalFunctions[functionIndex]->entrypoint.compilation = makeUnique<Compilation>( 240 computeExceptionHandlerLocations(m_exceptionHandlerLocations[functionIndex], function, context, linkBuffer); 241 function->entrypoint.compilation = makeUnique<Compilation>( 232 242 FINALIZE_CODE(linkBuffer, JITCompilationPtrTag, "WebAssembly BBQ function[%i] %s name %s", functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()), 233 243 WTFMove(context.wasmEntrypointByproducts)); … … 273 283 InternalFunction* function = m_wasmInternalFunctions[internalFunctionIndex].get(); 274 284 size_t functionIndexSpace = internalFunctionIndex + m_moduleInformation->importFunctionCount(); 275 Ref<BBQCallee> wasmEntrypointCallee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(m_tierUpCounts[internalFunctionIndex]), WTFMove(m_unlinkedWasmToWasmCalls[internalFunctionIndex]) );285 Ref<BBQCallee> wasmEntrypointCallee = BBQCallee::create(WTFMove(function->entrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(m_tierUpCounts[internalFunctionIndex]), WTFMove(m_unlinkedWasmToWasmCalls[internalFunctionIndex]), WTFMove(function->stackmaps), WTFMove(function->exceptionHandlers), WTFMove(m_exceptionHandlerLocations[internalFunctionIndex])); 276 286 MacroAssembler::repatchPointer(function->calleeMoveLocation, CalleeBits::boxWasm(wasmEntrypointCallee.ptr())); 277 287 -
trunk/Source/JavaScriptCore/wasm/WasmBBQPlan.h
r278093 r283852 84 84 85 85 Vector<std::unique_ptr<InternalFunction>> m_wasmInternalFunctions; 86 Vector<Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>> m_exceptionHandlerLocations; 86 87 HashMap<uint32_t, std::unique_ptr<InternalFunction>, DefaultHash<uint32_t>, WTF::UnsignedWithZeroKeyHashTraits<uint32_t>> m_embedderToWasmInternalFunctions; 87 88 Vector<CompilationContext> m_compilationContexts; -
trunk/Source/JavaScriptCore/wasm/WasmCallee.cpp
r261755 r283852 29 29 #if ENABLE(WEBASSEMBLY) 30 30 31 #include "LLIntExceptions.h" 31 32 #include "WasmCalleeRegistry.h" 32 33 #include "WasmCallingConvention.h" … … 57 58 } 58 59 60 const HandlerInfo* Callee::handlerForIndex(Instance& instance, unsigned index, const Tag* tag) 61 { 62 ASSERT(hasExceptionHandlers()); 63 return HandlerInfo::handlerForIndex(instance, m_exceptionHandlers, index, tag); 64 } 65 59 66 JITCallee::JITCallee(Wasm::CompilationMode compilationMode, Entrypoint&& entrypoint) 60 67 : Callee(compilationMode) … … 68 75 , m_entrypoint(WTFMove(entrypoint)) 69 76 { 77 } 78 79 LLIntCallee::LLIntCallee(std::unique_ptr<FunctionCodeBlock> codeBlock, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name) 80 : Callee(Wasm::CompilationMode::LLIntMode, index, WTFMove(name)) 81 , m_codeBlock(WTFMove(codeBlock)) 82 { 83 linkExceptionHandlers(); 84 } 85 86 void LLIntCallee::linkExceptionHandlers() 87 { 88 if (size_t count = m_codeBlock->numberOfExceptionHandlers()) { 89 m_exceptionHandlers.resizeToFit(count); 90 for (size_t i = 0; i < count; i++) { 91 const UnlinkedHandlerInfo& unlinkedHandler = m_codeBlock->exceptionHandler(i); 92 HandlerInfo& handler = m_exceptionHandlers[i]; 93 auto& instruction = *m_codeBlock->instructions().at(unlinkedHandler.m_target).ptr(); 94 CodeLocationLabel<ExceptionHandlerPtrTag> target; 95 if (unlinkedHandler.m_type == HandlerType::Catch) 96 target = CodeLocationLabel<ExceptionHandlerPtrTag>(LLInt::handleWasmCatch(instruction.width<WasmOpcodeTraits>()).code()); 97 else 98 target = CodeLocationLabel<ExceptionHandlerPtrTag>(LLInt::handleWasmCatchAll(instruction.width<WasmOpcodeTraits>()).code()); 99 100 handler.initialize(unlinkedHandler, target); 101 } 102 } 70 103 } 71 104 … … 105 138 } 106 139 140 void OptimizingJITCallee::linkExceptionHandlers() 141 { 142 size_t count = m_unlinkedExceptionHandlers.size(); 143 m_exceptionHandlers.resizeToFit(count); 144 for (size_t i = 0; i < count; i++) { 145 HandlerInfo& handler = m_exceptionHandlers[i]; 146 const UnlinkedHandlerInfo& unlinkedHandler = m_unlinkedExceptionHandlers[i]; 147 CodeLocationLabel<ExceptionHandlerPtrTag> location = m_exceptionHandlerLocations[i]; 148 handler.initialize(unlinkedHandler, location); 149 } 150 m_unlinkedExceptionHandlers.clear(); 151 m_exceptionHandlerLocations.clear(); 152 } 153 154 const Vector<OSREntryValue>& OptimizingJITCallee::stackmap(CallSiteIndex callSiteIndex) const 155 { 156 auto iter = m_stackmaps.find(callSiteIndex); 157 if (iter == m_stackmaps.end()) { 158 for (auto pair : m_stackmaps) { 159 dataLog(pair.key.bits(), ": "); 160 for (auto value : pair.value) 161 dataLog(value, ", "); 162 dataLogLn(""); 163 } 164 } 165 RELEASE_ASSERT(iter != m_stackmaps.end()); 166 return iter->value; 167 } 168 169 107 170 } } // namespace JSC::Wasm 108 171 -
trunk/Source/JavaScriptCore/wasm/WasmCallee.h
r271775 r283852 33 33 #include "WasmFormat.h" 34 34 #include "WasmFunctionCodeBlock.h" 35 #include "WasmHandlerInfo.h" 35 36 #include "WasmIndexOrName.h" 37 #include "WasmLLIntTierUpCounter.h" 36 38 #include "WasmTierUpCount.h" 37 39 #include <wtf/ThreadSafeRefCounted.h> … … 60 62 virtual std::tuple<void*, void*> range() const = 0; 61 63 64 const HandlerInfo* handlerForIndex(Instance&, unsigned, const Tag*); 65 66 bool hasExceptionHandlers() const { return !!m_exceptionHandlers.size(); } 67 62 68 #if ENABLE(WEBASSEMBLY_B3JIT) 63 69 virtual void setOSREntryCallee(Ref<OMGForOSREntryCallee>&&) … … 68 74 69 75 void dump(PrintStream&) const; 76 77 virtual FunctionCodeBlock* functionCodeBlock() const { return 0; } 70 78 71 79 protected: … … 76 84 CompilationMode m_compilationMode; 77 85 IndexOrName m_indexOrName; 86 87 protected: 88 Vector<HandlerInfo> m_exceptionHandlers; 78 89 }; 79 90 … … 100 111 }; 101 112 102 #if ENABLE(WEBASSEMBLY_B3JIT) 103 class OMGCallee final : public JITCallee { 104 public: 105 static Ref<OMGCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls) 106 { 107 return adoptRef(*new OMGCallee(WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls))); 108 } 109 110 private: 111 OMGCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls) 112 : JITCallee(Wasm::CompilationMode::OMGMode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls)) 113 { 114 } 115 }; 116 117 class OMGForOSREntryCallee final : public JITCallee { 118 public: 119 static Ref<OMGForOSREntryCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, unsigned osrEntryScratchBufferSize, uint32_t loopIndex, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls) 120 { 121 return adoptRef(*new OMGForOSREntryCallee(WTFMove(entrypoint), index, WTFMove(name), osrEntryScratchBufferSize, loopIndex, WTFMove(unlinkedCalls))); 113 class EmbedderEntrypointCallee final : public JITCallee { 114 public: 115 static Ref<EmbedderEntrypointCallee> create(Wasm::Entrypoint&& entrypoint) 116 { 117 return adoptRef(*new EmbedderEntrypointCallee(WTFMove(entrypoint))); 118 } 119 120 private: 121 EmbedderEntrypointCallee(Wasm::Entrypoint&& entrypoint) 122 : JITCallee(Wasm::CompilationMode::EmbedderEntrypointMode, WTFMove(entrypoint)) 123 { 124 } 125 }; 126 127 128 #if ENABLE(WEBASSEMBLY_B3JIT) 129 class OptimizingJITCallee : public JITCallee { 130 public: 131 const Vector<OSREntryValue>& stackmap(CallSiteIndex) const; 132 133 protected: 134 OptimizingJITCallee(Wasm::CompilationMode mode, Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, HashMap<CallSiteIndex, Vector<OSREntryValue>>&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 135 : JITCallee(mode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls)) 136 , m_stackmaps(WTFMove(stackmaps)) 137 , m_unlinkedExceptionHandlers(WTFMove(exceptionHandlers)) 138 , m_exceptionHandlerLocations(WTFMove(exceptionHandlerLocations)) 139 { 140 RELEASE_ASSERT(m_unlinkedExceptionHandlers.size() == m_exceptionHandlerLocations.size()); 141 linkExceptionHandlers(); 142 } 143 144 private: 145 void linkExceptionHandlers(); 146 147 HashMap<CallSiteIndex, Vector<OSREntryValue>> m_stackmaps; 148 Vector<UnlinkedHandlerInfo> m_unlinkedExceptionHandlers; 149 Vector<CodeLocationLabel<ExceptionHandlerPtrTag>> m_exceptionHandlerLocations; 150 }; 151 152 class OMGCallee final : public OptimizingJITCallee { 153 public: 154 static Ref<OMGCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, HashMap<CallSiteIndex, Vector<OSREntryValue>>&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 155 { 156 return adoptRef(*new OMGCallee(WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations))); 157 } 158 159 private: 160 OMGCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, HashMap<CallSiteIndex, Vector<OSREntryValue>>&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 161 : OptimizingJITCallee(Wasm::CompilationMode::OMGMode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations)) 162 { 163 } 164 }; 165 166 class OMGForOSREntryCallee final : public OptimizingJITCallee { 167 public: 168 static Ref<OMGForOSREntryCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, unsigned osrEntryScratchBufferSize, uint32_t loopIndex, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, HashMap<CallSiteIndex, Vector<OSREntryValue>>&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 169 { 170 return adoptRef(*new OMGForOSREntryCallee(WTFMove(entrypoint), index, WTFMove(name), osrEntryScratchBufferSize, loopIndex, WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations))); 122 171 } 123 172 … … 126 175 127 176 private: 128 OMGForOSREntryCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, unsigned osrEntryScratchBufferSize, uint32_t loopIndex, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls )129 : JITCallee(Wasm::CompilationMode::OMGForOSREntryMode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls))177 OMGForOSREntryCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, unsigned osrEntryScratchBufferSize, uint32_t loopIndex, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, HashMap<CallSiteIndex, Vector<OSREntryValue>>&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 178 : OptimizingJITCallee(Wasm::CompilationMode::OMGForOSREntryMode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations)) 130 179 , m_osrEntryScratchBufferSize(osrEntryScratchBufferSize) 131 180 , m_loopIndex(loopIndex) … … 136 185 uint32_t m_loopIndex; 137 186 }; 138 #endif 139 140 class EmbedderEntrypointCallee final : public JITCallee { 141 public: 142 static Ref<EmbedderEntrypointCallee> create(Wasm::Entrypoint&& entrypoint) 143 { 144 return adoptRef(*new EmbedderEntrypointCallee(WTFMove(entrypoint))); 145 } 146 147 private: 148 EmbedderEntrypointCallee(Wasm::Entrypoint&& entrypoint) 149 : JITCallee(Wasm::CompilationMode::EmbedderEntrypointMode, WTFMove(entrypoint)) 150 { 151 } 152 }; 153 154 #if ENABLE(WEBASSEMBLY_B3JIT) 155 class BBQCallee final : public JITCallee { 156 public: 157 static Ref<BBQCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls) 158 { 159 return adoptRef(*new BBQCallee(WTFMove(entrypoint), index, WTFMove(name), WTFMove(tierUpCount), WTFMove(unlinkedCalls))); 187 188 class BBQCallee final : public OptimizingJITCallee { 189 public: 190 static Ref<BBQCallee> create(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, HashMap<CallSiteIndex, Vector<OSREntryValue>>&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 191 { 192 return adoptRef(*new BBQCallee(WTFMove(entrypoint), index, WTFMove(name), WTFMove(tierUpCount), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations))); 160 193 } 161 194 … … 178 211 179 212 private: 180 BBQCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls )181 : JITCallee(Wasm::CompilationMode::BBQMode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls))213 BBQCallee(Wasm::Entrypoint&& entrypoint, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name, std::unique_ptr<TierUpCount>&& tierUpCount, Vector<UnlinkedWasmToWasmCall>&& unlinkedCalls, HashMap<CallSiteIndex, Vector<OSREntryValue>>&& stackmaps, Vector<UnlinkedHandlerInfo>&& exceptionHandlers, Vector<CodeLocationLabel<ExceptionHandlerPtrTag>>&& exceptionHandlerLocations) 214 : OptimizingJITCallee(Wasm::CompilationMode::BBQMode, WTFMove(entrypoint), index, WTFMove(name), WTFMove(unlinkedCalls), WTFMove(stackmaps), WTFMove(exceptionHandlers), WTFMove(exceptionHandlerLocations)) 182 215 , m_tierUpCount(WTFMove(tierUpCount)) 183 216 { … … 219 252 220 253 LLIntTierUpCounter& tierUpCounter() { return m_codeBlock->tierUpCounter(); } 221 #endif 222 223 private: 224 LLIntCallee(std::unique_ptr<FunctionCodeBlock> codeBlock, size_t index, std::pair<const Name*, RefPtr<NameSection>>&& name) 225 : Callee(Wasm::CompilationMode::LLIntMode, index, WTFMove(name)) 226 , m_codeBlock(WTFMove(codeBlock)) 227 { 228 RELEASE_ASSERT(m_codeBlock); 229 } 254 FunctionCodeBlock* functionCodeBlock() const final { return m_codeBlock.get(); } 255 #endif 256 257 private: 258 LLIntCallee(std::unique_ptr<FunctionCodeBlock>, size_t index, std::pair<const Name*, RefPtr<NameSection>>&&); 259 260 void linkExceptionHandlers(); 230 261 231 262 #if ENABLE(WEBASSEMBLY_B3JIT) -
trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h
r279265 r283852 126 126 size_t gpArgumentCount = 0; 127 127 size_t fpArgumentCount = 0; 128 size_t argStackOffset = headerSizeInBytes ;128 size_t argStackOffset = headerSizeInBytes + sizeof(Register); 129 129 if (role == CallRole::Caller) 130 130 argStackOffset -= sizeof(CallerFrameAndPC); … … 137 137 gpArgumentCount = 0; 138 138 fpArgumentCount = 0; 139 size_t resultStackOffset = headerSizeInBytes ;139 size_t resultStackOffset = headerSizeInBytes + sizeof(Register); 140 140 if (role == CallRole::Caller) 141 141 resultStackOffset -= sizeof(CallerFrameAndPC); -
trunk/Source/JavaScriptCore/wasm/WasmFormat.h
r281438 r283852 30 30 #include "CodeLocation.h" 31 31 #include "Identifier.h" 32 #include "JSString.h" 32 33 #include "MacroAssemblerCodeRef.h" 33 34 #include "RegisterAtOffsetList.h" … … 35 36 #include "WasmName.h" 36 37 #include "WasmNameSection.h" 38 #include "WasmOSREntryData.h" 37 39 #include "WasmOps.h" 38 40 #include "WasmPageCount.h" … … 51 53 struct CompilationContext; 52 54 struct ModuleInformation; 55 struct UnlinkedHandlerInfo; 53 56 54 57 using BlockSignature = const Signature*; … … 77 80 } 78 81 82 inline JSString* typeToString(VM& vm, TypeKind type) 83 { 84 #define TYPE_CASE(macroName, value, b3, inc, wasmName) \ 85 case TypeKind::macroName: \ 86 return jsNontrivialString(vm, #wasmName); \ 87 88 switch (type) { 89 FOR_EACH_WASM_TYPE(TYPE_CASE) 90 } 91 92 #undef TYPE_CASE 93 } 94 79 95 inline bool isSubtype(Type sub, Type parent) 80 96 { … … 116 132 Memory = 2, 117 133 Global = 3, 134 Exception = 4, 118 135 }; 119 136 … … 126 143 case static_cast<Int>(ExternalKind::Memory): 127 144 case static_cast<Int>(ExternalKind::Global): 145 case static_cast<Int>(ExternalKind::Exception): 128 146 return true; 129 147 } … … 135 153 static_assert(static_cast<int>(ExternalKind::Memory) == 2, "Wasm needs Memory to have the value 2"); 136 154 static_assert(static_cast<int>(ExternalKind::Global) == 3, "Wasm needs Global to have the value 3"); 155 static_assert(static_cast<int>(ExternalKind::Exception) == 4, "Wasm needs Exception to have the value 4"); 137 156 138 157 inline const char* makeString(ExternalKind kind) … … 143 162 case ExternalKind::Memory: return "memory"; 144 163 case ExternalKind::Global: return "global"; 164 case ExternalKind::Exception: return "tag"; 145 165 } 146 166 RELEASE_ASSERT_NOT_REACHED(); … … 373 393 WTF_MAKE_STRUCT_FAST_ALLOCATED; 374 394 CodeLocationDataLabelPtr<WasmEntryPtrTag> calleeMoveLocation; 395 StackMaps stackmaps; 396 Vector<UnlinkedHandlerInfo> exceptionHandlers; 375 397 Entrypoint entrypoint; 376 398 }; -
trunk/Source/JavaScriptCore/wasm/WasmFunctionCodeBlock.h
r276609 r283852 1 1 /* 2 * Copyright (C) 2019 Apple Inc. All rights reserved.2 * Copyright (C) 2019-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 30 30 #include "BytecodeConventions.h" 31 #include "HandlerInfo.h" 31 32 #include "InstructionStream.h" 32 33 #include "MacroAssemblerCodeRef.h" 34 #include "WasmHandlerInfo.h" 33 35 #include "WasmLLIntTierUpCounter.h" 34 36 #include "WasmOps.h" … … 121 123 unsigned numberOfJumpTables() const; 122 124 125 size_t numberOfExceptionHandlers() const { return m_exceptionHandlers.size(); } 126 UnlinkedHandlerInfo& exceptionHandler(int index) { return m_exceptionHandlers[index]; } 127 void addExceptionHandler(const UnlinkedHandlerInfo& handler) { m_exceptionHandlers.append(handler); } 128 123 129 private: 124 130 using OutOfLineJumpTargets = HashMap<InstructionStream::Offset, int>; … … 140 146 LLIntTierUpCounter m_tierUpCounter; 141 147 Vector<JumpTable> m_jumpTables; 148 Vector<UnlinkedHandlerInfo> m_exceptionHandlers; 142 149 }; 143 150 -
trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h
r281438 r283852 38 38 Block, 39 39 Loop, 40 TopLevel 40 TopLevel, 41 Try, 42 Catch, 43 }; 44 45 enum class CatchKind { 46 Catch, 47 CatchAll, 41 48 }; 42 49 … … 148 155 PartialResult WARN_UNUSED_RETURN parseIndexForGlobal(uint32_t&); 149 156 PartialResult WARN_UNUSED_RETURN parseFunctionIndex(uint32_t&); 157 PartialResult WARN_UNUSED_RETURN parseExceptionIndex(uint32_t&); 150 158 PartialResult WARN_UNUSED_RETURN parseBranchTarget(uint32_t&); 151 159 … … 211 219 unsigned m_loopIndex { 0 }; 212 220 }; 221 222 template<typename ControlType> 223 static bool isTryOrCatch(ControlType& data) 224 { 225 return ControlType::isTry(data) || ControlType::isCatch(data); 226 } 213 227 214 228 template<typename Context> … … 573 587 WASM_PARSER_FAIL_IF(functionIndex >= m_info.functionIndexSpaceSize(), "function index ", functionIndex, " exceeds function index space ", m_info.functionIndexSpaceSize()); 574 588 resultIndex = functionIndex; 589 return { }; 590 } 591 592 template<typename Context> 593 auto FunctionParser<Context>::parseExceptionIndex(uint32_t& result) -> PartialResult 594 { 595 uint32_t exceptionIndex; 596 WASM_PARSER_FAIL_IF(!parseVarUInt32(exceptionIndex), "can't parse exception index"); 597 WASM_VALIDATOR_FAIL_IF(exceptionIndex >= m_info.exceptionIndexSpaceSize(), "exception index ", exceptionIndex, " is invalid, limit is ", m_info.exceptionIndexSpaceSize()); 598 result = exceptionIndex; 575 599 return { }; 576 600 } … … 1334 1358 } 1335 1359 1360 case Try: { 1361 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1362 1363 BlockSignature inlineSignature; 1364 WASM_PARSER_FAIL_IF(!parseBlockSignature(m_info, inlineSignature), "can't get try's signature"); 1365 1366 WASM_VALIDATOR_FAIL_IF(m_expressionStack.size() < inlineSignature->argumentCount(), "Too few arguments on stack for try block. Trye expects ", inlineSignature->argumentCount(), ", but only ", m_expressionStack.size(), " were present. Try block has signature: ", inlineSignature->toString()); 1367 unsigned offset = m_expressionStack.size() - inlineSignature->argumentCount(); 1368 for (unsigned i = 0; i < inlineSignature->argumentCount(); ++i) 1369 WASM_VALIDATOR_FAIL_IF(m_expressionStack[offset + i].type() != inlineSignature->argument(i), "Try expects the argument at index", i, " to be ", inlineSignature->argument(i).kind, " but argument has type ", m_expressionStack[i].type().kind); 1370 1371 int64_t oldSize = m_expressionStack.size(); 1372 Stack newStack; 1373 ControlType control; 1374 WASM_TRY_ADD_TO_CONTEXT(addTry(inlineSignature, m_expressionStack, control, newStack)); 1375 ASSERT_UNUSED(oldSize, oldSize - m_expressionStack.size() == inlineSignature->argumentCount()); 1376 ASSERT(newStack.size() == inlineSignature->argumentCount()); 1377 1378 m_controlStack.append({ WTFMove(m_expressionStack), { }, WTFMove(control) }); 1379 m_expressionStack = WTFMove(newStack); 1380 return { }; 1381 } 1382 1383 case Catch: { 1384 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1385 1386 WASM_PARSER_FAIL_IF(m_controlStack.size() == 1, "can't use catch block at the top-level of a function"); 1387 1388 uint32_t exceptionIndex; 1389 WASM_FAIL_IF_HELPER_FAILS(parseExceptionIndex(exceptionIndex)); 1390 SignatureIndex signatureIndex = m_info.signatureIndexFromExceptionIndexSpace(exceptionIndex); 1391 const Signature& exceptionSignature = SignatureInformation::get(signatureIndex); 1392 1393 ControlEntry& controlEntry = m_controlStack.last(); 1394 WASM_VALIDATOR_FAIL_IF(!isTryOrCatch(controlEntry.controlData), "catch block isn't associated to a try"); 1395 WASM_FAIL_IF_HELPER_FAILS(unify(controlEntry.controlData)); 1396 1397 ResultList results; 1398 Stack preCatchStack; 1399 m_expressionStack.swap(preCatchStack); 1400 WASM_TRY_ADD_TO_CONTEXT(addCatch(exceptionIndex, exceptionSignature, preCatchStack, controlEntry.controlData, results)); 1401 1402 RELEASE_ASSERT(exceptionSignature.argumentCount() == results.size()); 1403 for (unsigned i = 0; i < exceptionSignature.argumentCount(); ++i) 1404 m_expressionStack.constructAndAppend(exceptionSignature.argument(i), results[i]); 1405 return { }; 1406 } 1407 1408 case CatchAll: { 1409 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1410 1411 WASM_PARSER_FAIL_IF(m_controlStack.size() == 1, "can't use catch block at the top-level of a function"); 1412 1413 ControlEntry& controlEntry = m_controlStack.last(); 1414 1415 WASM_VALIDATOR_FAIL_IF(!isTryOrCatch(controlEntry.controlData), "catch block isn't associated to a try"); 1416 WASM_FAIL_IF_HELPER_FAILS(unify(controlEntry.controlData)); 1417 1418 ResultList results; 1419 Stack preCatchStack; 1420 m_expressionStack.swap(preCatchStack); 1421 WASM_TRY_ADD_TO_CONTEXT(addCatchAll(preCatchStack, controlEntry.controlData)); 1422 return { }; 1423 } 1424 1425 case Delegate: { 1426 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1427 1428 WASM_PARSER_FAIL_IF(m_controlStack.size() == 1, "can't use delegate at the top-level of a function"); 1429 1430 uint32_t target; 1431 WASM_FAIL_IF_HELPER_FAILS(parseBranchTarget(target)); 1432 1433 ControlEntry controlEntry = m_controlStack.takeLast(); 1434 WASM_VALIDATOR_FAIL_IF(!ControlType::isTry(controlEntry.controlData), "delegate isn't associated to a try"); 1435 1436 ControlType& targetData = m_controlStack[m_controlStack.size() - 1 - target].controlData; 1437 WASM_VALIDATOR_FAIL_IF(!ControlType::isTry(targetData) && !ControlType::isTopLevel(targetData), "delegate target isn't a try or the top level block"); 1438 1439 WASM_TRY_ADD_TO_CONTEXT(addDelegate(targetData, controlEntry.controlData)); 1440 WASM_FAIL_IF_HELPER_FAILS(unify(controlEntry.controlData)); 1441 WASM_TRY_ADD_TO_CONTEXT(endBlock(controlEntry, m_expressionStack)); 1442 m_expressionStack.swap(controlEntry.enclosedExpressionStack); 1443 return { }; 1444 } 1445 1446 case Throw: { 1447 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1448 1449 uint32_t exceptionIndex; 1450 WASM_FAIL_IF_HELPER_FAILS(parseExceptionIndex(exceptionIndex)); 1451 SignatureIndex signatureIndex = m_info.signatureIndexFromExceptionIndexSpace(exceptionIndex); 1452 const Signature& exceptionSignature = SignatureInformation::get(signatureIndex); 1453 1454 WASM_VALIDATOR_FAIL_IF(m_expressionStack.size() < exceptionSignature.argumentCount(), "Too few arguments on stack for the exception being thrown. The exception expects ", exceptionSignature.argumentCount(), ", but only ", m_expressionStack.size(), " were present. Exception has signature: ", exceptionSignature.toString()); 1455 unsigned offset = m_expressionStack.size() - exceptionSignature.argumentCount(); 1456 Vector<ExpressionType> args; 1457 WASM_PARSER_FAIL_IF(!args.tryReserveCapacity(exceptionSignature.argumentCount()), "can't allocate enough memory for throw's ", exceptionSignature.argumentCount(), " arguments"); 1458 for (unsigned i = 0; i < exceptionSignature.argumentCount(); ++i) { 1459 TypedExpression arg = m_expressionStack.at(offset + i); 1460 WASM_VALIDATOR_FAIL_IF(arg.type() != exceptionSignature.argument(i), "The exception being thrown expects the argument at index ", i, " to be ", exceptionSignature.argument(i).kind, " but argument has type ", arg.type().kind); 1461 args.uncheckedAppend(arg); 1462 m_context.didPopValueFromStack(); 1463 } 1464 m_expressionStack.shrink(offset); 1465 1466 WASM_TRY_ADD_TO_CONTEXT(addThrow(exceptionIndex, args, m_expressionStack)); 1467 m_unreachableBlocks = 1; 1468 return { }; 1469 } 1470 1471 case Rethrow: { 1472 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1473 1474 uint32_t target; 1475 WASM_FAIL_IF_HELPER_FAILS(parseBranchTarget(target)); 1476 1477 ControlType& data = m_controlStack[m_controlStack.size() - 1 - target].controlData; 1478 WASM_VALIDATOR_FAIL_IF(!ControlType::isAnyCatch(data), "rethrow doesn't refer to a catch block"); 1479 1480 WASM_TRY_ADD_TO_CONTEXT(addRethrow(target, data)); 1481 m_unreachableBlocks = 1; 1482 return { }; 1483 } 1484 1336 1485 case Br: 1337 1486 case BrIf: { … … 1485 1634 WASM_TRY_ADD_TO_CONTEXT(addElseToUnreachable(data.controlData)); 1486 1635 m_expressionStack = WTFMove(data.elseBlockStack); 1636 return { }; 1637 } 1638 1639 case Catch: { 1640 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1641 1642 uint32_t exceptionIndex; 1643 WASM_FAIL_IF_HELPER_FAILS(parseExceptionIndex(exceptionIndex)); 1644 SignatureIndex signatureIndex = m_info.signatureIndexFromExceptionIndexSpace(exceptionIndex); 1645 const Signature& exceptionSignature = SignatureInformation::get(signatureIndex); 1646 1647 if (m_unreachableBlocks > 1) 1648 return { }; 1649 1650 ControlEntry& data = m_controlStack.last(); 1651 WASM_VALIDATOR_FAIL_IF(!isTryOrCatch(data.controlData), "catch block isn't associated to a try"); 1652 1653 m_unreachableBlocks = 0; 1654 m_expressionStack = { }; 1655 ResultList results; 1656 WASM_TRY_ADD_TO_CONTEXT(addCatchToUnreachable(exceptionIndex, exceptionSignature, data.controlData, results)); 1657 1658 RELEASE_ASSERT(exceptionSignature.argumentCount() == results.size()); 1659 for (unsigned i = 0; i < exceptionSignature.argumentCount(); ++i) 1660 m_expressionStack.constructAndAppend(exceptionSignature.argument(i), results[i]); 1661 return { }; 1662 } 1663 1664 case CatchAll: { 1665 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1666 1667 if (m_unreachableBlocks > 1) 1668 return { }; 1669 1670 ControlEntry& data = m_controlStack.last(); 1671 m_unreachableBlocks = 0; 1672 m_expressionStack = { }; 1673 WASM_VALIDATOR_FAIL_IF(!isTryOrCatch(data.controlData), "catch block isn't associated to a try"); 1674 WASM_TRY_ADD_TO_CONTEXT(addCatchAllToUnreachable(data.controlData)); 1675 return { }; 1676 } 1677 1678 case Delegate: { 1679 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1680 1681 WASM_PARSER_FAIL_IF(m_controlStack.size() == 1, "can't use delegate at the top-level of a function"); 1682 1683 uint32_t target; 1684 WASM_FAIL_IF_HELPER_FAILS(parseBranchTarget(target)); 1685 1686 ControlEntry controlEntry = m_controlStack.takeLast(); 1687 WASM_VALIDATOR_FAIL_IF(!ControlType::isTry(controlEntry.controlData), "delegate isn't associated to a try"); 1688 1689 ControlType& data = m_controlStack[m_controlStack.size() - 1 - target].controlData; 1690 WASM_VALIDATOR_FAIL_IF(!ControlType::isTry(data) && !ControlType::isTopLevel(data), "delegate target isn't a try block"); 1691 1692 WASM_TRY_ADD_TO_CONTEXT(addDelegateToUnreachable(data, controlEntry.controlData)); 1693 Stack emptyStack; 1694 WASM_TRY_ADD_TO_CONTEXT(addEndToUnreachable(controlEntry, emptyStack)); 1695 m_expressionStack.swap(controlEntry.enclosedExpressionStack); 1487 1696 return { }; 1488 1697 } … … 1496 1705 WASM_FAIL_IF_HELPER_FAILS(unify(data.controlData)); 1497 1706 WASM_TRY_ADD_TO_CONTEXT(endBlock(data, m_expressionStack)); 1498 } else 1499 WASM_TRY_ADD_TO_CONTEXT(addEndToUnreachable(data)); 1707 } else { 1708 Stack emptyStack; 1709 WASM_TRY_ADD_TO_CONTEXT(addEndToUnreachable(data, emptyStack)); 1710 } 1500 1711 1501 1712 m_expressionStack.swap(data.enclosedExpressionStack); … … 1504 1715 return { }; 1505 1716 } 1717 1718 case Try: 1719 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1720 FALLTHROUGH; 1506 1721 1507 1722 case Loop: … … 1577 1792 } 1578 1793 1794 case Rethrow: { 1795 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1796 uint32_t target; 1797 WASM_FAIL_IF_HELPER_FAILS(parseBranchTarget(target)); 1798 1799 ControlType& data = m_controlStack[m_controlStack.size() - 1 - target].controlData; 1800 WASM_VALIDATOR_FAIL_IF(!ControlType::isAnyCatch(data), "rethrow doesn't refer to a catch block"); 1801 return { }; 1802 } 1803 1579 1804 case Br: 1580 1805 case BrIf: { 1581 1806 uint32_t target; 1582 1807 WASM_FAIL_IF_HELPER_FAILS(parseBranchTarget(target)); 1808 return { }; 1809 } 1810 1811 case Throw: { 1812 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 1813 1814 uint32_t exceptionIndex; 1815 WASM_FAIL_IF_HELPER_FAILS(parseExceptionIndex(exceptionIndex)); 1816 1583 1817 return { }; 1584 1818 } -
trunk/Source/JavaScriptCore/wasm/WasmInstance.cpp
r278338 r283852 35 35 #include "WasmModuleInformation.h" 36 36 #include "WasmSignatureInlines.h" 37 #include "WasmTag.h" 37 38 #include <wtf/CheckedArithmetic.h> 38 39 … … 91 92 } 92 93 93 Instance::~Instance() { } 94 Instance::~Instance() 95 { 96 } 94 97 95 98 size_t Instance::extraMemoryAllocated() const … … 298 301 } 299 302 303 void Instance::addTag(const Tag& tag) 304 { 305 m_tags.append(Ref { tag }); 306 } 307 308 void Instance::addTag(Ref<Tag>&& tag) 309 { 310 m_tags.append(WTFMove(tag)); 311 } 312 300 313 } } // namespace JSC::Wasm 301 314 -
trunk/Source/JavaScriptCore/wasm/WasmInstance.h
r278338 r283852 211 211 } 212 212 213 void addTag(const Tag&); 214 void addTag(Ref<Tag>&&); 215 const Tag& tag(unsigned i) const { return *m_tags[i]; } 216 213 217 private: 214 218 Instance(Context*, Ref<Module>&&, EntryFrame**, void**, StoreTopCallFrameCallback&&); … … 238 242 BitVector m_passiveElements; 239 243 BitVector m_passiveDataSegments; 244 Vector<RefPtr<const Tag>> m_tags; 240 245 }; 241 246 -
trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp
r280507 r283852 63 63 }; 64 64 65 struct ControlType : public Variant<ControlLoop, ControlTopLevel, ControlBlock, ControlIf> { 66 using Base = Variant<ControlLoop, ControlTopLevel, ControlBlock, ControlIf>; 65 struct ControlTry { 66 Ref<Label> m_try; 67 unsigned m_tryDepth; 68 }; 69 70 struct ControlCatch { 71 CatchKind m_kind; 72 Ref<Label> m_tryStart; 73 Ref<Label> m_tryEnd; 74 unsigned m_tryDepth; 75 VirtualRegister m_exception; 76 }; 77 78 struct CatchRewriteInfo { 79 unsigned m_instructionOffset; 80 unsigned m_tryDepth; 81 }; 82 83 struct ControlType : public Variant<ControlLoop, ControlTopLevel, ControlBlock, ControlIf, ControlTry, ControlCatch> { 84 using Base = Variant<ControlLoop, ControlTopLevel, ControlBlock, ControlIf, ControlTry, ControlCatch>; 67 85 68 86 ControlType() … … 91 109 } 92 110 111 static ControlType createTry(BlockSignature signature, unsigned stackSize, Ref<Label>&& tryLabel, RefPtr<Label>&& continuation, unsigned tryDepth) 112 { 113 return ControlType(signature, stackSize - signature->argumentCount(), WTFMove(continuation), ControlTry { WTFMove(tryLabel), tryDepth }); 114 } 115 116 static ControlType createCatch(BlockSignature signature, unsigned stackSize, Ref<Label>&& tryStart, RefPtr<Label>&& continuation, Ref<Label> tryEnd, unsigned tryDepth, VirtualRegister exception) 117 { 118 return ControlType(signature, stackSize - signature->argumentCount(), WTFMove(continuation), ControlCatch { CatchKind::Catch, WTFMove(tryStart), WTFMove(tryEnd), tryDepth, exception }); 119 } 120 121 static bool isLoop(const ControlType& control) { return WTF::holds_alternative<ControlLoop>(control); } 122 static bool isTopLevel(const ControlType& control) { return WTF::holds_alternative<ControlTopLevel>(control); } 123 static bool isBlock(const ControlType& control) { return WTF::holds_alternative<ControlBlock>(control); } 93 124 static bool isIf(const ControlType& control) { return WTF::holds_alternative<ControlIf>(control); } 94 static bool isTopLevel(const ControlType& control) { return WTF::holds_alternative<ControlTopLevel>(control); } 125 static bool isTry(const ControlType& control) { return WTF::holds_alternative<ControlTry>(control); } 126 static bool isAnyCatch(const ControlType& control) { return WTF::holds_alternative<ControlCatch>(control); } 127 static bool isCatch(const ControlType& control) 128 { 129 if (!WTF::holds_alternative<ControlCatch>(control)) 130 return false; 131 ControlCatch catchData = WTF::get<ControlCatch>(control); 132 return catchData.m_kind == CatchKind::Catch; 133 } 95 134 96 135 unsigned stackSize() const { return m_stackSize; } … … 153 192 } 154 193 155 LLIntGenerator( constModuleInformation&, unsigned functionIndex, const Signature&);194 LLIntGenerator(ModuleInformation&, unsigned functionIndex, const Signature&); 156 195 157 196 std::unique_ptr<FunctionCodeBlock> finalize(); 197 198 template<typename Opcode> 199 void repatch(const CatchRewriteInfo&); 158 200 159 201 template<typename ExpressionListA, typename ExpressionListB> … … 162 204 ASSERT(destinations.size() <= values.size()); 163 205 auto offset = values.size() - destinations.size(); 164 for (size_t i = 0; i < destinations.size(); ++i) 165 WasmMov::emit(this, destinations[i], values[offset + i]); 206 for (size_t i = 0; i < destinations.size(); ++i) { 207 auto& src = values[offset + i]; 208 auto& dst = destinations[i]; 209 if ((VirtualRegister)src != (VirtualRegister)dst) 210 WasmMov::emit(this, dst, src); 211 } 166 212 } 167 213 … … 244 290 PartialResult WARN_UNUSED_RETURN addElseToUnreachable(ControlType&); 245 291 292 PartialResult WARN_UNUSED_RETURN addTry(BlockSignature, Stack& enclosingStack, ControlType& result, Stack& newStack); 293 PartialResult WARN_UNUSED_RETURN addCatch(unsigned exceptionIndex, const Signature&, Stack&, ControlType&, ResultList&); 294 PartialResult WARN_UNUSED_RETURN addCatchToUnreachable(unsigned exceptionIndex, const Signature&, ControlType&, ResultList&); 295 PartialResult WARN_UNUSED_RETURN addCatchAll(Stack&, ControlType&); 296 PartialResult WARN_UNUSED_RETURN addCatchAllToUnreachable(ControlType&); 297 PartialResult WARN_UNUSED_RETURN addDelegate(ControlType&, ControlType&); 298 PartialResult WARN_UNUSED_RETURN addDelegateToUnreachable(ControlType&, ControlType&); 299 PartialResult WARN_UNUSED_RETURN addThrow(unsigned exceptionIndex, Vector<ExpressionType>& args, Stack&); 300 PartialResult WARN_UNUSED_RETURN addRethrow(unsigned, ControlType&); 301 246 302 PartialResult WARN_UNUSED_RETURN addReturn(const ControlType&, Stack& returnValues); 247 303 PartialResult WARN_UNUSED_RETURN addBranch(ControlType&, ExpressionType condition, Stack& returnValues); 248 304 PartialResult WARN_UNUSED_RETURN addSwitch(ExpressionType condition, const Vector<ControlType*>& targets, ControlType& defaultTargets, Stack& expressionStack); 249 305 PartialResult WARN_UNUSED_RETURN endBlock(ControlEntry&, Stack& expressionStack); 250 PartialResult WARN_UNUSED_RETURN addEndToUnreachable(ControlEntry&, const Stack& expressionStack = { }, bool unreachable = true);306 PartialResult WARN_UNUSED_RETURN addEndToUnreachable(ControlEntry&, Stack& expressionStack, bool unreachable = true); 251 307 PartialResult WARN_UNUSED_RETURN endTopLevel(BlockSignature, const Stack&); 252 308 … … 338 394 } 339 395 340 template<typename Functor>396 template<typename Stack, typename Functor> 341 397 void walkExpressionStack(Stack& expressionStack, unsigned stackSize, const Functor& functor) 342 398 { … … 347 403 } 348 404 349 template<typename Functor>405 template<typename Stack, typename Functor> 350 406 void walkExpressionStack(Stack& expressionStack, const Functor& functor) 351 407 { … … 356 412 void walkExpressionStack(ControlEntry& entry, const Functor& functor) 357 413 { 358 walkExpressionStack(entry.enclosedExpressionStack, entry.controlData.stackSize(), functor); 414 unsigned stackSize = entry.controlData.stackSize(); 415 walkExpressionStack(entry.enclosedExpressionStack, stackSize, functor); 359 416 } 360 417 … … 382 439 void materializeConstantsAndLocals(Stack& expressionStack, NoConsistencyCheckTag) 383 440 { 384 walkExpressionStack(expressionStack, [&]( TypedExpression& expression, VirtualRegister slot) {441 walkExpressionStack(expressionStack, [&](auto& expression, VirtualRegister slot) { 385 442 ASSERT(expression.value() == slot || expression.value().isConstant() || expression.value().isArgument() || static_cast<unsigned>(expression.value().toLocal()) < m_codeBlock->m_numVars); 386 443 if (expression.value() == slot) … … 418 475 } 419 476 477 void finalizePreviousBlockForCatch(ControlType&, Stack&); 478 420 479 struct SwitchEntry { 421 480 InstructionStream::Offset offset; … … 430 489 431 490 FunctionParser<LLIntGenerator>* m_parser { nullptr }; 432 constModuleInformation& m_info;491 ModuleInformation& m_info; 433 492 const unsigned m_functionIndex { UINT_MAX }; 434 493 Vector<VirtualRegister> m_normalizedArguments; … … 441 500 Checked<unsigned> m_stackSize { 0 }; 442 501 Checked<unsigned> m_maxStackSize { 0 }; 502 Checked<unsigned> m_tryDepth { 0 }; 503 Checked<unsigned> m_maxTryDepth { 0 }; 504 bool m_usesExceptions { false }; 443 505 }; 444 506 445 Expected<std::unique_ptr<FunctionCodeBlock>, String> parseAndCompileBytecode(const uint8_t* functionStart, size_t functionLength, const Signature& signature, constModuleInformation& info, uint32_t functionIndex)507 Expected<std::unique_ptr<FunctionCodeBlock>, String> parseAndCompileBytecode(const uint8_t* functionStart, size_t functionLength, const Signature& signature, ModuleInformation& info, uint32_t functionIndex) 446 508 { 447 509 LLIntGenerator llintGenerator(info, functionIndex, signature); … … 467 529 } 468 530 469 LLIntGenerator::LLIntGenerator( constModuleInformation& info, unsigned functionIndex, const Signature&)531 LLIntGenerator::LLIntGenerator(ModuleInformation& info, unsigned functionIndex, const Signature&) 470 532 : BytecodeGeneratorBase(makeUnique<FunctionCodeBlock>(functionIndex), 0) 471 533 , m_info(info) … … 486 548 } 487 549 550 template<typename Opcode> 551 void LLIntGenerator::repatch(const CatchRewriteInfo& info) 552 { 553 auto ref = m_writer.ref(info.m_instructionOffset); 554 Opcode* instruction = ref->cast<Opcode, WasmOpcodeTraits>(); 555 VirtualRegister exceptionRegister = virtualRegisterForLocal(m_maxStackSize + info.m_tryDepth - 1); 556 instruction->setException(exceptionRegister, []() { 557 RELEASE_ASSERT_NOT_REACHED(); 558 return VirtualRegister(); 559 }); 560 } 561 488 562 std::unique_ptr<FunctionCodeBlock> LLIntGenerator::finalize() 489 563 { 490 564 RELEASE_ASSERT(m_codeBlock); 565 491 566 size_t numCalleeLocals = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_maxStackSize); 492 567 m_codeBlock->m_numCalleeLocals = numCalleeLocals; … … 500 575 RELEASE_ASSERT(usedBuffer.capacity() == oldCapacity); 501 576 *threadSpecific = WTFMove(usedBuffer); 577 578 if (!m_usesExceptions) 579 m_info.m_functionDoesNotUseExceptions.quickSet(m_functionIndex); 502 580 503 581 return WTFMove(m_codeBlock); … … 581 659 // FIXME: we are allocating the extra space for the argument/return count in order to avoid interference, but we could do better 582 660 // NOTE: We increase arg count by 1 for the case of indirect calls 583 m_stackSize += std::max(signature.argumentCount() + 1, signature.returnCount()) + gprCount + fprCount + stackCount + CallFrame::headerSizeInRegisters ;661 m_stackSize += std::max(signature.argumentCount() + 1, signature.returnCount()) + gprCount + fprCount + stackCount + CallFrame::headerSizeInRegisters + 1; 584 662 if (m_stackSize.value() % stackAlignmentRegisters()) 585 663 ++m_stackSize; … … 592 670 593 671 const unsigned stackOffset = m_stackSize; 594 const unsigned base = stackOffset - CallFrame::headerSizeInRegisters ;672 const unsigned base = stackOffset - CallFrame::headerSizeInRegisters - 1; 595 673 596 674 const uint32_t gprLimit = base - stackCount - gprCount; … … 684 762 uint32_t gprIndex = 0; 685 763 uint32_t fprIndex = gprCount; 686 uint32_t stackIndex = 0;764 uint32_t stackIndex = 1; 687 765 const uint32_t maxGPRIndex = gprCount; 688 766 const uint32_t maxFPRIndex = maxGPRIndex + fprCount; … … 732 810 uint32_t gprIndex = 0; 733 811 uint32_t fprIndex = maxGPRIndex; 734 uint32_t stackIndex = 0;812 uint32_t stackIndex = 1; 735 813 736 814 Vector<VirtualRegister> registerArguments(gprCount + fprCount); … … 907 985 block = ControlType::loop(signature, m_stackSize, WTFMove(body), WTFMove(continuation)); 908 986 987 Vector<unsigned> unresolvedOffsets; 909 988 Vector<VirtualRegister> osrEntryData; 910 989 for (uint32_t i = 0; i < m_codeBlock->m_numArguments; i++) … … 917 996 osrEntryData.append(virtualRegisterForLocal(i)); 918 997 for (unsigned controlIndex = 0; controlIndex < m_parser->controlStack().size(); ++controlIndex) { 998 ControlType& data = m_parser->controlStack()[controlIndex].controlData; 919 999 Stack& expressionStack = m_parser->controlStack()[controlIndex].enclosedExpressionStack; 920 1000 for (TypedExpression expression : expressionStack) 921 1001 osrEntryData.append(expression); 1002 if (ControlType::isAnyCatch(data)) 1003 osrEntryData.append(WTF::get<ControlCatch>(data).m_exception); 922 1004 } 923 1005 for (TypedExpression expression : enclosingStack) … … 973 1055 emitLabel(control.m_alternate.get()); 974 1056 data = ControlType::block(data.m_signature, m_stackSize, WTFMove(data.m_continuation)); 1057 return { }; 1058 } 1059 1060 auto LLIntGenerator::addTry(BlockSignature signature, Stack& enclosingStack, ControlType& result, Stack& newStack) -> PartialResult 1061 { 1062 m_usesExceptions = true; 1063 ++m_tryDepth; 1064 if (m_maxTryDepth < m_tryDepth) 1065 m_maxTryDepth = m_tryDepth; 1066 1067 splitStack(signature, enclosingStack, newStack); 1068 Ref<Label> tryLabel = newEmittedLabel(); 1069 Ref<Label> continuation = newLabel(); 1070 result = ControlType::createTry(signature, m_stackSize, WTFMove(tryLabel), WTFMove(continuation), m_tryDepth); 1071 return { }; 1072 } 1073 1074 void LLIntGenerator::finalizePreviousBlockForCatch(ControlType& data, Stack& expressionStack) 1075 { 1076 if (!ControlType::isAnyCatch(data)) 1077 materializeConstantsAndLocals(expressionStack); 1078 else { 1079 checkConsistency(); 1080 VirtualRegister dst = virtualRegisterForLocal(data.stackSize()); 1081 for (TypedExpression& value : expressionStack) { 1082 WasmMov::emit(this, dst, value); 1083 value = TypedExpression { value.type(), dst }; 1084 dst -= 1; 1085 } 1086 } 1087 WasmJmp::emit(this, data.m_continuation->bind(this)); 1088 } 1089 1090 auto LLIntGenerator::addCatch(unsigned exceptionIndex, const Signature& exceptionSignature, Stack& expressionStack, ControlType& data, ResultList& results) -> PartialResult 1091 { 1092 finalizePreviousBlockForCatch(data, expressionStack); 1093 return addCatchToUnreachable(exceptionIndex, exceptionSignature, data, results); 1094 } 1095 1096 auto LLIntGenerator::addCatchToUnreachable(unsigned exceptionIndex, const Signature& exceptionSignature, ControlType& data, ResultList& results) -> PartialResult 1097 { 1098 m_usesExceptions = true; 1099 Ref<Label> catchLabel = newEmittedLabel(); 1100 1101 m_stackSize = data.stackSize(); 1102 VirtualRegister exception = push(); 1103 if (WTF::holds_alternative<ControlTry>(data)) { 1104 ControlTry& tryData = WTF::get<ControlTry>(data); 1105 data = ControlType::createCatch(data.m_signature, data.stackSize(), WTFMove(tryData.m_try), WTFMove(data.m_continuation), catchLabel, tryData.m_tryDepth, exception); 1106 } 1107 for (unsigned i = 0; i < exceptionSignature.argumentCount(); ++i) 1108 results.append(push()); 1109 1110 if (Context::useFastTLS()) 1111 WasmCatch::emit(this, exceptionIndex, exception, exceptionSignature.argumentCount(), results.isEmpty() ? 0 : -results[0].offset()); 1112 else 1113 WasmCatchNoTls::emit(this, exceptionIndex, exception, exceptionSignature.argumentCount(), results.isEmpty() ? 0 : -results[0].offset()); 1114 1115 for (unsigned i = 0; i < exceptionSignature.argumentCount(); ++i) { 1116 VirtualRegister dst = results[i]; 1117 Type type = exceptionSignature.argument(i); 1118 switch (type.kind) { 1119 case Wasm::TypeKind::F32: 1120 WasmF32ReinterpretI32::emit(this, dst, dst); 1121 break; 1122 case Wasm::TypeKind::F64: 1123 WasmF64ReinterpretI64::emit(this, dst, dst); 1124 break; 1125 case Wasm::TypeKind::I32: 1126 case Wasm::TypeKind::I64: 1127 case Wasm::TypeKind::Externref: 1128 case Wasm::TypeKind::Funcref: 1129 break; 1130 default: 1131 RELEASE_ASSERT_NOT_REACHED(); 1132 break; 1133 } 1134 } 1135 1136 ControlCatch& catchData = WTF::get<ControlCatch>(data); 1137 catchData.m_kind = CatchKind::Catch; 1138 m_codeBlock->addExceptionHandler({ HandlerType::Catch, catchData.m_tryStart->location(), catchData.m_tryEnd->location(), catchLabel->location(), m_tryDepth, exceptionIndex }); 1139 1140 return { }; 1141 } 1142 1143 auto LLIntGenerator::addCatchAll(Stack& expressionStack, ControlType& data) -> PartialResult 1144 { 1145 finalizePreviousBlockForCatch(data, expressionStack); 1146 WasmJmp::emit(this, data.m_continuation->bind(this)); 1147 return addCatchAllToUnreachable(data); 1148 } 1149 1150 auto LLIntGenerator::addCatchAllToUnreachable(ControlType& data) -> PartialResult 1151 { 1152 m_usesExceptions = true; 1153 Ref<Label> catchLabel = newEmittedLabel(); 1154 m_stackSize = data.stackSize(); 1155 VirtualRegister exception = push(); 1156 if (WTF::holds_alternative<ControlTry>(data)) { 1157 ControlTry& tryData = WTF::get<ControlTry>(data); 1158 data = ControlType::createCatch(data.m_signature, data.stackSize(), WTFMove(tryData.m_try), WTFMove(data.m_continuation), catchLabel, tryData.m_tryDepth, exception); 1159 } 1160 ControlCatch& catchData = WTF::get<ControlCatch>(data); 1161 catchData.m_kind = CatchKind::CatchAll; 1162 1163 if (Context::useFastTLS()) 1164 WasmCatchAll::emit(this, exception); 1165 else 1166 WasmCatchAllNoTls::emit(this, exception); 1167 1168 m_codeBlock->addExceptionHandler({ HandlerType::CatchAll, catchData.m_tryStart->location(), catchData.m_tryEnd->location(), catchLabel->location(), m_tryDepth, 0 }); 1169 return { }; 1170 } 1171 1172 auto LLIntGenerator::addDelegate(ControlType& target, ControlType& data) -> PartialResult 1173 { 1174 return addDelegateToUnreachable(target, data); 1175 } 1176 1177 auto LLIntGenerator::addDelegateToUnreachable(ControlType& target, ControlType& data) -> PartialResult 1178 { 1179 m_usesExceptions = true; 1180 Ref<Label> delegateLabel = newEmittedLabel(); 1181 1182 ASSERT(ControlType::isTry(target) || ControlType::isTopLevel(target)); 1183 unsigned targetDepth = ControlType::isTry(target) ? WTF::get<ControlTry>(target).m_tryDepth : 0; 1184 1185 ControlTry& tryData = WTF::get<ControlTry>(data); 1186 m_codeBlock->addExceptionHandler({ HandlerType::Delegate, tryData.m_try->location(), delegateLabel->location(), 0, m_tryDepth, targetDepth }); 1187 checkConsistency(); 1188 return { }; 1189 } 1190 1191 auto LLIntGenerator::addThrow(unsigned exceptionIndex, Vector<ExpressionType>& args, Stack&) -> PartialResult 1192 { 1193 m_usesExceptions = true; 1194 walkExpressionStack(args, [&](VirtualRegister& arg, VirtualRegister slot) { 1195 if (arg == slot) 1196 return; 1197 WasmMov::emit(this, slot, arg); 1198 arg = slot; 1199 }); 1200 WasmThrow::emit(this, exceptionIndex, args.isEmpty() ? virtualRegisterForLocal(0) : args[0]); 1201 return { }; 1202 } 1203 1204 auto LLIntGenerator::addRethrow(unsigned, ControlType& data) -> PartialResult 1205 { 1206 m_usesExceptions = true; 1207 ASSERT(WTF::holds_alternative<ControlCatch>(data)); 1208 ControlCatch catchData = WTF::get<ControlCatch>(data); 1209 WasmRethrow::emit(this, catchData.m_exception); 975 1210 return { }; 976 1211 } … … 1050 1285 // FIXME: We only need to materialize constants here if there exists a jump to this label 1051 1286 // https://bugs.webkit.org/show_bug.cgi?id=203657 1052 materializeConstantsAndLocals(expressionStack);1287 finalizePreviousBlockForCatch(entry.controlData, expressionStack); 1053 1288 return addEndToUnreachable(entry, expressionStack, false); 1054 1289 } 1055 1290 1056 1291 1057 auto LLIntGenerator::addEndToUnreachable(ControlEntry& entry, constStack& expressionStack, bool unreachable) -> PartialResult1292 auto LLIntGenerator::addEndToUnreachable(ControlEntry& entry, Stack& expressionStack, bool unreachable) -> PartialResult 1058 1293 { 1059 1294 ControlType& data = entry.controlData; 1060 1295 1061 RELEASE_ASSERT(unreachable || m_stackSize == data.stackSize() + data.m_signature->returnCount()); 1296 unsigned stackSize = data.stackSize(); 1297 if (ControlType::isAnyCatch(entry.controlData)) 1298 ++stackSize; // Account for the caught exception 1299 RELEASE_ASSERT(unreachable || m_stackSize == stackSize + data.m_signature->returnCount()); 1062 1300 1063 1301 m_stackSize = data.stackSize(); 1302 1303 if (ControlType::isTry(data) || WTF::holds_alternative<ControlCatch>(data)) 1304 --m_tryDepth; 1064 1305 1065 1306 for (unsigned i = 0; i < data.m_signature->returnCount(); ++i) { -
trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.h
r271775 r283852 37 37 struct ModuleInformation; 38 38 39 Expected<std::unique_ptr<FunctionCodeBlock>, String> parseAndCompileBytecode(const uint8_t*, size_t, const Signature&, constModuleInformation&, uint32_t functionIndex);39 Expected<std::unique_ptr<FunctionCodeBlock>, String> parseAndCompileBytecode(const uint8_t*, size_t, const Signature&, ModuleInformation&, uint32_t functionIndex); 40 40 41 41 } } // namespace JSC::Wasm -
trunk/Source/JavaScriptCore/wasm/WasmLimits.h
r246571 r283852 42 42 constexpr size_t maxImports = 100000; 43 43 constexpr size_t maxExports = 100000; 44 constexpr size_t maxExceptions = 100000; 44 45 constexpr size_t maxGlobals = 1000000; 45 46 constexpr size_t maxDataSegments = 100000; -
trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.cpp
r261755 r283852 37 37 { 38 38 } 39 39 40 ModuleInformation::~ModuleInformation() { } 40 41 -
trunk/Source/JavaScriptCore/wasm/WasmModuleInformation.h
r278340 r283852 59 59 } 60 60 61 size_t exceptionIndexSpaceSize() const { return importExceptionSignatureIndices.size() + internalExceptionSignatureIndices.size(); } 62 bool isImportedExceptionFromExceptionIndexSpace(size_t exceptionIndex) const 63 { 64 ASSERT(exceptionIndex < exceptionIndexSpaceSize()); 65 return exceptionIndex < importExceptionSignatureIndices.size(); 66 } 67 SignatureIndex signatureIndexFromExceptionIndexSpace(size_t exceptionIndex) const 68 { 69 return isImportedExceptionFromExceptionIndexSpace(exceptionIndex) 70 ? importExceptionSignatureIndices[exceptionIndex] 71 : internalExceptionSignatureIndices[exceptionIndex - importExceptionSignatureIndices.size()]; 72 } 73 61 74 uint32_t importFunctionCount() const { return importFunctionSignatureIndices.size(); } 62 75 uint32_t internalFunctionCount() const { return internalFunctionSignatureIndices.size(); } 76 uint32_t importExceptionCount() const { return importExceptionSignatureIndices.size(); } 63 77 64 78 // Currently, our wasm implementation allows only one memory and table. … … 77 91 void addDeclaredFunction(uint32_t index) { m_declaredFunctions.set(index); } 78 92 93 bool isDeclaredException(uint32_t index) const { return m_declaredExceptions.contains(index); } 94 void addDeclaredException(uint32_t index) { m_declaredExceptions.set(index); } 95 79 96 Vector<Import> imports; 80 97 Vector<SignatureIndex> importFunctionSignatureIndices; 81 98 Vector<SignatureIndex> internalFunctionSignatureIndices; 99 Vector<SignatureIndex> importExceptionSignatureIndices; 100 Vector<SignatureIndex> internalExceptionSignatureIndices; 82 101 Vector<Ref<Signature>> usedSignatures; 83 102 … … 99 118 100 119 BitVector m_declaredFunctions; 120 BitVector m_declaredExceptions; 121 BitVector m_functionDoesNotUseExceptions; 101 122 mutable BitVector m_referencedFunctions; 102 123 }; -
trunk/Source/JavaScriptCore/wasm/WasmOMGForOSREntryPlan.cpp
r282860 r283852 92 92 } 93 93 94 InternalFunction* internalFunction = parseAndCompileResult->get(); 95 Vector<CodeLocationLabel<ExceptionHandlerPtrTag>> exceptionHandlerLocations; 96 computeExceptionHandlerLocations(exceptionHandlerLocations, internalFunction, context, linkBuffer); 97 94 98 omgEntrypoint.compilation = makeUnique<Compilation>( 95 99 FINALIZE_WASM_CODE_FOR_MODE(CompilationMode::OMGForOSREntryMode, linkBuffer, JITCompilationPtrTag, "WebAssembly OMGForOSREntry function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()), 96 100 WTFMove(context.wasmEntrypointByproducts)); 97 101 98 omgEntrypoint.calleeSaveRegisters = WTFMove( parseAndCompileResult.value()->entrypoint.calleeSaveRegisters);102 omgEntrypoint.calleeSaveRegisters = WTFMove(internalFunction->entrypoint.calleeSaveRegisters); 99 103 100 104 ASSERT(m_codeBlock.ptr() == m_module->codeBlockFor(mode())); 101 Ref<OMGForOSREntryCallee> callee = OMGForOSREntryCallee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), osrEntryScratchBufferSize, m_loopIndex, WTFMove(unlinkedCalls) );105 Ref<OMGForOSREntryCallee> callee = OMGForOSREntryCallee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), osrEntryScratchBufferSize, m_loopIndex, WTFMove(unlinkedCalls), WTFMove(internalFunction->stackmaps), WTFMove(internalFunction->exceptionHandlers), WTFMove(exceptionHandlerLocations)); 102 106 { 103 MacroAssembler::repatchPointer( parseAndCompileResult.value()->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr()));107 MacroAssembler::repatchPointer(internalFunction->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr())); 104 108 105 109 Locker locker { m_codeBlock->m_lock }; -
trunk/Source/JavaScriptCore/wasm/WasmOMGPlan.cpp
r282860 r283852 89 89 } 90 90 91 InternalFunction* internalFunction = parseAndCompileResult->get(); 92 Vector<CodeLocationLabel<ExceptionHandlerPtrTag>> exceptionHandlerLocations; 93 computeExceptionHandlerLocations(exceptionHandlerLocations, internalFunction, context, linkBuffer); 94 91 95 omgEntrypoint.compilation = makeUnique<Compilation>( 92 96 FINALIZE_WASM_CODE_FOR_MODE(CompilationMode::OMGMode, linkBuffer, JITCompilationPtrTag, "WebAssembly OMG function[%i] %s name %s", m_functionIndex, signature.toString().ascii().data(), makeString(IndexOrName(functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace))).ascii().data()), 93 97 WTFMove(context.wasmEntrypointByproducts)); 94 98 95 omgEntrypoint.calleeSaveRegisters = WTFMove( parseAndCompileResult.value()->entrypoint.calleeSaveRegisters);99 omgEntrypoint.calleeSaveRegisters = WTFMove(internalFunction->entrypoint.calleeSaveRegisters); 96 100 97 101 MacroAssemblerCodePtr<WasmEntryPtrTag> entrypoint; 98 102 { 99 103 ASSERT(m_codeBlock.ptr() == m_module->codeBlockFor(mode())); 100 Ref<OMGCallee> callee = OMGCallee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(unlinkedCalls) );101 MacroAssembler::repatchPointer( parseAndCompileResult.value()->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr()));104 Ref<OMGCallee> callee = OMGCallee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace), WTFMove(unlinkedCalls), WTFMove(internalFunction->stackmaps), WTFMove(internalFunction->exceptionHandlers), WTFMove(exceptionHandlerLocations)); 105 MacroAssembler::repatchPointer(internalFunction->calleeMoveLocation, CalleeBits::boxWasm(callee.ptr())); 102 106 ASSERT(!m_codeBlock->m_omgCallees[m_functionIndex]); 103 107 entrypoint = callee->entrypoint(); -
trunk/Source/JavaScriptCore/wasm/WasmOSREntryData.h
r271775 r283852 28 28 #if ENABLE(WEBASSEMBLY_B3JIT) 29 29 30 #include "B3Type.h" 30 31 #include "B3ValueRep.h" 31 #include "WasmFormat.h"32 32 #include <wtf/Vector.h> 33 33 … … 48 48 }; 49 49 50 using StackMap = Vector<OSREntryValue>; 51 using StackMaps = HashMap<CallSiteIndex, StackMap>; 52 50 53 class OSREntryData { 51 54 WTF_MAKE_NONCOPYABLE(OSREntryData); … … 60 63 uint32_t functionIndex() const { return m_functionIndex; } 61 64 uint32_t loopIndex() const { return m_loopIndex; } 62 Vector<OSREntryValue>& values() { return m_values; }65 StackMap& values() { return m_values; } 63 66 64 67 private: 65 68 uint32_t m_functionIndex; 66 69 uint32_t m_loopIndex; 67 Vector<OSREntryValue>m_values;70 StackMap m_values; 68 71 }; 69 72 -
trunk/Source/JavaScriptCore/wasm/WasmOperations.cpp
r282701 r283852 1 1 /* 2 * Copyright (C) 2019-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2019-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 35 35 #include "JSCJSValueInlines.h" 36 36 #include "JSGlobalObjectInlines.h" 37 #include "JSWebAssemblyException.h" 37 38 #include "JSWebAssemblyHelpers.h" 38 39 #include "JSWebAssemblyInstance.h" … … 106 107 } 107 108 108 SUPPRESS_ASAN 109 static void doOSREntry(Instance* instance, Probe::Context& context, BBQCallee& callee, OMGForOSREntryCallee& osrEntryCallee, OSREntryData& osrEntryData) 110 { 111 auto returnWithoutOSREntry = [&] { 112 context.gpr(GPRInfo::argumentGPR0) = 0; 113 }; 114 115 RELEASE_ASSERT(osrEntryCallee.osrEntryScratchBufferSize() == osrEntryData.values().size()); 116 117 uint64_t* buffer = instance->context()->scratchBufferForSize(osrEntryCallee.osrEntryScratchBufferSize()); 118 if (!buffer) 119 return returnWithoutOSREntry(); 120 121 dataLogLnIf(Options::verboseOSR(), osrEntryData.functionIndex(), ":OMG OSR entry: got entry callee ", RawPointer(&osrEntryCallee)); 122 123 // 1. Place required values in scratch buffer. 124 for (unsigned index = 0; index < osrEntryData.values().size(); ++index) { 125 const OSREntryValue& value = osrEntryData.values()[index]; 109 void loadValuesIntoBuffer(Probe::Context& context, const StackMap& values, uint64_t* buffer) 110 { 111 for (unsigned index = 0; index < values.size(); ++index) { 112 const OSREntryValue& value = values[index]; 126 113 dataLogLnIf(Options::verboseOSR(), "OMG OSR entry values[", index, "] ", value.type(), " ", value); 127 114 if (value.isGPR()) { … … 165 152 break; 166 153 } 167 } else if (value.isStackArgument()) {168 switch (value.type().kind()) {169 case B3::Float:170 *bitwise_cast<float*>(buffer + index) = *bitwise_cast<float*>(bitwise_cast<uint8_t*>(context.sp()) + value.offsetFromSP());171 break;172 case B3::Double:173 *bitwise_cast<double*>(buffer + index) = *bitwise_cast<double*>(bitwise_cast<uint8_t*>(context.sp()) + value.offsetFromSP());174 break;175 default:176 *bitwise_cast<uint64_t*>(buffer + index) = *bitwise_cast<uint64_t*>(bitwise_cast<uint8_t*>(context.sp()) + value.offsetFromSP());177 break;178 }179 154 } else 180 155 RELEASE_ASSERT_NOT_REACHED(); 181 156 } 157 } 158 159 SUPPRESS_ASAN 160 static void doOSREntry(Instance* instance, Probe::Context& context, BBQCallee& callee, OMGForOSREntryCallee& osrEntryCallee, OSREntryData& osrEntryData) 161 { 162 auto returnWithoutOSREntry = [&] { 163 context.gpr(GPRInfo::argumentGPR0) = 0; 164 }; 165 166 RELEASE_ASSERT(osrEntryCallee.osrEntryScratchBufferSize() == osrEntryData.values().size()); 167 168 uint64_t* buffer = instance->context()->scratchBufferForSize(osrEntryCallee.osrEntryScratchBufferSize()); 169 if (!buffer) 170 return returnWithoutOSREntry(); 171 172 dataLogLnIf(Options::verboseOSR(), osrEntryData.functionIndex(), ":OMG OSR entry: got entry callee ", RawPointer(&osrEntryCallee)); 173 174 // 1. Place required values in scratch buffer. 175 loadValuesIntoBuffer(context, osrEntryData.values(), buffer); 182 176 183 177 // 2. Restore callee saves. … … 659 653 } 660 654 661 JSC_DEFINE_JIT_OPERATION(operationWasmMemoryFill, bool, (Instance* instance, uint32_t dstAddress, uint32_t targetValue, uint32_t count))655 JSC_DEFINE_JIT_OPERATION(operationWasmMemoryFill, size_t, (Instance* instance, uint32_t dstAddress, uint32_t targetValue, uint32_t count)) 662 656 { 663 657 return instance->memory()->fill(dstAddress, static_cast<uint8_t>(targetValue), count); 664 658 } 665 659 666 JSC_DEFINE_JIT_OPERATION(operationWasmMemoryCopy, bool, (Instance* instance, uint32_t dstAddress, uint32_t srcAddress, uint32_t count))660 JSC_DEFINE_JIT_OPERATION(operationWasmMemoryCopy, size_t, (Instance* instance, uint32_t dstAddress, uint32_t srcAddress, uint32_t count)) 667 661 { 668 662 return instance->memory()->copy(dstAddress, srcAddress, count); … … 712 706 } 713 707 714 JSC_DEFINE_JIT_OPERATION(operationSetWasmTableElement, bool, (Instance* instance, unsigned tableIndex, uint32_t signedIndex, EncodedJSValue encValue))708 JSC_DEFINE_JIT_OPERATION(operationSetWasmTableElement, size_t, (Instance* instance, unsigned tableIndex, uint32_t signedIndex, EncodedJSValue encValue)) 715 709 { 716 710 return setWasmTableElement(instance, tableIndex, signedIndex, encValue); 717 711 } 718 712 719 JSC_DEFINE_JIT_OPERATION(operationWasmTableInit, bool, (Instance* instance, unsigned elementIndex, unsigned tableIndex, uint32_t dstOffset, uint32_t srcOffset, uint32_t length))713 JSC_DEFINE_JIT_OPERATION(operationWasmTableInit, size_t, (Instance* instance, unsigned elementIndex, unsigned tableIndex, uint32_t dstOffset, uint32_t srcOffset, uint32_t length)) 720 714 { 721 715 ASSERT(elementIndex < instance->module().moduleInformation().elementCount()); … … 762 756 } 763 757 764 JSC_DEFINE_JIT_OPERATION(operationWasmTableFill, bool, (Instance* instance, unsigned tableIndex, uint32_t offset, EncodedJSValue fill, uint32_t count))758 JSC_DEFINE_JIT_OPERATION(operationWasmTableFill, size_t, (Instance* instance, unsigned tableIndex, uint32_t offset, EncodedJSValue fill, uint32_t count)) 765 759 { 766 760 ASSERT(tableIndex < instance->module().moduleInformation().tableCount()); … … 778 772 } 779 773 780 JSC_DEFINE_JIT_OPERATION(operationWasmTableCopy, bool, (Instance* instance, unsigned dstTableIndex, unsigned srcTableIndex, int32_t dstOffset, int32_t srcOffset, int32_t length))774 JSC_DEFINE_JIT_OPERATION(operationWasmTableCopy, size_t, (Instance* instance, unsigned dstTableIndex, unsigned srcTableIndex, int32_t dstOffset, int32_t srcOffset, int32_t length)) 781 775 { 782 776 ASSERT(dstTableIndex < instance->module().moduleInformation().tableCount()); … … 905 899 } 906 900 907 JSC_DEFINE_JIT_OPERATION(operationWasmMemoryInit, bool, (Instance* instance, unsigned dataSegmentIndex, uint32_t dstAddress, uint32_t srcAddress, uint32_t length))901 JSC_DEFINE_JIT_OPERATION(operationWasmMemoryInit, size_t, (Instance* instance, unsigned dataSegmentIndex, uint32_t dstAddress, uint32_t srcAddress, uint32_t length)) 908 902 { 909 903 ASSERT(dataSegmentIndex < instance->module().moduleInformation().dataSegmentsCount()); … … 917 911 } 918 912 919 JSC_DEFINE_JIT_OPERATION(operationWasmToJSException, void*, (CallFrame* callFrame, Wasm::ExceptionType type, Instance* wasmInstance)) 920 { 921 wasmInstance->storeTopCallFrame(callFrame); 922 JSWebAssemblyInstance* instance = wasmInstance->owner<JSWebAssemblyInstance>(); 923 JSGlobalObject* globalObject = instance->globalObject(); 924 925 // Do not retrieve VM& from CallFrame since CallFrame's callee is not a JSCell. 913 JSC_DEFINE_JIT_OPERATION(operationWasmThrow, void*, (Instance* instance, CallFrame* callFrame, unsigned exceptionIndex, EncodedJSValue* arguments)) 914 { 915 instance->storeTopCallFrame(callFrame); 916 917 JSWebAssemblyInstance* jsInstance = instance->owner<JSWebAssemblyInstance>(); 918 JSGlobalObject* globalObject = jsInstance->globalObject(); 926 919 VM& vm = globalObject->vm(); 927 928 { 929 auto throwScope = DECLARE_THROW_SCOPE(vm); 930 931 JSObject* error; 932 if (type == ExceptionType::StackOverflow) 933 error = createStackOverflowError(globalObject); 934 else 935 error = createJSWebAssemblyRuntimeError(globalObject, vm, Wasm::errorMessageForExceptionType(type)); 936 throwException(globalObject, throwScope, error); 937 } 920 auto throwScope = DECLARE_THROW_SCOPE(vm); 921 922 const Wasm::Tag& tag = instance->tag(exceptionIndex); 923 924 FixedVector<uint64_t> values(tag.parameterCount()); 925 for (unsigned i = 0; i < tag.parameterCount(); ++i) 926 values[i] = arguments[i]; 927 928 JSWebAssemblyException* exception = JSWebAssemblyException::create(vm, globalObject->webAssemblyExceptionStructure(), tag, WTFMove(values)); 929 throwException(globalObject, throwScope, exception); 938 930 939 931 genericUnwind(vm, callFrame); … … 947 939 // to the exception handler. If we did this, we could remove this terrible hack. 948 940 // https://bugs.webkit.org/show_bug.cgi?id=170440 941 vm.calleeForWasmCatch = callFrame->callee(); 942 bitwise_cast<uint64_t*>(callFrame)[static_cast<int>(CallFrameSlot::callee)] = bitwise_cast<uint64_t>(jsInstance->module()); 943 return vm.targetMachinePCForThrow; 944 } 945 946 JSC_DEFINE_JIT_OPERATION(operationWasmRethrow, void*, (Instance* instance, CallFrame* callFrame, EncodedJSValue thrownValue)) 947 { 948 instance->storeTopCallFrame(callFrame); 949 950 JSWebAssemblyInstance* jsInstance = instance->owner<JSWebAssemblyInstance>(); 951 JSGlobalObject* globalObject = jsInstance->globalObject(); 952 VM& vm = globalObject->vm(); 953 auto throwScope = DECLARE_THROW_SCOPE(vm); 954 955 throwException(globalObject, throwScope, JSValue::decode(thrownValue)); 956 957 genericUnwind(vm, callFrame); 958 ASSERT(!!vm.callFrameForCatch); 959 ASSERT(!!vm.targetMachinePCForThrow); 960 // FIXME: We could make this better: 961 // This is a total hack, but the llint (both op_catch and llint_handle_uncaught_exception) 962 // require a cell in the callee field to load the VM. (The baseline JIT does not require 963 // this since it is compiled with a constant VM pointer.) We could make the calling convention 964 // for exceptions first load callFrameForCatch info call frame register before jumping 965 // to the exception handler. If we did this, we could remove this terrible hack. 966 // https://bugs.webkit.org/show_bug.cgi?id=170440 967 vm.calleeForWasmCatch = callFrame->callee(); 968 bitwise_cast<uint64_t*>(callFrame)[static_cast<int>(CallFrameSlot::callee)] = bitwise_cast<uint64_t>(jsInstance->module()); 969 return vm.targetMachinePCForThrow; 970 } 971 972 JSC_DEFINE_JIT_OPERATION(operationWasmToJSException, void*, (CallFrame* callFrame, Wasm::ExceptionType type, Instance* wasmInstance)) 973 { 974 wasmInstance->storeTopCallFrame(callFrame); 975 JSWebAssemblyInstance* instance = wasmInstance->owner<JSWebAssemblyInstance>(); 976 JSGlobalObject* globalObject = instance->globalObject(); 977 978 // Do not retrieve VM& from CallFrame since CallFrame's callee is not a JSCell. 979 VM& vm = globalObject->vm(); 980 981 { 982 auto throwScope = DECLARE_THROW_SCOPE(vm); 983 984 JSObject* error; 985 if (type == ExceptionType::StackOverflow) 986 error = createStackOverflowError(globalObject); 987 else 988 error = createJSWebAssemblyRuntimeError(globalObject, vm, type); 989 throwException(globalObject, throwScope, error); 990 } 991 992 genericUnwind(vm, callFrame); 993 ASSERT(!!vm.callFrameForCatch); 994 ASSERT(!!vm.targetMachinePCForThrow); 995 // FIXME: We could make this better: 996 // This is a total hack, but the llint (both op_catch and llint_handle_uncaught_exception) 997 // require a cell in the callee field to load the VM. (The baseline JIT does not require 998 // this since it is compiled with a constant VM pointer.) We could make the calling convention 999 // for exceptions first load callFrameForCatch info call frame register before jumping 1000 // to the exception handler. If we did this, we could remove this terrible hack. 1001 // https://bugs.webkit.org/show_bug.cgi?id=170440 1002 vm.calleeForWasmCatch = callFrame->callee(); 949 1003 bitwise_cast<uint64_t*>(callFrame)[static_cast<int>(CallFrameSlot::callee)] = bitwise_cast<uint64_t>(instance->module()); 950 1004 return vm.targetMachinePCForThrow; 951 1005 } 952 1006 1007 JSC_DEFINE_JIT_OPERATION(operationWasmRetrieveAndClearExceptionIfCatchable, PointerPair, (Instance* instance)) 1008 { 1009 JSWebAssemblyInstance* jsInstance = instance->owner<JSWebAssemblyInstance>(); 1010 JSGlobalObject* globalObject = jsInstance->globalObject(); 1011 VM& vm = globalObject->vm(); 1012 auto throwScope = DECLARE_THROW_SCOPE(vm); 1013 1014 RELEASE_ASSERT(!!throwScope.exception()); 1015 1016 Exception* exception = throwScope.exception(); 1017 JSValue thrownValue = exception->value(); 1018 1019 // We want to clear the exception here rather than in the catch prologue 1020 // JIT code because clearing it also entails clearing a bit in an Atomic 1021 // bit field in VMTraps. 1022 throwScope.clearException(); 1023 1024 void* payload = nullptr; 1025 if (JSWebAssemblyException* wasmException = jsDynamicCast<JSWebAssemblyException*>(vm, thrownValue)) 1026 payload = bitwise_cast<void*>(wasmException->payload().data()); 1027 return PointerPair { bitwise_cast<void*>(JSValue::encode(thrownValue)), payload }; 1028 } 1029 953 1030 } } // namespace JSC::Wasm 954 1031 -
trunk/Source/JavaScriptCore/wasm/WasmOperations.h
r282037 r283852 33 33 #include "SlowPathReturnType.h" 34 34 #include "WasmExceptionType.h" 35 #include "WasmOSREntryData.h" 35 36 36 37 namespace JSC { … … 46 47 class Instance; 47 48 class Signature; 49 50 void loadValuesIntoBuffer(Probe::Context&, const StackMap&, uint64_t* buffer); 48 51 49 52 #if ENABLE(WEBASSEMBLY_B3JIT) … … 67 70 JSC_DECLARE_JIT_OPERATION(operationPopcount64, uint64_t, (int64_t)); 68 71 JSC_DECLARE_JIT_OPERATION(operationGrowMemory, int32_t, (void*, Instance*, int32_t)); 69 JSC_DECLARE_JIT_OPERATION(operationWasmMemoryFill, bool, (Instance*, uint32_t dstAddress, uint32_t targetValue, uint32_t count));70 JSC_DECLARE_JIT_OPERATION(operationWasmMemoryCopy, bool, (Instance*, uint32_t dstAddress, uint32_t srcAddress, uint32_t count));72 JSC_DECLARE_JIT_OPERATION(operationWasmMemoryFill, size_t, (Instance*, uint32_t dstAddress, uint32_t targetValue, uint32_t count)); 73 JSC_DECLARE_JIT_OPERATION(operationWasmMemoryCopy, size_t, (Instance*, uint32_t dstAddress, uint32_t srcAddress, uint32_t count)); 71 74 72 75 JSC_DECLARE_JIT_OPERATION(operationGetWasmTableElement, EncodedJSValue, (Instance*, unsigned, int32_t)); 73 JSC_DECLARE_JIT_OPERATION(operationSetWasmTableElement, bool, (Instance*, unsigned, uint32_t, EncodedJSValue encValue));76 JSC_DECLARE_JIT_OPERATION(operationSetWasmTableElement, size_t, (Instance*, unsigned, uint32_t, EncodedJSValue encValue)); 74 77 JSC_DECLARE_JIT_OPERATION(operationWasmRefFunc, EncodedJSValue, (Instance*, uint32_t)); 75 JSC_DECLARE_JIT_OPERATION(operationWasmTableInit, bool, (Instance*, unsigned elementIndex, unsigned tableIndex, uint32_t dstOffset, uint32_t srcOffset, uint32_t length));78 JSC_DECLARE_JIT_OPERATION(operationWasmTableInit, size_t, (Instance*, unsigned elementIndex, unsigned tableIndex, uint32_t dstOffset, uint32_t srcOffset, uint32_t length)); 76 79 JSC_DECLARE_JIT_OPERATION(operationWasmElemDrop, void, (Instance*, unsigned elementIndex)); 77 80 JSC_DECLARE_JIT_OPERATION(operationWasmTableGrow, int32_t, (Instance*, unsigned, EncodedJSValue fill, uint32_t delta)); 78 JSC_DECLARE_JIT_OPERATION(operationWasmTableFill, bool, (Instance*, unsigned, uint32_t offset, EncodedJSValue fill, uint32_t count));79 JSC_DECLARE_JIT_OPERATION(operationWasmTableCopy, bool, (Instance*, unsigned dstTableIndex, unsigned srcTableIndex, int32_t dstOffset, int32_t srcOffset, int32_t length));81 JSC_DECLARE_JIT_OPERATION(operationWasmTableFill, size_t, (Instance*, unsigned, uint32_t offset, EncodedJSValue fill, uint32_t count)); 82 JSC_DECLARE_JIT_OPERATION(operationWasmTableCopy, size_t, (Instance*, unsigned dstTableIndex, unsigned srcTableIndex, int32_t dstOffset, int32_t srcOffset, int32_t length)); 80 83 JSC_DECLARE_JIT_OPERATION(operationGetWasmTableSize, int32_t, (Instance*, unsigned)); 81 84 … … 83 86 JSC_DECLARE_JIT_OPERATION(operationMemoryAtomicWait64, int32_t, (Instance* instance, unsigned base, unsigned offset, uint64_t value, int64_t timeout)); 84 87 JSC_DECLARE_JIT_OPERATION(operationMemoryAtomicNotify, int32_t, (Instance*, unsigned, unsigned, int32_t)); 85 JSC_DECLARE_JIT_OPERATION(operationWasmMemoryInit, bool, (Instance*, unsigned dataSegmentIndex, uint32_t dstAddress, uint32_t srcAddress, uint32_t length));88 JSC_DECLARE_JIT_OPERATION(operationWasmMemoryInit, size_t, (Instance*, unsigned dataSegmentIndex, uint32_t dstAddress, uint32_t srcAddress, uint32_t length)); 86 89 JSC_DECLARE_JIT_OPERATION(operationWasmDataDrop, void, (Instance*, unsigned dataSegmentIndex)); 87 90 91 JSC_DECLARE_JIT_OPERATION(operationWasmThrow, void*, (Instance*, CallFrame*, unsigned exceptionIndex, EncodedJSValue*)); 92 JSC_DECLARE_JIT_OPERATION(operationWasmRethrow, void*, (Instance*, CallFrame*, EncodedJSValue thrownValue)); 93 88 94 JSC_DECLARE_JIT_OPERATION(operationWasmToJSException, void*, (CallFrame*, Wasm::ExceptionType, Instance*)); 95 struct PointerPair { 96 void* first; 97 void* second; 98 }; 99 JSC_DECLARE_JIT_OPERATION(operationWasmRetrieveAndClearExceptionIfCatchable, PointerPair, (Instance*)); 89 100 90 101 } } // namespace JSC::Wasm -
trunk/Source/JavaScriptCore/wasm/WasmSectionParser.cpp
r281438 r283852 92 92 WASM_PARSER_FAIL_IF(!m_info->imports.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " imports"); // FIXME this over-allocates when we fix the FIXMEs below. 93 93 WASM_PARSER_FAIL_IF(!m_info->importFunctionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import function signatures"); // FIXME this over-allocates when we fix the FIXMEs below. 94 if (Options::useWebAssemblyExceptions()) 95 WASM_PARSER_FAIL_IF(!m_info->importExceptionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import exception signatures"); // FIXME this over-allocates when we fix the FIXMEs below. 94 96 95 97 for (uint32_t importNumber = 0; importNumber < importCount; ++importNumber) { … … 141 143 kindIndex = m_info->globals.size(); 142 144 m_info->globals.uncheckedAppend(WTFMove(global)); 145 break; 146 } 147 case ExternalKind::Exception: { 148 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 149 150 uint8_t tagType; 151 WASM_PARSER_FAIL_IF(!parseUInt8(tagType), "can't get ", importNumber, "th Import exception's tag type"); 152 WASM_PARSER_FAIL_IF(tagType, importNumber, "th Import exception has tag type ", tagType, " but the only supported tag type is 0"); 153 154 uint32_t exceptionSignatureIndex; 155 WASM_PARSER_FAIL_IF(!parseVarUInt32(exceptionSignatureIndex), "can't get ", importNumber, "th Import's exception signature in module '", moduleString, "' field '", fieldString, "'"); 156 WASM_PARSER_FAIL_IF(exceptionSignatureIndex >= m_info->usedSignatures.size(), "invalid exception signature for ", importNumber, "th Import, ", exceptionSignatureIndex, " is out of range of ", m_info->usedSignatures.size(), " in module '", moduleString, "' field '", fieldString, "'"); 157 kindIndex = m_info->importExceptionSignatureIndices.size(); 158 SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[exceptionSignatureIndex]); 159 m_info->importExceptionSignatureIndices.uncheckedAppend(signatureIndex); 143 160 break; 144 161 } … … 359 376 break; 360 377 } 378 case ExternalKind::Exception: { 379 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 380 381 WASM_PARSER_FAIL_IF(kindIndex >= m_info->exceptionIndexSpaceSize(), exportNumber, "th Export has invalid exception number ", kindIndex, " it exceeds the exception index space ", m_info->exceptionIndexSpaceSize(), ", named '", fieldString, "'"); 382 m_info->addDeclaredException(kindIndex); 383 break; 384 } 361 385 } 362 386 … … 818 842 } 819 843 844 auto SectionParser::parseException() -> PartialResult 845 { 846 WASM_PARSER_FAIL_IF(!Options::useWebAssemblyExceptions(), "wasm exceptions are not enabled"); 847 848 uint32_t exceptionCount; 849 WASM_PARSER_FAIL_IF(!parseVarUInt32(exceptionCount), "can't get Exception section's count"); 850 WASM_PARSER_FAIL_IF(exceptionCount > maxExceptions, "Export section's count is too big ", exceptionCount, " maximum ", maxExceptions); 851 WASM_PARSER_FAIL_IF(!m_info->internalExceptionSignatureIndices.tryReserveCapacity(exceptionCount), "can't allocate enough memory for ", exceptionCount, " exceptions"); 852 853 for (uint32_t exceptionNumber = 0; exceptionNumber < exceptionCount; ++exceptionNumber) { 854 uint8_t tagType; 855 WASM_PARSER_FAIL_IF(!parseUInt8(tagType), "can't get ", exceptionNumber, "th Exception tag type"); 856 WASM_PARSER_FAIL_IF(tagType, exceptionNumber, "th Exception has tag type ", tagType, " but the only supported tag type is 0"); 857 858 uint32_t typeNumber; 859 WASM_PARSER_FAIL_IF(!parseVarUInt32(typeNumber), "can't get ", exceptionNumber, "th Exception's type number"); 860 WASM_PARSER_FAIL_IF(typeNumber >= m_info->usedSignatures.size(), exceptionNumber, "th Exception type number is invalid ", typeNumber); 861 SignatureIndex signatureIndex = SignatureInformation::get(m_info->usedSignatures[typeNumber]); 862 m_info->internalExceptionSignatureIndices.uncheckedAppend(signatureIndex); 863 } 864 865 return { }; 866 } 820 867 auto SectionParser::parseCustom() -> PartialResult 821 868 { -
trunk/Source/JavaScriptCore/wasm/WasmSections.h
r270948 r283852 46 46 macro(Code, 10, "Function bodies (code)") \ 47 47 macro(Data, 11, "Data segments") \ 48 macro(DataCount, 12, "Data count") 48 macro(DataCount, 12, "Data count") \ 49 macro(Exception, 13, "Exception declarations") \ 49 50 50 51 enum class Section : uint8_t { … … 91 92 if (previousKnown == Section::DataCount && next == Section::Code) 92 93 return true; 94 if (previousKnown == Section::Exception) 95 return next >= Section::Global; 96 if (next == Section::Exception) 97 return previousKnown <= Section::Memory; 93 98 return static_cast<uint8_t>(previousKnown) < static_cast<uint8_t>(next); 94 99 } -
trunk/Source/JavaScriptCore/wasm/WasmSignature.cpp
r282860 r283852 97 97 SignatureInformation::SignatureInformation() 98 98 { 99 #define MAKE_THUNK_SIGNATURE(type, enc, str, val )\99 #define MAKE_THUNK_SIGNATURE(type, enc, str, val, _) \ 100 100 do { \ 101 101 if (TypeKind::type != TypeKind::Void) { \ … … 166 166 RefPtr<Signature> SignatureInformation::signatureFor(const Vector<Type, 1>& results, const Vector<Type>& args) 167 167 { 168 if constexpr (ASSERT_ENABLED) { 169 ASSERT(!results.contains(Wasm::Types::Void)); 170 ASSERT(!args.contains(Wasm::Types::Void)); 171 } 168 172 SignatureInformation& info = singleton(); 169 173 Locker locker { info.m_lock }; -
trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp
r282860 r283852 30 30 31 31 #include "BytecodeStructs.h" 32 #include "JITExceptions.h" 33 #include "JSWebAssemblyException.h" 32 34 #include "JSWebAssemblyInstance.h" 33 35 #include "LLIntData.h" … … 587 589 } 588 590 591 WASM_SLOW_PATH_DECL(throw) 592 { 593 instance->storeTopCallFrame(callFrame); 594 595 JSWebAssemblyInstance* jsInstance = instance->owner<JSWebAssemblyInstance>(); 596 JSGlobalObject* globalObject = jsInstance->globalObject(); 597 VM& vm = globalObject->vm(); 598 auto throwScope = DECLARE_THROW_SCOPE(vm); 599 600 auto instruction = pc->as<WasmThrow, WasmOpcodeTraits>(); 601 const Wasm::Tag& tag = instance->tag(instruction.m_exceptionIndex); 602 603 FixedVector<uint64_t> values(tag.parameterCount()); 604 for (unsigned i = 0; i < tag.parameterCount(); ++i) 605 values[i] = READ((instruction.m_firstValue - i)).encodedJSValue(); 606 607 JSWebAssemblyException* exception = JSWebAssemblyException::create(vm, globalObject->webAssemblyExceptionStructure(), tag, WTFMove(values)); 608 throwException(globalObject, throwScope, exception); 609 610 genericUnwind(vm, callFrame); 611 ASSERT(!!vm.callFrameForCatch); 612 ASSERT(!!vm.targetMachinePCForThrow); 613 // FIXME: We could make this better: 614 // This is a total hack, but the llint (both op_catch and llint_handle_uncaught_exception) 615 // require a cell in the callee field to load the VM. (The baseline JIT does not require 616 // this since it is compiled with a constant VM pointer.) We could make the calling convention 617 // for exceptions first load callFrameForCatch info call frame register before jumping 618 // to the exception handler. If we did this, we could remove this terrible hack. 619 // https://bugs.webkit.org/show_bug.cgi?id=170440 620 vm.calleeForWasmCatch = callFrame->callee(); 621 bitwise_cast<uint64_t*>(callFrame)[static_cast<int>(CallFrameSlot::callee)] = bitwise_cast<uint64_t>(jsInstance->module()); 622 WASM_RETURN_TWO(vm.targetMachinePCForThrow, nullptr); 623 } 624 625 WASM_SLOW_PATH_DECL(rethrow) 626 { 627 instance->storeTopCallFrame(callFrame); 628 629 JSWebAssemblyInstance* jsInstance = instance->owner<JSWebAssemblyInstance>(); 630 JSGlobalObject* globalObject = jsInstance->globalObject(); 631 VM& vm = globalObject->vm(); 632 auto throwScope = DECLARE_THROW_SCOPE(vm); 633 634 auto instruction = pc->as<WasmRethrow, WasmOpcodeTraits>(); 635 JSValue exception = READ(instruction.m_exception).jsValue(); 636 throwException(globalObject, throwScope, exception); 637 638 genericUnwind(vm, callFrame); 639 ASSERT(!!vm.callFrameForCatch); 640 ASSERT(!!vm.targetMachinePCForThrow); 641 // FIXME: We could make this better: 642 // This is a total hack, but the llint (both op_catch and llint_handle_uncaught_exception) 643 // require a cell in the callee field to load the VM. (The baseline JIT does not require 644 // this since it is compiled with a constant VM pointer.) We could make the calling convention 645 // for exceptions first load callFrameForCatch info call frame register before jumping 646 // to the exception handler. If we did this, we could remove this terrible hack. 647 // https://bugs.webkit.org/show_bug.cgi?id=170440 648 vm.calleeForWasmCatch = callFrame->callee(); 649 bitwise_cast<uint64_t*>(callFrame)[static_cast<int>(CallFrameSlot::callee)] = bitwise_cast<uint64_t>(jsInstance->module()); 650 WASM_RETURN_TWO(vm.targetMachinePCForThrow, nullptr); 651 } 652 653 WASM_SLOW_PATH_DECL(retrieve_and_clear_exception) 654 { 655 UNUSED_PARAM(callFrame); 656 JSWebAssemblyInstance* jsInstance = instance->owner<JSWebAssemblyInstance>(); 657 JSGlobalObject* globalObject = jsInstance->globalObject(); 658 VM& vm = globalObject->vm(); 659 auto throwScope = DECLARE_THROW_SCOPE(vm); 660 661 RELEASE_ASSERT(!!throwScope.exception()); 662 663 Exception* exception = throwScope.exception(); 664 JSValue thrownValue = exception->value(); 665 void* payload = nullptr; 666 667 const auto& handleCatchAll = [&](const auto& instruction) { 668 callFrame->uncheckedR(instruction.m_exception) = thrownValue; 669 }; 670 671 const auto& handleCatch = [&](const auto& instruction) { 672 JSWebAssemblyException* wasmException = jsDynamicCast<JSWebAssemblyException*>(vm, thrownValue); 673 RELEASE_ASSERT(!!wasmException); 674 payload = bitwise_cast<void*>(wasmException->payload().data()); 675 callFrame->uncheckedR(instruction.m_exception) = thrownValue; 676 }; 677 678 if (pc->is<WasmCatch, WasmOpcodeTraits>()) 679 handleCatch(pc->as<WasmCatch, WasmOpcodeTraits>()); 680 else if (pc->is<WasmCatchAll, WasmOpcodeTraits>()) 681 handleCatchAll(pc->as<WasmCatchAll, WasmOpcodeTraits>()); 682 else if (pc->is<WasmCatchNoTls, WasmOpcodeTraits>()) 683 handleCatch(pc->as<WasmCatchNoTls, WasmOpcodeTraits>()); 684 else if (pc->is<WasmCatchAllNoTls, WasmOpcodeTraits>()) 685 handleCatchAll(pc->as<WasmCatchAllNoTls, WasmOpcodeTraits>()); 686 else 687 RELEASE_ASSERT_NOT_REACHED(); 688 689 // We want to clear the exception here rather than in the catch prologue 690 // JIT code because clearing it also entails clearing a bit in an Atomic 691 // bit field in VMTraps. 692 throwScope.clearException(); 693 WASM_RETURN_TWO(pc, payload); 694 } 695 589 696 extern "C" SlowPathReturnType slow_path_wasm_throw_exception(CallFrame* callFrame, const Instruction* pc, Wasm::Instance* instance, Wasm::ExceptionType exceptionType) 590 697 { -
trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.h
r280770 r283852 84 84 WASM_SLOW_PATH_HIDDEN_DECL(memory_atomic_wait64); 85 85 WASM_SLOW_PATH_HIDDEN_DECL(memory_atomic_notify); 86 WASM_SLOW_PATH_HIDDEN_DECL(throw); 87 WASM_SLOW_PATH_HIDDEN_DECL(rethrow); 88 WASM_SLOW_PATH_HIDDEN_DECL(retrieve_and_clear_exception); 86 89 87 90 extern "C" SlowPathReturnType slow_path_wasm_throw_exception(CallFrame*, const Instruction*, Wasm::Instance* instance, Wasm::ExceptionType) REFERENCED_FROM_ASM WTF_INTERNAL; -
trunk/Source/JavaScriptCore/wasm/WasmStreamingParser.cpp
r278340 r283852 118 118 m_functionIndex = 0; 119 119 m_codeOffset = m_offset; 120 m_info->m_functionDoesNotUseExceptions.ensureSize(functionCount); 120 121 121 122 WASM_PARSER_FAIL_IF(functionCount == std::numeric_limits<uint32_t>::max(), "Code section's count is too big ", functionCount); -
trunk/Source/JavaScriptCore/wasm/WasmTag.cpp
r283851 r283852 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 24 24 */ 25 25 26 #pragma once 26 #include "config.h" 27 #include "WasmTag.h" 27 28 28 29 #if ENABLE(WEBASSEMBLY) 29 30 30 #include "ErrorInstance.h" 31 namespace JSC { 32 namespace Wasm { 31 33 32 namespace JSC { 34 std::atomic<uint32_t> Tag::s_id = 0; 33 35 34 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, const String&); 36 } } // namespace JSC::Wasm 35 37 36 } // namespace JSC 37 38 #endif // ENABLE(WEBASSEMBLY) 38 #endif -
trunk/Source/JavaScriptCore/wasm/WasmTag.h
r283851 r283852 1 1 /* 2 * Copyright (C) 20 19Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include <wtf/Expected.h> 31 #include <wtf/text/WTFString.h> 30 #include "WasmSignature.h" 32 31 33 32 namespace JSC { namespace Wasm { 34 33 35 class FunctionCodeBlock; 36 class Signature; 37 struct ModuleInformation; 34 class Tag : public ThreadSafeRefCounted<Tag> { 35 WTF_MAKE_FAST_ALLOCATED; 36 WTF_MAKE_NONCOPYABLE(Tag); 37 public: 38 static Ref<Tag> create(const Signature& signature) { return adoptRef(*new Tag(signature)); } 38 39 39 Expected<std::unique_ptr<FunctionCodeBlock>, String> parseAndCompileBytecode(const uint8_t*, size_t, const Signature&, const ModuleInformation&, uint32_t functionIndex); 40 SignatureArgCount parameterCount() const { return m_signature->argumentCount(); } 41 Type parameter(SignatureArgCount i) const { return m_signature->argument(i); } 42 43 bool operator==(const Tag& other) const { return m_id == other.m_id; } 44 bool operator!=(const Tag& other) const { return m_id != other.m_id; } 45 46 const Signature& signature() const { return m_signature.get(); } 47 48 private: 49 Tag(const Signature& signature) 50 : m_id(++s_id) 51 , m_signature(Ref { signature }) 52 { 53 } 54 55 static std::atomic<uint32_t> s_id; 56 uint32_t m_id; 57 Ref<const Signature> m_signature; 58 }; 40 59 41 60 } } // namespace JSC::Wasm -
trunk/Source/JavaScriptCore/wasm/WasmThunks.cpp
r277928 r283852 1 1 /* 2 * Copyright (C) 2017-202 0Apple Inc. All rights reserved.2 * Copyright (C) 2017-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 #if ENABLE(WEBASSEMBLY) 30 30 31 #include "AllowMacroScratchRegisterUsage.h" 31 32 #include "CCallHelpers.h" 33 #include "JSInterfaceJIT.h" 32 34 #include "LinkBuffer.h" 35 #include "ProbeContext.h" 33 36 #include "ScratchRegisterAllocator.h" 34 37 #include "WasmExceptionType.h" -
trunk/Source/JavaScriptCore/wasm/WasmThunks.h
r278093 r283852 1 1 /* 2 * Copyright (C) 2017-20 18Apple Inc. All rights reserved.2 * Copyright (C) 2017-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without -
trunk/Source/JavaScriptCore/wasm/generateWasmB3IRGeneratorInlinesHeader.py
r277853 r283852 145 145 self.consume(")") 146 146 elif argumentRegex.match(self.token()): 147 result = " arg" + self.token()[1:]147 result = "get(arg" + self.token()[1:] + ")" 148 148 self.advance() 149 149 else: … … 157 157 return result 158 158 159 def makeResult(self, resultValue): 160 return resultValue + ";\n" + "result = push(resultValue->type());\n" + "m_currentBlock->appendNew<VariableValue>(m_proc, Set, origin(), result, resultValue);" 161 159 162 def generate(self, wasmOp): 160 163 if len(self.tokens) == 1: 161 params = [" arg" + str(param)for param in range(len(wasmOp["parameter"]))]162 return " result = m_currentBlock->appendNew<Value>(m_proc, B3::" + self.token() + ", origin(), " + ", ".join(params) + ")"164 params = ["get(arg" + str(param) + ")" for param in range(len(wasmOp["parameter"]))] 165 return self.makeResult(" Value* resultValue = m_currentBlock->appendNew<Value>(m_proc, B3::" + self.token() + ", origin(), " + ", ".join(params) + ")") 163 166 result = self.generateOpcode() 164 self.code.append(" result= " + result)165 return " " + " \n".join(self.code)167 self.code.append("Value* resultValue = " + result) 168 return self.makeResult(" " + " \n".join(self.code)) 166 169 167 170 … … 192 195 template<> auto B3IRGenerator::addOp<OpType::""" + wasm.toCpp(op["name"]) + ">(" + ", ".join(args) + """) -> PartialResult 193 196 { 194 """ + generateB3Code(opcode, b3op) + """ ;197 """ + generateB3Code(opcode, b3op) + """ 195 198 return { }; 196 199 } -
trunk/Source/JavaScriptCore/wasm/generateWasmOpsHeader.py
r282701 r283852 54 54 inc = 0 55 55 for ty in wasm.types: 56 yield cppMacro(ty, wasm.types[ty]["value"], wasm.types[ty]["b3type"], inc )56 yield cppMacro(ty, wasm.types[ty]["value"], wasm.types[ty]["b3type"], inc, ty) 57 57 inc += 1 58 58 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssembly.cpp
r281438 r283852 79 79 @begin webAssemblyTable 80 80 CompileError createWebAssemblyCompileError DontEnum|PropertyCallback 81 Exception createWebAssemblyException DontEnum|PropertyCallback 81 82 Global createWebAssemblyGlobal DontEnum|PropertyCallback 82 83 Instance createWebAssemblyInstance DontEnum|PropertyCallback … … 86 87 RuntimeError createWebAssemblyRuntimeError DontEnum|PropertyCallback 87 88 Table createWebAssemblyTable DontEnum|PropertyCallback 89 Tag createWebAssemblyTag DontEnum|PropertyCallback 88 90 compile webAssemblyCompileFunc Function 1 89 91 instantiate webAssemblyInstantiateFunc Function 1 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h
r273813 r283852 33 33 #include "JSCJSValue.h" 34 34 #include "JSSourceCode.h" 35 #include "JSWebAssemblyRuntimeError.h" 35 36 #include "WasmFormat.h" 36 37 #include "WebAssemblyFunction.h" … … 145 146 } 146 147 148 ALWAYS_INLINE JSValue toJSValue(JSGlobalObject* globalObject, const Wasm::Type type, uint64_t bits) 149 { 150 switch (type.kind) { 151 case Wasm::TypeKind::Void: 152 return jsUndefined(); 153 case Wasm::TypeKind::I32: 154 return jsNumber(static_cast<int32_t>(bits)); 155 case Wasm::TypeKind::F32: 156 return jsNumber(bitwise_cast<float>(static_cast<int32_t>(bits))); 157 case Wasm::TypeKind::F64: 158 return jsNumber(bitwise_cast<double>(bits)); 159 case Wasm::TypeKind::I64: 160 return JSBigInt::createFrom(globalObject, static_cast<int64_t>(bits)); 161 case Wasm::TypeKind::Externref: 162 case Wasm::TypeKind::Funcref: 163 return bitwise_cast<JSValue>(bits); 164 default: 165 break; 166 } 167 RELEASE_ASSERT_NOT_REACHED(); 168 return JSValue(); 169 } 170 171 ALWAYS_INLINE uint64_t fromJSValue(JSGlobalObject* globalObject, const Wasm::Type type, JSValue value) 172 { 173 VM& vm = globalObject->vm(); 174 auto scope = DECLARE_THROW_SCOPE(vm); 175 switch (type.kind) { 176 case Wasm::TypeKind::TypeIdx: 177 case Wasm::TypeKind::Funcref: { 178 bool isNullable = type.isNullable(); 179 WebAssemblyFunction* wasmFunction = nullptr; 180 WebAssemblyWrapperFunction* wasmWrapperFunction = nullptr; 181 if (!isWebAssemblyHostFunction(vm, value, wasmFunction, wasmWrapperFunction) && (!isNullable || !value.isNull())) 182 return throwVMException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Funcref must be an exported wasm function")); 183 if (type.kind == Wasm::TypeKind::TypeIdx && (wasmFunction || wasmWrapperFunction)) { 184 Wasm::SignatureIndex paramIndex = type.index; 185 Wasm::SignatureIndex argIndex; 186 if (wasmFunction) 187 argIndex = wasmFunction->signatureIndex(); 188 else 189 argIndex = wasmWrapperFunction->signatureIndex(); 190 if (paramIndex != argIndex) 191 return throwVMException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Argument function did not match the reference type")); 192 } 193 break; 194 } 195 case Wasm::TypeKind::Externref: 196 if (!type.isNullable() && value.isNull()) 197 return throwVMException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Non-null Externref cannot be null")); 198 break; 199 case Wasm::TypeKind::I32: 200 RELEASE_AND_RETURN(scope, value.toInt32(globalObject)); 201 case Wasm::TypeKind::I64: 202 RELEASE_AND_RETURN(scope, bitwise_cast<uint64_t>(value.toBigInt64(globalObject))); 203 case Wasm::TypeKind::F32: 204 RELEASE_AND_RETURN(scope, bitwise_cast<uint32_t>(value.toFloat(globalObject))); 205 case Wasm::TypeKind::F64: 206 RELEASE_AND_RETURN(scope, bitwise_cast<uint64_t>(value.toNumber(globalObject))); 207 case Wasm::TypeKind::Void: 208 case Wasm::TypeKind::Func: 209 case Wasm::TypeKind::RefNull: 210 case Wasm::TypeKind::Ref: 211 RELEASE_ASSERT_NOT_REACHED(); 212 } 213 214 RELEASE_AND_RETURN(scope, JSValue::encode(value)); 215 } 216 147 217 } // namespace JSC 148 218 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
r277909 r283852 217 217 case Wasm::ExternalKind::Global: 218 218 case Wasm::ExternalKind::Table: 219 case Wasm::ExternalKind::Exception: 219 220 continue; 220 221 case Wasm::ExternalKind::Memory: … … 243 244 case Wasm::ExternalKind::Global: 244 245 case Wasm::ExternalKind::Table: 246 case Wasm::ExternalKind::Exception: 245 247 break; 246 248 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
r282860 r283852 49 49 50 50 class JSWebAssemblyInstance final : public JSNonFinalObject { 51 friend class LLIntOffsetsExtractor; 52 51 53 public: 52 54 using Base = JSNonFinalObject; -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.cpp
r277238 r283852 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved.2 * Copyright (C) 2016-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 38 38 return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyRuntimeErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true); 39 39 } 40 41 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject* globalObject, VM& vm, Wasm::ExceptionType type) 42 { 43 ErrorInstance* error = ErrorInstance::create(globalObject, vm, globalObject->webAssemblyRuntimeErrorStructure(), Wasm::errorMessageForExceptionType(type), JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true); 44 error->setCatchableFromWasm(false); 45 return error; 46 } 40 47 41 48 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.h
r274609 r283852 1 1 /* 2 * Copyright (C) 2016 Apple Inc. All rights reserved.2 * Copyright (C) 2016-2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 29 29 30 30 #include "ErrorInstance.h" 31 #include "WasmExceptionType.h" 31 32 32 33 namespace JSC { 33 34 34 35 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, const String&); 36 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, Wasm::ExceptionType); 35 37 36 38 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTag.cpp
r283851 r283852 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 25 25 26 26 #include "config.h" 27 #include "JSWebAssembly RuntimeError.h"27 #include "JSWebAssemblyTag.h" 28 28 29 29 #if ENABLE(WEBASSEMBLY) 30 30 31 #include " JSCJSValueInlines.h"31 #include "WasmTag.h" 32 32 33 33 namespace JSC { 34 34 35 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject* globalObject, VM& vm, const String& message) 35 const ClassInfo JSWebAssemblyTag::s_info = { "WebAssembly.Tag", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyTag) }; 36 37 JSWebAssemblyTag* JSWebAssemblyTag::create(VM& vm, JSGlobalObject* globalObject, Structure* structure, const Wasm::Tag& tag) 36 38 { 37 ASSERT(!message.isEmpty()); 38 return ErrorInstance::create(globalObject, vm, globalObject->webAssemblyRuntimeErrorStructure(), message, JSValue(), defaultSourceAppender, TypeNothing, ErrorType::Error, true); 39 UNUSED_PARAM(globalObject); 40 auto* jsTag = new (NotNull, allocateCell<JSWebAssemblyTag>(vm.heap)) JSWebAssemblyTag(vm, structure, tag); 41 jsTag->finishCreation(vm); 42 return jsTag; 39 43 } 40 44 45 Structure* JSWebAssemblyTag::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 46 { 47 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); 48 } 49 50 JSWebAssemblyTag::JSWebAssemblyTag(VM& vm, Structure* structure, const Wasm::Tag& tag) 51 : Base(vm, structure) 52 , m_tag(Ref { tag }) 53 { 54 } 55 56 void JSWebAssemblyTag::destroy(JSCell* cell) 57 { 58 static_cast<JSWebAssemblyTag*>(cell)->JSWebAssemblyTag::~JSWebAssemblyTag(); 59 } 60 41 61 } // namespace JSC 42 62 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTag.h
r283851 r283852 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include " ErrorInstance.h"30 #include "WasmTag.h" 31 31 32 32 namespace JSC { 33 33 34 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, const String&); 34 class JSWebAssemblyTag final : public JSNonFinalObject { 35 public: 36 using Base = JSNonFinalObject; 37 static constexpr bool needsDestruction = true; 38 39 static void destroy(JSCell*); 40 41 template<typename CellType, SubspaceAccess mode> 42 static IsoSubspace* subspaceFor(VM& vm) 43 { 44 return vm.webAssemblyTagSpace<mode>(); 45 } 46 47 DECLARE_EXPORT_INFO; 48 49 JS_EXPORT_PRIVATE static JSWebAssemblyTag* create(VM&, JSGlobalObject*, Structure*, const Wasm::Tag&); 50 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 51 52 const Wasm::Tag& tag() const { return m_tag; } 53 const Wasm::Signature& signature() const { return tag().signature(); } 54 55 private: 56 JSWebAssemblyTag(VM&, Structure*, const Wasm::Tag&); 57 58 const Ref<const Wasm::Tag> m_tag; 59 }; 35 60 36 61 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/WasmToJS.cpp
r279265 r283852 99 99 unsigned marshalledFPRs = 0; 100 100 unsigned calleeFrameOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register)); 101 unsigned frOffset = CallFrame ::headerSizeInRegisters* static_cast<int>(sizeof(Register));101 unsigned frOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register)); 102 102 for (unsigned argNum = 0; argNum < argCount; ++argNum) { 103 103 Type argType = signature.argument(argNum); … … 163 163 unsigned marshalledFPRs = 0; 164 164 unsigned calleeFrameOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register)); 165 unsigned frOffset = CallFrame ::headerSizeInRegisters* static_cast<int>(sizeof(Register));165 unsigned frOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register)); 166 166 167 167 auto marshallFPR = [&] (FPRReg fprReg) { -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyExceptionConstructor.h
r283851 r283852 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include "ErrorInstance.h" 30 #include "InternalFunction.h" 31 #include "JSObject.h" 31 32 32 33 namespace JSC { 33 34 34 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, const String&); 35 class WebAssemblyExceptionPrototype; 36 37 class WebAssemblyExceptionConstructor final : public InternalFunction { 38 public: 39 using Base = InternalFunction; 40 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable; 41 42 static WebAssemblyExceptionConstructor* create(VM&, Structure*, WebAssemblyExceptionPrototype*); 43 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 44 45 DECLARE_INFO; 46 47 private: 48 WebAssemblyExceptionConstructor(VM&, Structure*); 49 void finishCreation(VM&, WebAssemblyExceptionPrototype*); 50 }; 51 STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(WebAssemblyExceptionConstructor, InternalFunction); 35 52 36 53 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyExceptionPrototype.h
r283851 r283852 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include "ErrorInstance.h" 30 #include "JSDestructibleObject.h" 31 #include "JSObject.h" 31 32 32 33 namespace JSC { 33 34 34 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, const String&); 35 class WebAssemblyExceptionPrototype final : public JSNonFinalObject { 36 public: 37 using Base = JSNonFinalObject; 38 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable; 39 40 template<typename CellType, SubspaceAccess> 41 static IsoSubspace* subspaceFor(VM& vm) 42 { 43 STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(WebAssemblyExceptionPrototype, Base); 44 return &vm.plainObjectSpace; 45 } 46 47 static WebAssemblyExceptionPrototype* create(VM&, JSGlobalObject*, Structure*); 48 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 49 50 DECLARE_INFO; 51 52 private: 53 WebAssemblyExceptionPrototype(VM&, Structure*); 54 void finishCreation(VM&); 55 }; 35 56 36 57 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r279265 r283852 79 79 80 80 for (unsigned argIndex = 0; argIndex < signature.argumentCount(); ++argIndex) { 81 JSValue arg = callFrame->argument(argIndex); 82 switch (signature.argument(argIndex).kind) { 83 case Wasm::TypeKind::I32: 84 arg = JSValue::decode(arg.toInt32(globalObject)); 85 break; 86 case Wasm::TypeKind::TypeIdx: 87 case Wasm::TypeKind::Funcref: { 88 bool isNullable = signature.argument(argIndex).isNullable(); 89 WebAssemblyFunction* wasmFunction = nullptr; 90 WebAssemblyWrapperFunction* wasmWrapperFunction = nullptr; 91 if (!isWebAssemblyHostFunction(vm, arg, wasmFunction, wasmWrapperFunction) && (!isNullable || !arg.isNull())) 92 return JSValue::encode(throwException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Funcref must be an exported wasm function"))); 93 if (signature.argument(argIndex).kind == Wasm::TypeKind::TypeIdx && (wasmFunction || wasmWrapperFunction)) { 94 Wasm::SignatureIndex paramIndex = signature.argument(argIndex).index; 95 Wasm::SignatureIndex argIndex; 96 if (wasmFunction) 97 argIndex = wasmFunction->signatureIndex(); 98 else 99 argIndex = wasmWrapperFunction->signatureIndex(); 100 if (paramIndex != argIndex) 101 return JSValue::encode(throwException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Argument function did not match the reference type"))); 102 } 103 break; 104 } 105 case Wasm::TypeKind::Externref: 106 if (!signature.argument(argIndex).isNullable() && arg.isNull()) 107 return JSValue::encode(throwException(globalObject, scope, createJSWebAssemblyRuntimeError(globalObject, vm, "Non-null Externref cannot be null"))); 108 break; 109 case Wasm::TypeKind::I64: 110 arg = JSValue::decode(bitwise_cast<uint64_t>(arg.toBigInt64(globalObject))); 111 break; 112 case Wasm::TypeKind::F32: 113 arg = JSValue::decode(bitwise_cast<uint32_t>(arg.toFloat(globalObject))); 114 break; 115 case Wasm::TypeKind::F64: 116 arg = JSValue::decode(bitwise_cast<uint64_t>(arg.toNumber(globalObject))); 117 break; 118 case Wasm::TypeKind::Void: 119 case Wasm::TypeKind::Func: 120 case Wasm::TypeKind::RefNull: 121 case Wasm::TypeKind::Ref: 122 RELEASE_ASSERT_NOT_REACHED(); 123 } 81 uint64_t value = fromJSValue(globalObject, signature.argument(argIndex), callFrame->argument(argIndex)); 124 82 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 125 boxedArgs.append( arg);83 boxedArgs.append(JSValue::decode(value)); 126 84 } 127 85 … … 153 111 ASSERT(&wasmFunction->instance()->instance() == vm.wasmContext.load()); 154 112 EncodedJSValue rawResult = vmEntryToWasm(wasmFunction->jsEntrypoint(MustCheckArity).executableAddress(), &vm, &protoCallFrame); 155 // We need to make sure this is in a register or on the stack since it's stored in Vector<JSValue>.156 // This probably isn't strictly necessary, since the WebAssemblyFunction* should keep the instance157 // alive. But it's good hygiene.158 instance->use();159 113 if (prevWasmInstance != wasmInstance) { 160 114 // This is just for some extra safety instead of leaving a cached … … 168 122 vm.wasmContext.store(prevWasmInstance, vm.softStackLimit()); 169 123 RETURN_IF_EXCEPTION(scope, { }); 124 125 // We need to make sure this is in a register or on the stack since it's stored in Vector<JSValue>. 126 // This probably isn't strictly necessary, since the WebAssemblyFunction* should keep the instance 127 // alive. But it's good hygiene. 128 instance->use(); 170 129 171 130 return rawResult; -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r279265 r283852 38 38 #include "JSWebAssemblyLinkError.h" 39 39 #include "JSWebAssemblyModule.h" 40 #include "JSWebAssemblyTag.h" 40 41 #include "ObjectConstructor.h" 41 42 #include "WasmSignatureInlines.h" … … 131 132 case Wasm::ExternalKind::Global: 132 133 case Wasm::ExternalKind::Table: 134 case Wasm::ExternalKind::Exception: 133 135 break; 134 136 case Wasm::ExternalKind::Memory: … … 364 366 365 367 case Wasm::ExternalKind::Table: { 366 // 7. Otherwise (i is a table import):368 // 7. If i is a table import: 367 369 JSWebAssemblyTable* table = jsDynamicCast<JSWebAssemblyTable*>(vm, value); 368 370 // i. If v is not a WebAssembly.Table object, throw a WebAssembly.LinkError. … … 392 394 m_instance->setTable(vm, import.kindIndex, table); 393 395 RETURN_IF_EXCEPTION(scope, void()); 396 break; 397 } 398 399 case Wasm::ExternalKind::Exception: { 400 JSWebAssemblyTag* tag = jsDynamicCast<JSWebAssemblyTag*>(vm, value); 401 if (!tag) 402 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Tag import", "is not an instance of WebAssembly.Tag"))); 403 404 Wasm::SignatureIndex expectedSignatureIndex = moduleInformation.importExceptionSignatureIndices[import.kindIndex]; 405 406 if (expectedSignatureIndex != tag->tag().signature().index()) 407 return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "imported Tag", "signature doesn't match the imported WebAssembly Tag's signature"))); 408 409 m_instance->instance().addTag(tag->tag()); 394 410 break; 395 411 } … … 421 437 } 422 438 } 439 440 for (Wasm::SignatureIndex signatureIndex : moduleInformation.internalExceptionSignatureIndices) 441 m_instance->instance().addTag(Wasm::Tag::create(Wasm::SignatureInformation::get(signatureIndex))); 423 442 424 443 unsigned functionImportCount = codeBlock->functionImportCount(); … … 558 577 break; 559 578 } 579 case Wasm::ExternalKind::Exception: { 580 exportedValue = JSWebAssemblyTag::create(vm, globalObject, globalObject->m_webAssemblyTagStructure.get(globalObject), m_instance->instance().tag(exp.kindIndex)); 581 break; 582 } 560 583 } 561 584 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTagConstructor.h
r283851 r283852 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include "ErrorInstance.h" 30 #include "InternalFunction.h" 31 #include "WasmOps.h" 31 32 32 33 namespace JSC { 33 34 34 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, const String&); 35 class JSWebAssemblyTag; 36 class WebAssemblyTagPrototype; 37 38 namespace Wasm { 39 class Tag; 40 } 41 42 class WebAssemblyTagConstructor final : public InternalFunction { 43 public: 44 using Base = InternalFunction; 45 46 static WebAssemblyTagConstructor* create(VM&, Structure*, WebAssemblyTagPrototype*); 47 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 48 49 DECLARE_INFO; 50 51 private: 52 WebAssemblyTagConstructor(VM&, Structure*); 53 void finishCreation(VM&, WebAssemblyTagPrototype*); 54 }; 55 STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(WebAssemblyTagConstructor, InternalFunction); 35 56 36 57 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTagPrototype.h
r283851 r283852 1 1 /* 2 * Copyright (C) 20 16Apple Inc. All rights reserved.2 * Copyright (C) 2021 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 28 28 #if ENABLE(WEBASSEMBLY) 29 29 30 #include " ErrorInstance.h"30 #include "JSObject.h" 31 31 32 32 namespace JSC { 33 33 34 JSObject* createJSWebAssemblyRuntimeError(JSGlobalObject*, VM&, const String&); 34 class WebAssemblyTagPrototype final : public JSNonFinalObject { 35 public: 36 using Base = JSNonFinalObject; 37 static constexpr unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable; 38 39 template<typename CellType, SubspaceAccess> 40 static IsoSubspace* subspaceFor(VM& vm) 41 { 42 STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(WebAssemblyTagPrototype, Base); 43 return &vm.plainObjectSpace; 44 } 45 46 static WebAssemblyTagPrototype* create(VM&, JSGlobalObject*, Structure*); 47 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 48 49 DECLARE_INFO; 50 51 private: 52 WebAssemblyTagPrototype(VM&, Structure*); 53 void finishCreation(VM&); 54 }; 35 55 36 56 } // namespace JSC -
trunk/Source/JavaScriptCore/wasm/wasm.json
r279265 r283852 24 24 "ref_type": ["funcref", "externref", "type_idx"], 25 25 "external_kind": { 26 "Function": { "type": "uint8", "value": 0 }, 27 "Table": { "type": "uint8", "value": 1 }, 28 "Memory": { "type": "uint8", "value": 2 }, 29 "Global": { "type": "uint8", "value": 3 } 26 "Function": { "type": "uint8", "value": 0 }, 27 "Table": { "type": "uint8", "value": 1 }, 28 "Memory": { "type": "uint8", "value": 2 }, 29 "Global": { "type": "uint8", "value": 3 }, 30 "Exception": { "type": "uint8", "value": 4 } 30 31 }, 31 32 "section" : { 32 "Type": { "type": "varuint7", "value": 1, "description": "Function signature declarations" }, 33 "Import": { "type": "varuint7", "value": 2, "description": "Import declarations" }, 34 "Function": { "type": "varuint7", "value": 3, "description": "Function declarations" }, 35 "Table": { "type": "varuint7", "value": 4, "description": "Indirect function table and other tables" }, 36 "Memory": { "type": "varuint7", "value": 5, "description": "Memory attributes" }, 37 "Global": { "type": "varuint7", "value": 6, "description": "Global declarations" }, 38 "Export": { "type": "varuint7", "value": 7, "description": "Exports" }, 39 "Start": { "type": "varuint7", "value": 8, "description": "Start function declaration" }, 40 "Element": { "type": "varuint7", "value": 9, "description": "Elements section" }, 41 "Code": { "type": "varuint7", "value": 10, "description": "Function bodies (code)" }, 42 "Data": { "type": "varuint7", "value": 11, "description": "Data segments" } 33 "Type": { "type": "varuint7", "value": 1, "description": "Function signature declarations" }, 34 "Import": { "type": "varuint7", "value": 2, "description": "Import declarations" }, 35 "Function": { "type": "varuint7", "value": 3, "description": "Function declarations" }, 36 "Table": { "type": "varuint7", "value": 4, "description": "Indirect function table and other tables" }, 37 "Memory": { "type": "varuint7", "value": 5, "description": "Memory attributes" }, 38 "Exception": { "type": "varuint7", "value": 13, "description": "Exception declarations" }, 39 "Global": { "type": "varuint7", "value": 6, "description": "Global declarations" }, 40 "Export": { "type": "varuint7", "value": 7, "description": "Exports" }, 41 "Start": { "type": "varuint7", "value": 8, "description": "Start function declaration" }, 42 "Element": { "type": "varuint7", "value": 9, "description": "Elements section" }, 43 "Code": { "type": "varuint7", "value": 10, "description": "Function bodies (code)" }, 44 "Data": { "type": "varuint7", "value": 11, "description": "Data segments" }, 45 "DataCount": { "type": "varuint7", "value": 12, "description": "Number of data segments" } 43 46 }, 44 47 "opcode": { 45 48 "unreachable": { "category": "control", "value": 0, "return": [], "parameter": [], "immediate": [], "description": "trap immediately" }, 49 "nop": { "category": "control", "value": 1, "return": [], "parameter": [], "immediate": [], "description": "no operation" }, 46 50 "block": { "category": "control", "value": 2, "return": ["control"], "parameter": [], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin a sequence of expressions, yielding 0 or 1 values" }, 47 51 "loop": { "category": "control", "value": 3, "return": ["control"], "parameter": [], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin a block which can also form control flow loops" }, 48 52 "if": { "category": "control", "value": 4, "return": ["control"], "parameter": ["bool"], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin if expression" }, 49 53 "else": { "category": "control", "value": 5, "return": ["control"], "parameter": [], "immediate": [], "description": "begin else expression of if" }, 50 " select": { "category": "control", "value": 27, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [], "description": "select one of two values based on condition" },51 " annotated_select": { "category": "control", "value": 28, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [{"name": "target_types_count", "type": "varuint32", "description": "number of entries in the target types vector"},52 {"name": "target_types", "type": "value_type*", "description": "target types that indicate result of select instruction"}],53 "description": "the same as just select but with the annotation for result types" },54 "try": { "category": "control", "value": 6, "return": ["control"], "parameter": [], "immediate": [{"name": "sig", "type": "block_type"}], "description": "begin try expression" }, 55 "catch": { "category": "control", "value": 7, "return": ["control"], "parameter": [], "immediate": [{"name": "exn", "type": "varuint32"}], "description": "begin catch expression of try" }, 56 "throw": { "category": "control", "value": 8, "return": ["control"], "parameter": [], "immediate": [{"name": "exn", "type": "varuint32"}], "description": "throw exception" }, 57 "rethrow": { "category": "control", "value": 9, "return": ["control"], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "rethrow the exception at the top of the stack" }, 54 58 "br": { "category": "control", "value": 12, "return": [], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "break that targets an outer nested block" }, 55 59 "br_if": { "category": "control", "value": 13, "return": [], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "conditional break that targets an outer nested block" }, … … 59 63 "description": "branch table control flow construct" }, 60 64 "return": { "category": "control", "value": 15, "return": [], "parameter": [], "immediate": [], "description": "return zero or one value from this function" }, 65 "delegate": { "category": "control", "value": 24, "return": ["control"], "parameter": [], "immediate": [{"name": "relative_depth", "type": "varuint32"}], "description": "delegate to a parent try block" }, 66 "catch_all": { "category": "control", "value": 25, "return": ["control"], "parameter": [], "immediate": [], "description": "catch exceptions regardless of tag" }, 61 67 "drop": { "category": "control", "value": 26, "return": [], "parameter": ["any"], "immediate": [], "description": "ignore value" }, 62 "nop": { "category": "control", "value": 1, "return": [], "parameter": [], "immediate": [], "description": "no operation" }, 68 "select": { "category": "control", "value": 27, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [], "description": "select one of two values based on condition" }, 69 "annotated_select": { "category": "control", "value": 28, "return": ["prev"], "parameter": ["any", "prev", "bool"], "immediate": [{"name": "target_types_count", "type": "varuint32", "description": "number of entries in the target types vector"}, 70 {"name": "target_types", "type": "value_type*", "description": "target types that indicate result of select instruction"}], 71 "description": "the same as just select but with the annotation for result types" }, 63 72 "end": { "category": "control", "value": 11, "return": [], "parameter": [], "immediate": [], "description": "end a block, loop, or if" }, 64 73 "i32.const": { "category": "special", "value": 65, "return": ["i32"], "parameter": [], "immediate": [{"name": "value", "type": "varint32"}], "description": "a constant value interpreted as i32" }, -
trunk/Tools/ChangeLog
r283851 r283852 1 2021-10-08 Tadeu Zagallo <tzagallo@apple.com> 2 3 Implement the WebAssembly exception handling proposal 4 https://bugs.webkit.org/show_bug.cgi?id=229681 5 <rdar://81603387> 6 7 Reviewed by Keith Miller. 8 9 * Scripts/run-jsc-stress-tests: 10 1 11 2021-10-08 Jer Noble <jer.noble@apple.com> 2 12 -
trunk/Tools/Scripts/run-jsc-stress-tests
r283745 r283852 1228 1228 prepareExtraAbsoluteFiles(WASMTESTS_PATH, ["wasm.json"]) 1229 1229 prepareExtraRelativeFiles(modules.map { |f| "../" + f }, $collection) 1230 run("default-wasm", "-m", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1230 if optionalTestSpecificOptions[0] == :no_module 1231 optionalTestSpecificOptions.shift 1232 else 1233 optionalTestSpecificOptions.unshift "-m" 1234 end 1235 run("default-wasm", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1231 1236 if $mode != "quick" 1232 run("wasm-no-cjit-yes-tls-context", "- m", "--useFastTLSForWasmContext=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + optionalTestSpecificOptions))1233 run("wasm-eager", "-m",*(FTL_OPTIONS + EAGER_OPTIONS + optionalTestSpecificOptions))1234 run("wasm-eager-jettison", "- m", "--forceCodeBlockToJettisonDueToOldAge=true", "--useRandomizingExecutableIslandAllocation=true", "--verifyGC=true", *(FTL_OPTIONS + optionalTestSpecificOptions))1235 run("wasm-no-tls-context", "- m", "--useFastTLSForWasmContext=false", *(FTL_OPTIONS + optionalTestSpecificOptions))1236 run("wasm-slow-memory", "- m", "--useWebAssemblyFastMemory=false", *(FTL_OPTIONS + optionalTestSpecificOptions))1237 run("wasm-b3", "- m", "--useWasmLLInt=false", "--wasmBBQUsesAir=false", *(FTL_OPTIONS + optionalTestSpecificOptions))1238 run("wasm-air", "- m", "--useWasmLLInt=false", "--useRandomizingExecutableIslandAllocation=true", *(FTL_OPTIONS + optionalTestSpecificOptions))1239 run("wasm-collect-continuously", "- m", "--collectContinuously=true", "--verifyGC=true", *(FTL_OPTIONS + optionalTestSpecificOptions)) if shouldCollectContinuously?1237 run("wasm-no-cjit-yes-tls-context", "--useFastTLSForWasmContext=true", *(FTL_OPTIONS + NO_CJIT_OPTIONS + optionalTestSpecificOptions)) 1238 run("wasm-eager", *(FTL_OPTIONS + EAGER_OPTIONS + optionalTestSpecificOptions)) 1239 run("wasm-eager-jettison", "--forceCodeBlockToJettisonDueToOldAge=true", "--useRandomizingExecutableIslandAllocation=true", "--verifyGC=true", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1240 run("wasm-no-tls-context", "--useFastTLSForWasmContext=false", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1241 run("wasm-slow-memory", "--useWebAssemblyFastMemory=false", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1242 run("wasm-b3", "--useWasmLLInt=false", "--wasmBBQUsesAir=false", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1243 run("wasm-air", "--useWasmLLInt=false", "--useRandomizingExecutableIslandAllocation=true", *(FTL_OPTIONS + optionalTestSpecificOptions)) 1244 run("wasm-collect-continuously", "--collectContinuously=true", "--verifyGC=true", *(FTL_OPTIONS + optionalTestSpecificOptions)) if shouldCollectContinuously? 1240 1245 end 1241 1246 end
Note: See TracChangeset
for help on using the changeset viewer.