-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[JSC] Inlined functions in OMG may have exception handlers
https://bugs.webkit.org/show_bug.cgi?id=272106 rdar://125181187 Reviewed by Justin Michaud and Yusuke Suzuki. Primarily fixes a bug where any WebAssembly function inlined in OMG was assumed to not have exception handlers. We now propagate a reference to the Wasm::CalleeGroup from the OMGPlan/OSREntryPlan to the B3IRGenerator, and read the hasExceptionHandlers() property from the inlined function's callee, similar to how the top-level function's generator is initialized in the plan. In addition to this, we also change when we set the callsite index. Currently we don't set the callsite index for any call or throw outside of a try block, which means that we might throw with an old callsite index set, and erroneously catch the exception in a previous block. To fix this, we now set a bool in the IR generator after a try or catch block ends, and set the callsite index for the first call/throw after a try/catch ends. Finally, consistent with BBQ, we don't write invalid callsite indices except for during the function prologue (before our first call/throw). We also don't write the callsite index at all in the case that we are known to be in a function without exception handlers. * JSTests/wasm/stress/inlinee-may-have-exception-handlers.js: Added. (async test): * JSTests/wasm/stress/rethrow-should-set-callsite-index.js: Added. (async test): * JSTests/wasm/stress/throw-should-set-callsite-index.js: Added. (async test): * Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp: (JSC::Wasm::B3IRGenerator::shouldSetCallSiteIndexAfterTry const): (JSC::Wasm::B3IRGenerator::didSetCallSiteIndexAfterTry): (JSC::Wasm::B3IRGenerator::B3IRGenerator): (JSC::Wasm::B3IRGenerator::preparePatchpointForExceptions): (JSC::Wasm::B3IRGenerator::addThrow): (JSC::Wasm::B3IRGenerator::addRethrow): (JSC::Wasm::B3IRGenerator::addEndToUnreachable): (JSC::Wasm::B3IRGenerator::emitInlineDirectCall): (JSC::Wasm::parseAndCompileB3): * Source/JavaScriptCore/wasm/WasmB3IRGenerator.h: * Source/JavaScriptCore/wasm/WasmIRGeneratorHelpers.h: (JSC::Wasm::PatchpointExceptionHandle::PatchpointExceptionHandle): (JSC::Wasm::PatchpointExceptionHandle::generate const): * Source/JavaScriptCore/wasm/WasmOMGPlan.cpp: (JSC::Wasm::OMGPlan::work): * Source/JavaScriptCore/wasm/WasmOSREntryPlan.cpp: (JSC::Wasm::OSREntryPlan::work): Canonical link: https://commits.webkit.org/272448.917@safari-7618-branch
- Loading branch information
Showing
8 changed files
with
209 additions
and
31 deletions.
There are no files selected for viewing
84 changes: 84 additions & 0 deletions
84
JSTests/wasm/stress/inlinee-may-have-exception-handlers.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import * as assert from '../assert.js'; | ||
import { instantiate } from "../wabt-wrapper.js"; | ||
|
||
let wat = ` | ||
(module | ||
(func $main (export "main") | ||
call $catcher | ||
i64.const 3127057505886423800 | ||
i64.const -5049743701649469475 | ||
i32.const 1279394412 | ||
i32.const 1249280136 | ||
i32.const -851957055 | ||
i32.div_s | ||
i32.div_s | ||
select (result i64) | ||
loop (result i64) | ||
i64.const 7052281334997434446 | ||
f64.const 0x1.f0094d7063744p+967 | ||
i64.trunc_sat_f64_u | ||
i64.rem_s | ||
end | ||
i64.add | ||
f64.convert_i64_s | ||
i32.const 993640798 | ||
i32.const -291103156 | ||
i32.atomic.rmw.xor offset=36014 | ||
f32.const 0x1.2e5784p-38 | ||
i64.const 8981315711995315489 | ||
i64.const 5932917051412947299 | ||
i64.const 6207621187208520631 | ||
i32.const 1636976966 | ||
select (result i64) | ||
i64.ne | ||
br 0 | ||
i32.trunc_sat_f32_u | ||
i32.div_s | ||
f64.const 0x1.7c35ecf56d865p-116 | ||
i32.const 1987656988 | ||
i64.const -1947434429939530388 | ||
f64.const -0x1.ca05a27b00c85p+372 | ||
i64.const 5169929820610505455 | ||
block (param f64 i32 f64 i32 i64 f64 i64) | ||
drop | ||
drop | ||
drop | ||
drop | ||
drop | ||
drop | ||
drop | ||
end | ||
) | ||
(func $empty (param i32)) | ||
(func $catcher (type 0) | ||
try | ||
i32.const 1 | ||
call $empty | ||
catch_all | ||
throw $exc | ||
end | ||
call $main | ||
) | ||
(memory 32 64) | ||
(tag $exc) | ||
) | ||
`; | ||
|
||
async function test() { | ||
let instance = await instantiate(wat, {}, {threads: true, exceptions: true}); | ||
|
||
let caughtCount = 0; | ||
for (let i = 0; i < 10; i ++) { | ||
try { | ||
instance.exports.main(); | ||
} catch (e) { | ||
// We expect to either overflow the stack, or end up throwing $exc back into JavaScript. | ||
assert.truthy(e instanceof RangeError || e instanceof WebAssembly.Exception); | ||
caughtCount ++; | ||
} | ||
} | ||
|
||
assert.eq(caughtCount, 10); | ||
} | ||
|
||
assert.asyncTest(test()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import * as assert from '../assert.js'; | ||
import { instantiate } from "../wabt-wrapper.js"; | ||
|
||
let wat = ` | ||
(module | ||
(type (func)) | ||
(tag $exc (type 0)) | ||
(func $empty) | ||
(func $rethrower | ||
try | ||
call $empty | ||
throw $exc | ||
catch_all | ||
rethrow 0 | ||
end | ||
) | ||
(func $call-rethrower | ||
call $rethrower | ||
) | ||
(export "call_rethrower" (func $call-rethrower)) | ||
) | ||
`; | ||
|
||
async function test() { | ||
let instance = await instantiate(wat, {}, {exceptions: true}); | ||
|
||
let caughtCount = 0; | ||
for (let i = 0; i < 10000; i ++) { | ||
try { | ||
instance.exports.call_rethrower(); | ||
} catch (e) { | ||
assert.instanceof(e, WebAssembly.Exception); | ||
caughtCount ++; | ||
} | ||
} | ||
|
||
assert.eq(caughtCount, 10000); | ||
} | ||
|
||
assert.asyncTest(test()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import * as assert from '../assert.js'; | ||
import { instantiate } from "../wabt-wrapper.js"; | ||
|
||
let wat = ` | ||
(module | ||
(type (func)) | ||
(tag $exc (type 0)) | ||
(func $empty) | ||
(func $thrower | ||
try | ||
call $empty | ||
catch_all | ||
end | ||
throw $exc | ||
) | ||
(func $call-thrower | ||
call $thrower | ||
) | ||
(export "call_thrower" (func $call-thrower)) | ||
) | ||
`; | ||
|
||
async function test() { | ||
let instance = await instantiate(wat, {}, {exceptions: true}); | ||
|
||
let caughtCount = 0; | ||
for (let i = 0; i < 10000; i ++) { | ||
try { | ||
instance.exports.call_thrower(); | ||
} catch (e) { | ||
assert.instanceof(e, WebAssembly.Exception); | ||
caughtCount ++; | ||
} | ||
} | ||
|
||
assert.eq(caughtCount, 10000); | ||
} | ||
|
||
assert.asyncTest(test()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.