Commit 835ff2bc authored by Ng Zhi An's avatar Ng Zhi An Committed by V8 LUCI CQ

[wasm][api] Add WasmModuleObject::Compile api function

This is a partial revert of https://crrev.com/c/2033171 to bring back
WasmModuleObject::Compile, that compiles Wasm bytes into a Wasm module.

Also adding a simple test to make sure the compile works.

There are some users, e.g. Cloudflare, Halide, see bug for more details.

Bug: v8:10461
Change-Id: I199abea108311025decad793d2232a08bba05d38
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3292088
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78003}
parent 41f99df7
......@@ -103,6 +103,12 @@ class V8_EXPORT WasmModuleObject : public Object {
*/
CompiledWasmModule GetCompiledModule();
/**
* Compile a Wasm module from the provided uncompiled bytes.
*/
static MaybeLocal<WasmModuleObject> Compile(
Isolate* isolate, MemorySpan<const uint8_t> wire_bytes);
V8_INLINE static WasmModuleObject* Cast(Value* value) {
#ifdef V8_ENABLE_CHECKS
CheckCast(value);
......
......@@ -7858,6 +7858,37 @@ MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
#endif // V8_ENABLE_WEBASSEMBLY
}
MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
Isolate* isolate, MemorySpan<const uint8_t> wire_bytes) {
#if V8_ENABLE_WEBASSEMBLY
const uint8_t* start = wire_bytes.data();
size_t length = wire_bytes.size();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
if (!i::wasm::IsWasmCodegenAllowed(i_isolate, i_isolate->native_context())) {
return MaybeLocal<WasmModuleObject>();
}
i::MaybeHandle<i::JSObject> maybe_compiled;
{
i::wasm::ErrorThrower thrower(i_isolate, "WasmModuleObject::Compile()");
auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate);
maybe_compiled = i::wasm::GetWasmEngine()->SyncCompile(
i_isolate, enabled_features, &thrower,
i::wasm::ModuleWireBytes(start, start + length));
}
CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_pending_exception());
if (maybe_compiled.is_null()) {
i_isolate->OptionalRescheduleException(false);
return MaybeLocal<WasmModuleObject>();
}
return Local<WasmModuleObject>::Cast(
Utils::ToLocal(maybe_compiled.ToHandleChecked()));
#else
Utils::ApiCheck(false, "WasmModuleObject::Compile",
"WebAssembly support is not enabled.");
UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
}
WasmModuleObjectBuilderStreaming::WasmModuleObjectBuilderStreaming(
Isolate* isolate) {
USE(isolate_);
......
......@@ -581,6 +581,7 @@
'test-api/WasmI64AtomicWaitCallback': [SKIP],
'test-api/WasmSetJitCodeEventHandler': [SKIP],
'test-api-wasm/WasmStreaming*': [SKIP],
'test-api-wasm/WasmCompileToWasmModuleObject': [SKIP],
'test-backing-store/Run_WasmModule_Buffer_Externalized_Regression_UseAfterFree': [SKIP],
'test-c-wasm-entry/*': [SKIP],
'test-compilation-cache/*': [SKIP],
......
......@@ -20,6 +20,10 @@ namespace {
bool wasm_streaming_callback_got_called = false;
bool wasm_streaming_data_got_collected = false;
// The bytes of a minimal WebAssembly module.
const uint8_t kMinimalWasmModuleBytes[]{0x00, 0x61, 0x73, 0x6d,
0x01, 0x00, 0x00, 0x00};
void WasmStreamingTestFinalizer(const v8::WeakCallbackInfo<void>& data) {
CHECK(!wasm_streaming_data_got_collected);
wasm_streaming_data_got_collected = true;
......@@ -54,9 +58,8 @@ void WasmStreamingCallbackTestFinishWithSuccess(
const v8::FunctionCallbackInfo<v8::Value>& args) {
std::shared_ptr<v8::WasmStreaming> streaming =
v8::WasmStreaming::Unpack(args.GetIsolate(), args.Data());
// The bytes of a minimal WebAssembly module.
const uint8_t bytes[]{0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00};
streaming->OnBytesReceived(bytes, arraysize(bytes));
streaming->OnBytesReceived(kMinimalWasmModuleBytes,
arraysize(kMinimalWasmModuleBytes));
streaming->Finish();
}
......@@ -133,6 +136,16 @@ TEST(WasmStreamingAbortWithoutReject) {
v8::Promise::kPending);
}
TEST(WasmCompileToWasmModuleObject) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
auto maybe_module = v8::WasmModuleObject::Compile(
CcTest::isolate(),
{kMinimalWasmModuleBytes, arraysize(kMinimalWasmModuleBytes)});
CHECK(!maybe_module.IsEmpty());
}
namespace {
bool wasm_simd_enabled_value = false;
......
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