Skip to content

Commit

Permalink
Re-land [WASM-Function-References] Fix block signature parsing for re…
Browse files Browse the repository at this point in the history
…ftypes https://bugs.webkit.org/show_bug.cgi?id=247383

Reviewed by Justin Michaud.

This is a re-land of this patch that removes a perf issue introduced in
the previous attempts.

Adds a fast path for parsing potentially nested blocks with simple (one byte)
type signatures. Also changes BlockSignature definition in order to avoid
redundant calls to as<FunctionSignature>().

Also fixes the error case when a block signature refers to a non-function type.

* JSTests/wasm/function-references/block_signature.js: Added.
(module):
(async blockSignatureTest):
* JSTests/wasm/gc-spec-tests/type-equivalence.wast.js:
* JSTests/wasm/gc-spec-tests/type-subtyping.wast.js:
* JSTests/wasm/gc/block.js: Added.
(testBlockType):
* Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::ControlData::ControlData):
(JSC::Wasm::B3IRGenerator::ControlData::hasNonVoidresult const):
(JSC::Wasm::B3IRGenerator::ControlData::branchTargetArity const):
(JSC::Wasm::B3IRGenerator::ControlData::branchTargetType const):
(JSC::Wasm::B3IRGenerator::toB3ResultType):
(JSC::Wasm::B3IRGenerator::addLoop):
(JSC::Wasm::B3IRGenerator::addElseToUnreachable):
(JSC::Wasm::B3IRGenerator::endBlock):
(JSC::Wasm::B3IRGenerator::addEndToUnreachable):
* Source/JavaScriptCore/wasm/WasmBBQJIT.cpp:
(JSC::Wasm::BBQJIT::ControlData::ControlData):
(JSC::Wasm::BBQJIT::ControlData::branchTargetArity const):
(JSC::Wasm::BBQJIT::ControlData::branchTargetType const):
(JSC::Wasm::BBQJIT::ControlData::argumentType const):
(JSC::Wasm::BBQJIT::addBlock):
(JSC::Wasm::BBQJIT::addLoop):
(JSC::Wasm::BBQJIT::addIf):
(JSC::Wasm::BBQJIT::addElse):
(JSC::Wasm::BBQJIT::addElseToUnreachable):
(JSC::Wasm::BBQJIT::addTry):
(JSC::Wasm::BBQJIT::addEndToUnreachable):
* Source/JavaScriptCore/wasm/WasmCallingConvention.h:
(JSC::Wasm::WasmCallingConvention::callInformationFor const):
* Source/JavaScriptCore/wasm/WasmFormat.h:
(JSC::Wasm::isValueType):
* Source/JavaScriptCore/wasm/WasmFunctionParser.h:
(JSC::Wasm::splitStack):
(JSC::Wasm::FunctionParser<Context>::parseBody):
(JSC::Wasm::FunctionParser<Context>::unify):
(JSC::Wasm::FunctionParser<Context>::parseNestedBlocksEagerly):
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::switchToBlock):
* Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp:
(JSC::Wasm::IPIntControlType::branchTargetType const):
(JSC::Wasm::IPIntControlType::branchTargetArity const):
(JSC::Wasm::IPIntGenerator::addElse):
(JSC::Wasm::IPIntGenerator::addEndToUnreachable):
(JSC::Wasm::IPIntGenerator::endTopLevel):
* Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::ControlType::loop):
(JSC::Wasm::LLIntGenerator::ControlType::block):
(JSC::Wasm::LLIntGenerator::ControlType::if_):
(JSC::Wasm::LLIntGenerator::ControlType::createTry):
(JSC::Wasm::LLIntGenerator::ControlType::branchTargetArity const):
(JSC::Wasm::LLIntGenerator::ControlType::branchTargetType const):
(JSC::Wasm::LLIntGenerator::addElseToUnreachable):
(JSC::Wasm::LLIntGenerator::addReturn):
(JSC::Wasm::LLIntGenerator::addEndToUnreachable):
(JSC::Wasm::LLIntGenerator::endTopLevel):
* Source/JavaScriptCore/wasm/WasmParser.h:
(JSC::Wasm::Parser<SuccessType>::parseBlockSignature):
(JSC::Wasm::Parser<SuccessType>::parseReftypeSignature):
* Source/JavaScriptCore/wasm/WasmTypeDefinition.cpp:
(JSC::Wasm::TypeInformation::TypeInformation):
* Source/JavaScriptCore/wasm/WasmTypeDefinition.h:
(JSC::Wasm::TypeInformation::thunkFor const):

