Commit 409e02c1 authored by Jakob Kummerow's avatar Jakob Kummerow Committed by V8 LUCI CQ

[wasm-gc] Experiment: non-validated non-nullable locals

This introduces a new flag, --experimental-wasm-unsafe-nn-locals, which
allows arbitrary unvalidated local.get operations on non-nullable
locals.
For invalid accesses, this will crash. The intention is to allow module
producers to experiment; if they find these locals particularly useful,
we will add engine-side validation later.

Bug: v8:7748
Change-Id: I9a05747eaff312448ce0acf57a412e76679ff061
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3110192
Auto-Submit: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Manos Koukoutos <manoskouk@chromium.org>
Reviewed-by: 's avatarManos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#76489}
parent 1acb1cd9
......@@ -2224,6 +2224,7 @@ class WasmFullDecoder : public WasmDecoder<validate, decoding_mode> {
int non_defaultable = 0;
for (uint32_t index = params_count; index < this->num_locals(); index++) {
if (!VALIDATE(this->enabled_.has_nn_locals() ||
this->enabled_.has_unsafe_nn_locals() ||
this->local_type(index).is_defaultable())) {
this->DecodeError(
"Cannot define function-level local of non-defaultable type %s",
......
......@@ -138,7 +138,9 @@ class WasmGraphBuildingInterface {
while (index < num_locals) {
ValueType type = decoder->local_type(index);
TFNode* node;
if (decoder->enabled_.has_nn_locals() && !type.is_defaultable()) {
if ((decoder->enabled_.has_nn_locals() ||
decoder->enabled_.has_unsafe_nn_locals()) &&
!type.is_defaultable()) {
DCHECK(type.is_reference());
// TODO(jkummerow): Consider using "the hole" instead, to make any
// illegal uses more obvious.
......
......@@ -27,7 +27,12 @@
/* Non-specified, V8-only experimental additions to the GC proposal */ \
/* V8 side owner: jkummerow */ \
V(gc_experiments, "garbage collection V8-only experimental features", false) \
V(nn_locals, "allow non-defaultable/non-nullable locals", false) \
V(nn_locals, \
"allow non-defaultable/non-nullable locals, validated with 'until end of " \
"block' semantics", \
false) \
V(unsafe_nn_locals, \
"allow non-defaultable/non-nullable locals, no validation", false) \
\
/* Typed function references proposal. */ \
/* Official proposal: https://github.com/WebAssembly/function-references */ \
......
......@@ -3706,6 +3706,38 @@ TEST_F(FunctionBodyDecoderTest, AllowingNonDefaultableLocals) {
kAppendEnd, "uninitialized non-defaultable local: 2");
}
TEST_F(FunctionBodyDecoderTest, UnsafeNonDefaultableLocals) {
WASM_FEATURE_SCOPE(typed_funcref);
WASM_FEATURE_SCOPE(reftypes);
WASM_FEATURE_SCOPE(unsafe_nn_locals);
byte struct_type_index = builder.AddStruct({F(kWasmI32, true)});
ValueType rep = ref(struct_type_index);
FunctionSig sig(0, 1, &rep);
AddLocals(rep, 2);
// Declaring non-defaultable locals is fine.
ExpectValidates(&sig, {});
// Loading from an uninitialized non-defaultable local validates (but crashes
// when executed).
ExpectValidates(&sig, {WASM_LOCAL_GET(1), WASM_DROP});
// Loading from an initialized local is fine.
ExpectValidates(&sig, {WASM_LOCAL_SET(1, WASM_LOCAL_GET(0)),
WASM_LOCAL_GET(1), WASM_DROP});
ExpectValidates(&sig, {WASM_LOCAL_TEE(1, WASM_LOCAL_GET(0)),
WASM_LOCAL_GET(1), WASM_DROP, WASM_DROP});
// Non-nullable locals must be initialized with non-null values.
ExpectFailure(&sig, {WASM_LOCAL_SET(1, WASM_REF_NULL(struct_type_index))},
kAppendEnd,
"expected type (ref 0), found ref.null of type (ref null 0)");
// Block structure doesn't matter, everything validates.
ExpectValidates(&sig, {WASM_LOCAL_SET(1, WASM_LOCAL_GET(0)),
WASM_BLOCK(WASM_LOCAL_GET(1), WASM_DROP),
WASM_LOCAL_GET(1), WASM_DROP});
ExpectValidates(&sig,
{WASM_LOCAL_SET(1, WASM_LOCAL_GET(0)),
WASM_BLOCK(WASM_LOCAL_SET(2, WASM_LOCAL_GET(0))),
WASM_LOCAL_GET(1), WASM_DROP, WASM_LOCAL_GET(2), WASM_DROP});
}
TEST_F(FunctionBodyDecoderTest, RefEq) {
WASM_FEATURE_SCOPE(reftypes);
WASM_FEATURE_SCOPE(eh);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment