Commit 4372a9b5 authored by Emanuel Ziegler's avatar Emanuel Ziegler Committed by Commit Bot

[wasm] Implement optional init parameter for Table.grow

The typed function references proposal allows an optional second
parameter to Table.grow containing the initialization value for the
newly added entries for tables that do not support null defaults.

This CL adds this functionality but hides it behind a newly added
experimental flag --experimental-wasm-typed-funcref.

R=ahaas@chromium.org
CC=jkummerow@chromium.org
CC=manoskouk@chromium.org

Bug: v8:9495
Change-Id: Ia156aeacf95bc36a9fc182990f315c42075cbb7b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2207184
Commit-Queue: Emanuel Ziegler <ecmziegler@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67900}
parent c8d51a81
......@@ -33,7 +33,12 @@
/* Official proposal: https://github.com/WebAssembly/gc */ \
/* Prototype engineering spec: https://bit.ly/3cWcm6Q */ \
/* V8 side owner: jkummerow */ \
V(gc, "garbage collection", false)
V(gc, "garbage collection", false) \
\
/* Typed function references proposal. */ \
/* Official proposal: https://github.com/WebAssembly/function-references */ \
/* V8 side owner: ahaas */ \
V(typed_funcref, "typed function references", false)
// #############################################################################
// Staged features (disabled by default, but enabled via --wasm-staging (also
......
......@@ -1589,7 +1589,7 @@ void WebAssemblyTableGetLength(
v8::Number::New(isolate, receiver->current_length()));
}
// WebAssembly.Table.grow(num) -> num
// WebAssembly.Table.grow(num, init_value = null) -> num
void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
......@@ -1603,8 +1603,20 @@ void WebAssemblyTableGrow(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
int old_size = i::WasmTableObject::Grow(i_isolate, receiver, grow_by,
i_isolate->factory()->null_value());
i::Handle<i::Object> init_value = i_isolate->factory()->null_value();
auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
if (enabled_features.has_typed_funcref()) {
if (args.Length() >= 2 && !args[1]->IsUndefined()) {
init_value = Utils::OpenHandle(*args[1]);
}
if (!i::WasmTableObject::IsValidElement(i_isolate, receiver, init_value)) {
thrower.TypeError("Argument 1 must be a valid type for the table");
return;
}
}
int old_size =
i::WasmTableObject::Grow(i_isolate, receiver, grow_by, init_value);
if (old_size < 0) {
thrower.RangeError("failed to grow table by %u", grow_by);
......
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --experimental-wasm-typed-funcref
load('test/mjsunit/wasm/wasm-module-builder.js');
// Export an arbitrary function from a Wasm module (identity).
let foo = (() => {
let builder = new WasmModuleBuilder();
builder.addFunction('foo', kSig_i_i)
.addBody([kExprLocalGet, 0])
.exportAs('foo');
let module = new WebAssembly.Module(builder.toBuffer());
return (new WebAssembly.Instance(builder.toModule())).exports.foo;
})();
(function TableGrowWithInitializer() {
print(arguments.callee.name);
var table =
new WebAssembly.Table({element: 'anyfunc', initial: 0, maximum: 100});
table.grow(10);
table.grow(10, foo);
table.grow(10, null);
table.grow(10, undefined);
for (let i = 0; i < 10; i++) {
assertNull(table.get(i));
}
for (let i = 10; i < 20; i++) {
assertEquals(foo, table.get(i));
}
for (let i = 20; i < 40; i++) {
assertNull(table.get(i));
}
})();
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