Canonical link: https://commits.webkit.org/271262@main
  • Loading branch information
takikawa committed Nov 29, 2023
1 parent b6b7455 commit 9a518a5
Show file tree
Hide file tree
Showing 14 changed files with 321 additions and 133 deletions.
62 changes: 62 additions & 0 deletions JSTests/wasm/function-references/block_signature.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//@ runWebAssemblySuite("--useWebAssemblyTypedFunctionReferences=true")
import * as assert from '../assert.js';

function module(bytes, valid = true) {
let buffer = new ArrayBuffer(bytes.length);
let view = new Uint8Array(buffer);
for (let i = 0; i < bytes.length; ++i) {
view[i] = bytes.charCodeAt(i);
}
return new WebAssembly.Module(buffer);
}

async function blockSignatureTest() {
/*
(module
(type (func))
(func (type 0))
(elem declare funcref (ref.func 0))
(func (result)
(block (result (ref 0))
(ref.func 0))
drop)
)
*/
new WebAssembly.Instance(module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x83\x80\x80\x80\x00\x02\x00\x00\x09\x87\x80\x80\x80\x00\x01\x07\x70\x01\xd2\x00\x0b\x0a\x96\x80\x80\x80\x00\x02\x82\x80\x80\x80\x00\x00\x0b\x89\x80\x80\x80\x00\x00\x02\x64\x00\xd2\x00\x0b\x1a\x0b"));

/*
(module
(type (func))
(func (result)
(block (result (ref null 0))
(ref.null 0))
drop)
)
*/
new WebAssembly.Instance(module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x63\x00\xd0\x00\x0b\x1a\x0b"));

// Both shorthand and Ref encodings tested below.
/*
(module
(func (result)
(block (result (ref null extern))
(ref.null extern))
drop)
)
*/
new WebAssembly.Instance(module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x6f\xd0\x6f\x0b\x1a\x0b"));
new WebAssembly.Instance(module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x63\x6f\xd0\x6f\x0b\x1a\x0b"));

/*
(module
(func (result)
(block (result (ref null func))
(ref.null func))
drop)
)
*/
new WebAssembly.Instance(module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8e\x80\x80\x80\x00\x01\x88\x80\x80\x80\x00\x00\x02\x70\xd0\x70\x0b\x1a\x0b"));
new WebAssembly.Instance(module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x84\x80\x80\x80\x00\x01\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x00\x0a\x8f\x80\x80\x80\x00\x01\x89\x80\x80\x80\x00\x00\x02\x63\x70\xd0\x70\x0b\x1a\x0b"));
}

assert.asyncTest(blockSignatureTest());
6 changes: 2 additions & 4 deletions JSTests/wasm/gc-spec-tests/type-equivalence.wast.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,11 @@ let $7 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x9e\x80\x80\x80\x00\x06\
// type-equivalence.wast:131
assert_return(() => call($7, "run", []));

// FIXME: https://bugs.webkit.org/show_bug.cgi?id=247383
// type-equivalence.wast:136
//let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x03\x60\x00\x01\x63\x00\x60\x00\x01\x63\x01\x60\x00\x00\x03\x84\x80\x80\x80\x00\x03\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x02\x02\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x02\x09\x8e\x80\x80\x80\x00\x01\x06\x00\x41\x00\x0b\x70\x02\xd2\x00\x0b\xd2\x01\x0b\x0a\xe4\x80\x80\x80\x00\x03\x84\x80\x80\x80\x00\x00\xd0\x00\x0b\x84\x80\x80\x80\x00\x00\xd0\x01\x0b\xcc\x80\x80\x80\x00\x00\x02\x63\x00\x41\x00\x11\x00\x00\x0b\x02\x63\x00\x41\x00\x11\x01\x00\x0b\x02\x63\x01\x41\x00\x11\x00\x00\x0b\x02\x63\x01\x41\x00\x11\x01\x00\x0b\x02\x63\x00\x41\x01\x11\x00\x00\x0b\x02\x63\x00\x41\x01\x11\x01\x00\x0b\x02\x63\x01\x41\x01\x11\x00\x00\x0b\x02\x63\x01\x41\x01\x11\x01\x00\x0b\x0c\x00\x0b");
let $8 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x8e\x80\x80\x80\x00\x03\x60\x00\x01\x63\x00\x60\x00\x01\x63\x01\x60\x00\x00\x03\x84\x80\x80\x80\x00\x03\x00\x01\x02\x04\x85\x80\x80\x80\x00\x01\x70\x01\x02\x02\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x02\x09\x8e\x80\x80\x80\x00\x01\x06\x00\x41\x00\x0b\x70\x02\xd2\x00\x0b\xd2\x01\x0b\x0a\xe4\x80\x80\x80\x00\x03\x84\x80\x80\x80\x00\x00\xd0\x00\x0b\x84\x80\x80\x80\x00\x00\xd0\x01\x0b\xcc\x80\x80\x80\x00\x00\x02\x63\x00\x41\x00\x11\x00\x00\x0b\x02\x63\x00\x41\x00\x11\x01\x00\x0b\x02\x63\x01\x41\x00\x11\x00\x00\x0b\x02\x63\x01\x41\x00\x11\x01\x00\x0b\x02\x63\x00\x41\x01\x11\x00\x00\x0b\x02\x63\x00\x41\x01\x11\x01\x00\x0b\x02\x63\x01\x41\x01\x11\x00\x00\x0b\x02\x63\x01\x41\x01\x11\x01\x00\x0b\x0c\x00\x0b");

// FIXME: https://bugs.webkit.org/show_bug.cgi?id=247383
// type-equivalence.wast:156
//assert_return(() => call($8, "run", []));
assert_return(() => call($8, "run", []));

// type-equivalence.wast:161
let $9 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xac\x80\x80\x80\x00\x03\x4e\x03\x60\x02\x7f\x64\x00\x00\x60\x02\x7f\x64\x02\x00\x60\x02\x7f\x64\x01\x00\x4e\x03\x60\x02\x7f\x64\x03\x00\x60\x02\x7f\x64\x05\x00\x60\x02\x7f\x64\x04\x00\x60\x00\x00\x03\x85\x80\x80\x80\x00\x04\x00\x01\x02\x06\x04\x85\x80\x80\x80\x00\x01\x70\x01\x03\x03\x07\x87\x80\x80\x80\x00\x01\x03\x72\x75\x6e\x00\x03\x09\x91\x80\x80\x80\x00\x01\x06\x00\x41\x00\x0b\x70\x03\xd2\x00\x0b\xd2\x01\x0b\xd2\x02\x0b\x0a\xd3\x80\x80\x80\x00\x04\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\xb8\x80\x80\x80\x00\x00\x41\x01\xd2\x00\x41\x00\x11\x00\x00\x41\x01\xd2\x02\x41\x01\x11\x01\x00\x41\x01\xd2\x01\x41\x02\x11\x02\x00\x41\x01\xd2\x00\x41\x00\x11\x03\x00\x41\x01\xd2\x02\x41\x01\x11\x04\x00\x41\x01\xd2\x01\x41\x02\x11\x05\x00\x0b");
Expand Down
30 changes: 15 additions & 15 deletions JSTests/wasm/gc-spec-tests/type-subtyping.wast.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,30 +49,30 @@ assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x9b\x80\x80\x80\x00\x02\x4e
// type-subtyping.wast:215
assert_invalid("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\xa8\x80\x80\x80\x00\x03\x4e\x02\x50\x00\x60\x00\x00\x50\x01\x00\x60\x00\x00\x4e\x02\x50\x00\x60\x00\x00\x50\x01\x00\x60\x00\x00\x4e\x02\x50\x00\x60\x00\x00\x50\x01\x02\x60\x00\x00\x03\x82\x80\x80\x80\x00\x01\x04\x06\x87\x80\x80\x80\x00\x01\x64\x02\x00\xd2\x00\x0b\x0a\x88\x80\x80\x80\x00\x01\x82\x80\x80\x80\x00\x00\x0b");

// FIXME: https://bugs.webkit.org/show_bug.cgi?id=247383
// type-subtyping.wast:229
//let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x9a\x80\x80\x80\x00\x04\x50\x00\x60\x00\x01\x70\x50\x01\x00\x60\x00\x01\x63\x01\x50\x01\x01\x60\x00\x01\x63\x02\x60\x00\x00\x03\x8b\x80\x80\x80\x00\x0a\x00\x01\x02\x03\x03\x03\x03\x03\x03\x03\x04\x85\x80\x80\x80\x00\x01\x70\x01\x03\x03\x07\xb7\x80\x80\x80\x00\x07\x03\x72\x75\x6e\x00\x03\x05\x66\x61\x69\x6c\x31\x00\x04\x05\x66\x61\x69\x6c\x32\x00\x05\x05\x66\x61\x69\x6c\x33\x00\x06\x05\x66\x61\x69\x6c\x34\x00\x07\x05\x66\x61\x69\x6c\x35\x00\x08\x05\x66\x61\x69\x6c\x36\x00\x09\x09\x91\x80\x80\x80\x00\x01\x06\x00\x41\x00\x0b\x70\x03\xd2\x00\x0b\xd2\x01\x0b\xd2\x02\x0b\x0a\x80\x82\x80\x80\x00\x0a\x84\x80\x80\x80\x00\x00\xd0\x70\x0b\x84\x80\x80\x80\x00\x00\xd0\x01\x0b\x84\x80\x80\x80\x00\x00\xd0\x02\x0b\xf9\x80\x80\x80\x00\x00\x02\x70\x41\x00\x11\x00\x00\x0b\x02\x70\x41\x01\x11\x00\x00\x0b\x02\x70\x41\x02\x11\x00\x00\x0b\x02\x63\x01\x41\x01\x11\x01\x00\x0b\x02\x63\x01\x41\x02\x11\x01\x00\x0b\x02\x63\x02\x41\x02\x11\x02\x00\x0b\x02\x63\x00\x41\x00\x25\x00\xfb\x16\x00\x0b\x02\x63\x00\x41\x01\x25\x00\xfb\x16\x00\x0b\x02\x63\x00\x41\x02\x25\x00\xfb\x16\x00\x0b\x02\x63\x01\x41\x01\x25\x00\xfb\x16\x01\x0b\x02\x63\x01\x41\x02\x25\x00\xfb\x16\x01\x0b\x02\x63\x02\x41\x02\x25\x00\xfb\x16\x02\x0b\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x63\x01\x41\x00\x11\x01\x00\x0b\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x63\x01\x41\x00\x11\x02\x00\x0b\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x63\x01\x41\x01\x11\x02\x00\x0b\x0c\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x25\x00\xfb\x16\x01\x0c\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x25\x00\xfb\x16\x02\x0c\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x01\x25\x00\xfb\x16\x02\x0c\x00\x0b");
//
let $15 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x9a\x80\x80\x80\x00\x04\x50\x00\x60\x00\x01\x70\x50\x01\x00\x60\x00\x01\x63\x01\x50\x01\x01\x60\x00\x01\x63\x02\x60\x00\x00\x03\x8b\x80\x80\x80\x00\x0a\x00\x01\x02\x03\x03\x03\x03\x03\x03\x03\x04\x85\x80\x80\x80\x00\x01\x70\x01\x03\x03\x07\xb7\x80\x80\x80\x00\x07\x03\x72\x75\x6e\x00\x03\x05\x66\x61\x69\x6c\x31\x00\x04\x05\x66\x61\x69\x6c\x32\x00\x05\x05\x66\x61\x69\x6c\x33\x00\x06\x05\x66\x61\x69\x6c\x34\x00\x07\x05\x66\x61\x69\x6c\x35\x00\x08\x05\x66\x61\x69\x6c\x36\x00\x09\x09\x91\x80\x80\x80\x00\x01\x06\x00\x41\x00\x0b\x70\x03\xd2\x00\x0b\xd2\x01\x0b\xd2\x02\x0b\x0a\x80\x82\x80\x80\x00\x0a\x84\x80\x80\x80\x00\x00\xd0\x70\x0b\x84\x80\x80\x80\x00\x00\xd0\x01\x0b\x84\x80\x80\x80\x00\x00\xd0\x02\x0b\xf9\x80\x80\x80\x00\x00\x02\x70\x41\x00\x11\x00\x00\x0b\x02\x70\x41\x01\x11\x00\x00\x0b\x02\x70\x41\x02\x11\x00\x00\x0b\x02\x63\x01\x41\x01\x11\x01\x00\x0b\x02\x63\x01\x41\x02\x11\x01\x00\x0b\x02\x63\x02\x41\x02\x11\x02\x00\x0b\x02\x63\x00\x41\x00\x25\x00\xfb\x16\x00\x0b\x02\x63\x00\x41\x01\x25\x00\xfb\x16\x00\x0b\x02\x63\x00\x41\x02\x25\x00\xfb\x16\x00\x0b\x02\x63\x01\x41\x01\x25\x00\xfb\x16\x01\x0b\x02\x63\x01\x41\x02\x25\x00\xfb\x16\x01\x0b\x02\x63\x02\x41\x02\x25\x00\xfb\x16\x02\x0b\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x63\x01\x41\x00\x11\x01\x00\x0b\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x63\x01\x41\x00\x11\x02\x00\x0b\x0c\x00\x0b\x8d\x80\x80\x80\x00\x00\x02\x63\x01\x41\x01\x11\x02\x00\x0b\x0c\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x25\x00\xfb\x16\x01\x0c\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x00\x25\x00\xfb\x16\x02\x0c\x00\x0b\x8b\x80\x80\x80\x00\x00\x41\x01\x25\x00\xfb\x16\x02\x0c\x00\x0b");

// FIXME: https://bugs.webkit.org/show_bug.cgi?id=260820
// type-subtyping.wast:282
//assert_return(() => call($15, "run", []));
//

// type-subtyping.wast:283
//assert_trap(() => call($15, "fail1", []));
//
assert_trap(() => call($15, "fail1", []));

// type-subtyping.wast:284
//assert_trap(() => call($15, "fail2", []));
//
assert_trap(() => call($15, "fail2", []));

// type-subtyping.wast:285
//assert_trap(() => call($15, "fail3", []));
//
assert_trap(() => call($15, "fail3", []));

// type-subtyping.wast:286
//assert_trap(() => call($15, "fail4", []));
//
assert_trap(() => call($15, "fail4", []));

// type-subtyping.wast:287
//assert_trap(() => call($15, "fail5", []));
//
assert_trap(() => call($15, "fail5", []));

// type-subtyping.wast:288
//assert_trap(() => call($15, "fail6", []));
assert_trap(() => call($15, "fail6", []));

// type-subtyping.wast:290
let $16 = instance("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x89\x80\x80\x80\x00\x02\x50\x00\x60\x00\x00\x60\x00\x00\x03\x87\x80\x80\x80\x00\x06\x00\x01\x01\x01\x01\x01\x04\x85\x80\x80\x80\x00\x01\x70\x01\x02\x02\x07\xa1\x80\x80\x80\x00\x04\x05\x66\x61\x69\x6c\x31\x00\x02\x05\x66\x61\x69\x6c\x32\x00\x03\x05\x66\x61\x69\x6c\x33\x00\x04\x05\x66\x61\x69\x6c\x34\x00\x05\x09\x8e\x80\x80\x80\x00\x01\x06\x00\x41\x00\x0b\x70\x02\xd2\x00\x0b\xd2\x01\x0b\x0a\xcb\x80\x80\x80\x00\x06\x82\x80\x80\x80\x00\x00\x0b\x82\x80\x80\x80\x00\x00\x0b\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x01\x11\x00\x00\x0b\x0b\x8a\x80\x80\x80\x00\x00\x02\x40\x41\x00\x11\x01\x00\x0b\x0b\x8a\x80\x80\x80\x00\x00\x41\x01\x25\x00\xfb\x16\x00\x1a\x0b\x8a\x80\x80\x80\x00\x00\x41\x00\x25\x00\xfb\x16\x01\x1a\x0b");
Expand Down
44 changes: 44 additions & 0 deletions JSTests/wasm/gc/block.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//@ runWebAssemblySuite("--useWebAssemblyTypedFunctionReferences=true", "--useWebAssemblyGC=true")

import * as assert from "../assert.js";
import { compile, instantiate } from "./wast-wrapper.js";

function testBlockType() {
compile(`
(module
(rec (type (func (result (ref null 0)))))
(func (block (type 0) (ref.null 0)) drop))
`);

assert.throws(
() => compile(`
(module
(type (array i32))
(func (block (type 0))))
`),
WebAssembly.CompileError,
"WebAssembly.Module doesn't parse at byte 3: can't get block's signature, in function at index 0"
);

assert.throws(
() => compile(`
(module
(type (struct))
(func (block (type 0))))
`),
WebAssembly.CompileError,
"WebAssembly.Module doesn't parse at byte 3: can't get block's signature, in function at index 0"
);

assert.throws(
() => compile(`
(module
(type (array i32))
(func (type 0)))
`),
WebAssembly.CompileError,
"WebAssembly.Module doesn't parse at byte 0: type signature was not a function signature, in function at index 0"
);
}

testBlockType();
48 changes: 24 additions & 24 deletions Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,14 @@ class B3IRGenerator {
{
ASSERT(type != BlockType::Try && type != BlockType::Catch);
if (type != BlockType::TopLevel)
m_stackSize -= signature->as<FunctionSignature>()->argumentCount();
m_stackSize -= signature->argumentCount();

if (type == BlockType::Loop) {
for (unsigned i = 0; i < signature->as<FunctionSignature>()->argumentCount(); ++i)
phis.append(proc.add<Value>(Phi, toB3Type(signature->as<FunctionSignature>()->argumentType(i)), origin));
for (unsigned i = 0; i < signature->argumentCount(); ++i)
phis.append(proc.add<Value>(Phi, toB3Type(signature->argumentType(i)), origin));
} else {
for (unsigned i = 0; i < signature->as<FunctionSignature>()->returnCount(); ++i)
phis.append(proc.add<Value>(Phi, toB3Type(signature->as<FunctionSignature>()->returnType(i)), origin));
for (unsigned i = 0; i < signature->returnCount(); ++i)
phis.append(proc.add<Value>(Phi, toB3Type(signature->returnType(i)), origin));
}
}

Expand All @@ -147,9 +147,9 @@ class B3IRGenerator {
, m_tryCatchDepth(tryDepth)
{
ASSERT(type == BlockType::Try);
m_stackSize -= signature->as<FunctionSignature>()->argumentCount();
for (unsigned i = 0; i < signature->as<FunctionSignature>()->returnCount(); ++i)
phis.append(proc.add<Value>(Phi, toB3Type(signature->as<FunctionSignature>()->returnType(i)), origin));
m_stackSize -= signature->argumentCount();
for (unsigned i = 0; i < signature->returnCount(); ++i)
phis.append(proc.add<Value>(Phi, toB3Type(signature->returnType(i)), origin));
}

ControlData()
Expand Down Expand Up @@ -202,7 +202,7 @@ class B3IRGenerator {

BlockSignature signature() const { return m_signature; }

bool hasNonVoidresult() const { return m_signature->as<FunctionSignature>()->returnsVoid(); }
bool hasNonVoidresult() const { return m_signature->returnsVoid(); }

BasicBlock* targetBlockForBranch()
{
Expand Down Expand Up @@ -239,16 +239,16 @@ class B3IRGenerator {
FunctionArgCount branchTargetArity() const
{
if (blockType() == BlockType::Loop)
return m_signature->as<FunctionSignature>()->argumentCount();
return m_signature->as<FunctionSignature>()->returnCount();
return m_signature->argumentCount();
return m_signature->returnCount();
}

Type branchTargetType(unsigned i) const
{
ASSERT(i < branchTargetArity());
if (blockType() == BlockType::Loop)
return m_signature->as<FunctionSignature>()->argumentType(i);
return m_signature->as<FunctionSignature>()->returnType(i);
return m_signature->argumentType(i);
return m_signature->returnType(i);
}

unsigned tryStart() const
Expand Down Expand Up @@ -715,7 +715,7 @@ class B3IRGenerator {
void insertEntrySwitch();
void insertConstants();

B3::Type toB3ResultType(BlockSignature);
B3::Type toB3ResultType(const TypeDefinition*);

void addStackMap(unsigned callSiteIndex, StackMap&& stackmap)
{
Expand Down Expand Up @@ -921,7 +921,7 @@ class B3IRGenerator {
Vector<UnlinkedWasmToWasmCall>& m_unlinkedWasmToWasmCalls; // List each call site and the function index whose address it should be patched with.
unsigned* m_osrEntryScratchBufferSize;
HashMap<ValueKey, Value*> m_constantPool;
HashMap<BlockSignature, B3::Type> m_tupleMap;
HashMap<const TypeDefinition*, B3::Type> m_tupleMap;
InsertionSet m_constantInsertionValues;
Value* m_framePointer { nullptr };
bool m_makesCalls { false };
Expand Down Expand Up @@ -1309,7 +1309,7 @@ void B3IRGenerator::insertConstants()
m_constantInsertionValues.execute(block);
}

B3::Type B3IRGenerator::toB3ResultType(BlockSignature returnType)
B3::Type B3IRGenerator::toB3ResultType(const TypeDefinition* returnType)
{
if (returnType->as<FunctionSignature>()->returnsVoid())
return B3::Void;
Expand Down Expand Up @@ -4023,8 +4023,8 @@ auto B3IRGenerator::addLoop(BlockSignature signature, Stack& enclosingStack, Con

block = ControlData(m_proc, origin(), signature, BlockType::Loop, m_stackSize, continuation, body);

unsigned offset = enclosingStack.size() - signature->as<FunctionSignature>()->argumentCount();
for (unsigned i = 0; i < signature->as<FunctionSignature>()->argumentCount(); ++i) {
unsigned offset = enclosingStack.size() - signature->argumentCount();
for (unsigned i = 0; i < signature->argumentCount(); ++i) {
TypedExpression value = enclosingStack.at(offset + i);
Value* phi = block.phis[i];
m_currentBlock->appendNew<UpsilonValue>(m_proc, origin(), get(value), phi);
Expand Down Expand Up @@ -4126,7 +4126,7 @@ auto B3IRGenerator::addElse(ControlData& data, const Stack& currentStack) -> Par
auto B3IRGenerator::addElseToUnreachable(ControlData& data) -> PartialResult
{
ASSERT(data.blockType() == BlockType::If);
m_stackSize = data.stackSize() + data.m_signature->as<FunctionSignature>()->argumentCount();
m_stackSize = data.stackSize() + data.m_signature->argumentCount();
m_currentBlock = data.special;
data.convertIfToBlock();
TRACE_CF("ELSE");
Expand Down Expand Up @@ -4441,7 +4441,7 @@ auto B3IRGenerator::endBlock(ControlEntry& entry, Stack& expressionStack) -> Par
{
ControlData& data = entry.controlData;

ASSERT(expressionStack.size() == data.signature()->as<FunctionSignature>()->returnCount());
ASSERT(expressionStack.size() == data.signature()->returnCount());
if (data.blockType() != BlockType::Loop)
unifyValuesWithBlock(expressionStack, data);

Expand All @@ -4464,19 +4464,19 @@ auto B3IRGenerator::addEndToUnreachable(ControlEntry& entry, const Stack& expres
--m_tryCatchDepth;

if (data.blockType() != BlockType::Loop) {
for (unsigned i = 0; i < data.signature()->as<FunctionSignature>()->returnCount(); ++i) {
for (unsigned i = 0; i < data.signature()->returnCount(); ++i) {
Value* result = data.phis[i];
m_currentBlock->append(result);
entry.enclosedExpressionStack.constructAndAppend(data.signature()->as<FunctionSignature>()->returnType(i), push(result));
entry.enclosedExpressionStack.constructAndAppend(data.signature()->returnType(i), push(result));
}
} else {
m_outerLoops.removeLast();
for (unsigned i = 0; i < data.signature()->as<FunctionSignature>()->returnCount(); ++i) {
for (unsigned i = 0; i < data.signature()->returnCount(); ++i) {
if (i < expressionStack.size()) {
++m_stackSize;
entry.enclosedExpressionStack.append(expressionStack[i]);
} else {
Type returnType = data.signature()->as<FunctionSignature>()->returnType(i);
Type returnType = data.signature()->returnType(i);
entry.enclosedExpressionStack.constructAndAppend(returnType, push(constant(toB3Type(returnType), 0xbbadbeef)));
}
}
Expand Down
Loading

0 comments on commit 9a518a5

Please sign in to comment.