[wasm-gc] Add callback for Wasm GC origin trial
The callback can be used to enable / disable Wasm GC from Chrome or other users. For more simplicity and as many users of Wasm GC also use stringrefs, enabling it via the callback will also stringrefs. Bug: v8:7748 Change-Id: I474034eabe438f0ce9759c1d34dda12a99aa491e Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4165090 Auto-Submit: Matthias Liedtke <mliedtke@chromium.org> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org> Reviewed-by: Adam Klein <adamk@chromium.org> Commit-Queue: Matthias Liedtke <mliedtke@chromium.org> Cr-Commit-Position: refs/heads/main@{#85306}
This commit is contained in:
parent
6ca23f83ee
commit
debcabf7b5
@ -328,6 +328,10 @@ using WasmSimdEnabledCallback = bool (*)(Local<Context> context);
|
||||
// --- Callback for checking if WebAssembly exceptions are enabled ---
|
||||
using WasmExceptionsEnabledCallback = bool (*)(Local<Context> context);
|
||||
|
||||
// --- Callback for checking if WebAssembly GC is enabled ---
|
||||
// If the callback returns true, it will also enable Wasm stringrefs.
|
||||
using WasmGCEnabledCallback = bool (*)(Local<Context> context);
|
||||
|
||||
// --- Callback for checking if the SharedArrayBuffer constructor is enabled ---
|
||||
using SharedArrayBufferConstructorEnabledCallback =
|
||||
bool (*)(Local<Context> context);
|
||||
|
@ -1513,6 +1513,13 @@ class V8_EXPORT Isolate {
|
||||
V8_DEPRECATED("Wasm exceptions are always enabled")
|
||||
void SetWasmExceptionsEnabledCallback(WasmExceptionsEnabledCallback callback);
|
||||
|
||||
/**
|
||||
* Register callback to control whehter Wasm GC is enabled.
|
||||
* The callback overwrites the value of the flag.
|
||||
* If the callback returns true, it will also enable Wasm stringrefs.
|
||||
*/
|
||||
void SetWasmGCEnabledCallback(WasmGCEnabledCallback callback);
|
||||
|
||||
void SetSharedArrayBufferConstructorEnabledCallback(
|
||||
SharedArrayBufferConstructorEnabledCallback callback);
|
||||
|
||||
|
@ -9766,6 +9766,9 @@ CALLBACK_SETTER(WasmAsyncResolvePromiseCallback,
|
||||
CALLBACK_SETTER(WasmLoadSourceMapCallback, WasmLoadSourceMapCallback,
|
||||
wasm_load_source_map_callback)
|
||||
|
||||
CALLBACK_SETTER(WasmGCEnabledCallback, WasmGCEnabledCallback,
|
||||
wasm_gc_enabled_callback)
|
||||
|
||||
CALLBACK_SETTER(SharedArrayBufferConstructorEnabledCallback,
|
||||
SharedArrayBufferConstructorEnabledCallback,
|
||||
sharedarraybuffer_constructor_enabled_callback)
|
||||
|
@ -2940,6 +2940,31 @@ bool Isolate::IsSharedArrayBufferConstructorEnabled(Handle<Context> context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Isolate::IsWasmGCEnabled(Handle<Context> context) {
|
||||
#ifdef V8_ENABLE_WEBASSEMBLY
|
||||
if (wasm_gc_enabled_callback()) {
|
||||
v8::Local<v8::Context> api_context = v8::Utils::ToLocal(context);
|
||||
return wasm_gc_enabled_callback()(api_context);
|
||||
}
|
||||
return v8_flags.experimental_wasm_gc;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Isolate::IsWasmStringRefEnabled(Handle<Context> context) {
|
||||
// If Wasm GC is explicitly enabled via a callback, also enable stringref.
|
||||
#ifdef V8_ENABLE_WEBASSEMBLY
|
||||
if (wasm_gc_enabled_callback()) {
|
||||
v8::Local<v8::Context> api_context = v8::Utils::ToLocal(context);
|
||||
return wasm_gc_enabled_callback()(api_context);
|
||||
}
|
||||
return v8_flags.experimental_wasm_stringref;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
Handle<Context> Isolate::GetIncumbentContext() {
|
||||
JavaScriptFrameIterator it(this);
|
||||
|
||||
|
@ -510,6 +510,7 @@ using DebugObjectCache = std::vector<Handle<HeapObject>>;
|
||||
V(WasmLoadSourceMapCallback, wasm_load_source_map_callback, nullptr) \
|
||||
V(WasmSimdEnabledCallback, wasm_simd_enabled_callback, nullptr) \
|
||||
V(WasmExceptionsEnabledCallback, wasm_exceptions_enabled_callback, nullptr) \
|
||||
V(WasmGCEnabledCallback, wasm_gc_enabled_callback, nullptr) \
|
||||
/* State for Relocatable. */ \
|
||||
V(Relocatable*, relocatable_top, nullptr) \
|
||||
V(DebugObjectCache*, string_stream_debug_object_cache, nullptr) \
|
||||
@ -769,6 +770,9 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
|
||||
|
||||
bool IsSharedArrayBufferConstructorEnabled(Handle<Context> context);
|
||||
|
||||
bool IsWasmGCEnabled(Handle<Context> context);
|
||||
bool IsWasmStringRefEnabled(Handle<Context> context);
|
||||
|
||||
THREAD_LOCAL_TOP_ADDRESS(Context, pending_handler_context)
|
||||
THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_entrypoint)
|
||||
THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_constant_pool)
|
||||
|
@ -494,5 +494,17 @@ RUNTIME_FUNCTION(Runtime_FreezeWasmLazyCompilation) {
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
// This runtime function enables WebAssembly GC through an embedder
|
||||
// callback and thereby bypasses the value in v8_flags.
|
||||
RUNTIME_FUNCTION(Runtime_SetWasmGCEnabled) {
|
||||
DCHECK_EQ(1, args.length());
|
||||
bool enable = args.at(0)->BooleanValue(isolate);
|
||||
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
|
||||
WasmGCEnabledCallback enabled = [](v8::Local<v8::Context>) { return true; };
|
||||
WasmGCEnabledCallback disabled = [](v8::Local<v8::Context>) { return false; };
|
||||
v8_isolate->SetWasmGCEnabledCallback(enable ? enabled : disabled);
|
||||
return ReadOnlyRoots(isolate).undefined_value();
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -668,6 +668,7 @@ namespace internal {
|
||||
F(SerializeWasmModule, 1, 1) \
|
||||
F(SetWasmCompileControls, 2, 1) \
|
||||
F(SetWasmInstantiateControls, 0, 1) \
|
||||
F(SetWasmGCEnabled, 1, 1) \
|
||||
F(WasmGetNumberOfInstances, 1, 1) \
|
||||
F(WasmNumCodeSpaces, 1, 1) \
|
||||
F(WasmEnterDebugging, 0, 1) \
|
||||
|
@ -33,6 +33,12 @@ WasmFeatures WasmFeatures::FromIsolate(Isolate* isolate) {
|
||||
WasmFeatures WasmFeatures::FromContext(Isolate* isolate,
|
||||
Handle<Context> context) {
|
||||
WasmFeatures features = WasmFeatures::FromFlags();
|
||||
if (isolate->IsWasmGCEnabled(handle(isolate->context(), isolate))) {
|
||||
features.Add(kFeature_gc);
|
||||
}
|
||||
if (isolate->IsWasmStringRefEnabled(handle(isolate->context(), isolate))) {
|
||||
features.Add(kFeature_stringref);
|
||||
}
|
||||
// This space intentionally left blank for future Wasm origin trials.
|
||||
return features;
|
||||
}
|
||||
|
46
test/mjsunit/wasm/origin-trial-flags.js
Normal file
46
test/mjsunit/wasm/origin-trial-flags.js
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright 2023 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: --noexperimental-wasm-gc --no-experimental-wasm-stringref
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
function instantiateModuleWithGC() {
|
||||
// Build a WebAssembly module which uses Wasm GC features.
|
||||
const builder = new WasmModuleBuilder();
|
||||
builder.addFunction('main', makeSig([], [kWasmAnyRef]))
|
||||
.addBody([
|
||||
kExprI32Const, 42,
|
||||
kGCPrefix, kExprI31New,
|
||||
])
|
||||
.exportFunc();
|
||||
|
||||
return builder.instantiate();
|
||||
}
|
||||
|
||||
function instantiateModuleWithStringRef() {
|
||||
// Build a WebAssembly module which uses stringref features.
|
||||
const builder = new WasmModuleBuilder();
|
||||
builder.addFunction("main",
|
||||
makeSig([kWasmStringRef], [kWasmStringRef]))
|
||||
.addBody([kExprLocalGet, 0])
|
||||
.exportFunc();
|
||||
return builder.instantiate();
|
||||
}
|
||||
|
||||
// Due to --noexperimental-wasm-gc GC is disabled.
|
||||
assertThrows(instantiateModuleWithGC, WebAssembly.CompileError);
|
||||
// Due to --noexperimental-wasm-stringref stringrefs are not supported.
|
||||
assertThrows(instantiateModuleWithStringRef, WebAssembly.CompileError);
|
||||
// Disable WebAssembly GC explicitly.
|
||||
%SetWasmGCEnabled(false);
|
||||
assertThrows(instantiateModuleWithGC, WebAssembly.CompileError);
|
||||
assertThrows(instantiateModuleWithStringRef, WebAssembly.CompileError);
|
||||
// Enable WebAssembly GC explicitly.
|
||||
%SetWasmGCEnabled(true);
|
||||
assertEquals(42, instantiateModuleWithGC().exports.main());
|
||||
// Enabling Wasm GC via callback will also enable wasm stringref.
|
||||
let str = "Hello World!";
|
||||
assertSame(str, instantiateModuleWithStringRef().exports.main(str));
|
@ -13,6 +13,7 @@
|
||||
#include "include/v8-wasm.h"
|
||||
#include "src/api/api-inl.h"
|
||||
#include "src/handles/global-handles.h"
|
||||
#include "test/common/flag-utils.h"
|
||||
#include "test/unittests/test-utils.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
@ -156,4 +157,33 @@ TEST_F(ApiWasmTest, WasmStreamingSetCallback) {
|
||||
Promise::kPending);
|
||||
}
|
||||
|
||||
TEST_F(ApiWasmTest, WasmEnableDisableGC) {
|
||||
Local<Context> context_local = Context::New(isolate());
|
||||
Context::Scope context_scope(context_local);
|
||||
i::Handle<i::Context> context = v8::Utils::OpenHandle(*context_local);
|
||||
// When using the flags, stringref and GC are controlled independently.
|
||||
{
|
||||
i::FlagScope<bool> flag_gc(&i::v8_flags.experimental_wasm_gc, false);
|
||||
i::FlagScope<bool> flag_stringref(&i::v8_flags.experimental_wasm_stringref,
|
||||
true);
|
||||
EXPECT_FALSE(i_isolate()->IsWasmGCEnabled(context));
|
||||
EXPECT_TRUE(i_isolate()->IsWasmStringRefEnabled(context));
|
||||
}
|
||||
{
|
||||
i::FlagScope<bool> flag_gc(&i::v8_flags.experimental_wasm_gc, true);
|
||||
i::FlagScope<bool> flag_stringref(&i::v8_flags.experimental_wasm_stringref,
|
||||
false);
|
||||
EXPECT_TRUE(i_isolate()->IsWasmGCEnabled(context));
|
||||
EXPECT_FALSE(i_isolate()->IsWasmStringRefEnabled(context));
|
||||
}
|
||||
// When providing a callback, the callback will control GC and stringref.
|
||||
isolate()->SetWasmGCEnabledCallback([](auto) { return true; });
|
||||
EXPECT_TRUE(i_isolate()->IsWasmGCEnabled(context));
|
||||
EXPECT_TRUE(i_isolate()->IsWasmStringRefEnabled(context));
|
||||
isolate()->SetWasmGCEnabledCallback([](auto) { return false; });
|
||||
EXPECT_FALSE(i_isolate()->IsWasmGCEnabled(context));
|
||||
EXPECT_FALSE(i_isolate()->IsWasmStringRefEnabled(context));
|
||||
isolate()->SetWasmGCEnabledCallback(nullptr);
|
||||
}
|
||||
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user