Revert of [wasm] Embedder can control what buffers wasm compilation works on. (patchset #3 id:60001 of https://codereview.chromium.org/2699843003/ )
Reason for revert:
Introduces a new test failure/flake: https://build.chromium.org/p/client.v8/builders/V8%20Linux/builds/16427
Original issue's description:
> [wasm] Embedder can control what buffers wasm compilation works on.
>
> Two controls, one for instantiation and one for compilation. They allow
> the embedder (e.g. Chrome) check properties of the parameters of those
> two operations, and decide if they are allowed to continue.
>
> For example, Chrome may now decline compilation of certain size buffers,
> in synchronous cases; same for instantiation (where the buffer size
> refers to the size of the buffer containing wasm wire bytes)
>
> BUG=v8:5981
>
> Review-Url: https://codereview.chromium.org/2699843003
> Cr-Commit-Position: refs/heads/master@{#43295}
> Committed: d9bc0ffb16
TBR=bradnelson@chromium.org,titzer@chromium.org,mtrofin@chromium.org
# Not skipping CQ checks because original CL landed more than 1 days ago.
BUG=v8:5981
Review-Url: https://codereview.chromium.org/2701413002
Cr-Commit-Position: refs/heads/master@{#43303}
This commit is contained in:
parent
96afb852bc
commit
1bbbfb42d5
22
include/v8.h
22
include/v8.h
@ -5947,18 +5947,6 @@ typedef void (*FailedAccessCheckCallback)(Local<Object> target,
|
||||
*/
|
||||
typedef bool (*AllowCodeGenerationFromStringsCallback)(Local<Context> context);
|
||||
|
||||
// --- WASM compilation callbacks ---
|
||||
|
||||
/**
|
||||
* Callback to check if a buffer source may be compiled to WASM, given
|
||||
* the compilation is attempted as a promise or not.
|
||||
*/
|
||||
|
||||
typedef bool (*AllowWasmCompileCallback)(Local<Value> source, bool as_promise);
|
||||
|
||||
typedef bool (*AllowWasmInstantiateCallback)(Local<WasmCompiledModule> module,
|
||||
Local<Value> ffi, bool as_promise);
|
||||
|
||||
// --- Garbage Collection Callbacks ---
|
||||
|
||||
/**
|
||||
@ -7212,16 +7200,6 @@ class V8_EXPORT Isolate {
|
||||
void SetAllowCodeGenerationFromStringsCallback(
|
||||
AllowCodeGenerationFromStringsCallback callback);
|
||||
|
||||
/**
|
||||
* Set the callback to invoke to check if wasm compilation from
|
||||
* the specified object is allowed. By default, wasm compilation
|
||||
* is allowed.
|
||||
*
|
||||
* Similar for instantiate.
|
||||
*/
|
||||
void SetAllowWasmCompileCallback(AllowWasmCompileCallback callback);
|
||||
void SetAllowWasmInstantiateCallback(AllowWasmInstantiateCallback callback);
|
||||
|
||||
/**
|
||||
* Check if V8 is dead and therefore unusable. This is the case after
|
||||
* fatal errors such as out-of-memory situations.
|
||||
|
10
src/api.cc
10
src/api.cc
@ -8707,16 +8707,6 @@ void Isolate::SetAllowCodeGenerationFromStringsCallback(
|
||||
isolate->set_allow_code_gen_callback(callback);
|
||||
}
|
||||
|
||||
void Isolate::SetAllowWasmCompileCallback(AllowWasmCompileCallback callback) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||
isolate->set_allow_wasm_compile_callback(callback);
|
||||
}
|
||||
|
||||
void Isolate::SetAllowWasmInstantiateCallback(
|
||||
AllowWasmInstantiateCallback callback) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||
isolate->set_allow_wasm_instantiate_callback(callback);
|
||||
}
|
||||
|
||||
bool Isolate::IsDead() {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
|
||||
|
@ -394,8 +394,6 @@ typedef List<HeapObject*> DebugObjectCache;
|
||||
V(OOMErrorCallback, oom_behavior, nullptr) \
|
||||
V(LogEventCallback, event_logger, nullptr) \
|
||||
V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, nullptr) \
|
||||
V(AllowWasmCompileCallback, allow_wasm_compile_callback, nullptr) \
|
||||
V(AllowWasmInstantiateCallback, allow_wasm_instantiate_callback, nullptr) \
|
||||
V(ExternalReferenceRedirectorPointer*, external_reference_redirector, \
|
||||
nullptr) \
|
||||
/* State for Relocatable. */ \
|
||||
|
@ -19,27 +19,6 @@
|
||||
#include "src/wasm/wasm-module.h"
|
||||
#include "src/wasm/wasm-objects.h"
|
||||
|
||||
namespace {
|
||||
struct WasmCompileControls {
|
||||
uint32_t MaxWasmBufferSize = std::numeric_limits<uint32_t>::max();
|
||||
bool AllowAnySizeForAsync = true;
|
||||
} g_WasmCompileControls;
|
||||
|
||||
bool IsWasmCompileAllowed(v8::Local<v8::Value> value, bool is_async) {
|
||||
return (is_async && g_WasmCompileControls.AllowAnySizeForAsync) ||
|
||||
(v8::Local<v8::ArrayBuffer>::Cast(value)->ByteLength() <=
|
||||
g_WasmCompileControls.MaxWasmBufferSize);
|
||||
}
|
||||
|
||||
// Use the compile controls for instantiation, too
|
||||
bool IsWasmInstantiateAllowed(v8::Local<v8::WasmCompiledModule> module,
|
||||
v8::Local<v8::Value> ffi, bool is_async) {
|
||||
return (is_async && g_WasmCompileControls.AllowAnySizeForAsync) ||
|
||||
(static_cast<uint32_t>(module->GetWasmWireBytes()->Length()) <=
|
||||
g_WasmCompileControls.MaxWasmBufferSize);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -450,25 +429,6 @@ RUNTIME_FUNCTION(Runtime_CheckWasmWrapperElision) {
|
||||
return isolate->heap()->ToBoolean(count == 1);
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_SetWasmCompileControls) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK(args.length() == 2);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Smi, block_size, 0);
|
||||
CONVERT_BOOLEAN_ARG_CHECKED(allow_async, 1);
|
||||
g_WasmCompileControls.AllowAnySizeForAsync = allow_async;
|
||||
g_WasmCompileControls.MaxWasmBufferSize =
|
||||
static_cast<uint32_t>(block_size->value());
|
||||
isolate->set_allow_wasm_compile_callback(IsWasmCompileAllowed);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_SetWasmInstantiateControls) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK(args.length() == 0);
|
||||
isolate->set_allow_wasm_instantiate_callback(IsWasmInstantiateAllowed);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_NotifyContextDisposed) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(0, args.length());
|
||||
|
@ -609,8 +609,6 @@ namespace internal {
|
||||
F(ValidateWasmInstancesChain, 2, 1) \
|
||||
F(ValidateWasmModuleState, 1, 1) \
|
||||
F(ValidateWasmOrphanedInstance, 1, 1) \
|
||||
F(SetWasmCompileControls, 2, 1) \
|
||||
F(SetWasmInstantiateControls, 0, 1) \
|
||||
F(Verify, 1, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_TYPEDARRAY(F) \
|
||||
|
@ -79,18 +79,9 @@ RawBuffer GetRawBufferSource(
|
||||
|
||||
static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject(
|
||||
v8::Isolate* isolate, const v8::Local<v8::Value> source,
|
||||
ErrorThrower* thrower, bool async) {
|
||||
ErrorThrower* thrower) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
i::MaybeHandle<i::WasmModuleObject> nothing;
|
||||
|
||||
AllowWasmCompileCallback callback =
|
||||
reinterpret_cast<i::Isolate*>(isolate)->allow_wasm_compile_callback();
|
||||
if (callback != nullptr && !callback(source, async)) {
|
||||
thrower->RangeError(
|
||||
"Wasm compilation exceeds internal limits in this context for provided "
|
||||
"arguments");
|
||||
return nothing;
|
||||
}
|
||||
i::MaybeHandle<i::JSObject> nothing;
|
||||
|
||||
RawBuffer buffer = GetRawBufferSource(source, thrower);
|
||||
if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>();
|
||||
@ -148,7 +139,7 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
return;
|
||||
}
|
||||
i::MaybeHandle<i::JSObject> module_obj =
|
||||
CreateModuleObject(isolate, args[0], &thrower, true);
|
||||
CreateModuleObject(isolate, args[0], &thrower);
|
||||
|
||||
if (thrower.error()) {
|
||||
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
||||
@ -189,7 +180,7 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
}
|
||||
|
||||
i::MaybeHandle<i::JSObject> module_obj =
|
||||
CreateModuleObject(isolate, args[0], &thrower, false);
|
||||
CreateModuleObject(isolate, args[0], &thrower);
|
||||
if (module_obj.is_null()) return;
|
||||
|
||||
v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
|
||||
@ -198,8 +189,7 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
||||
MaybeLocal<Value> InstantiateModuleImpl(
|
||||
i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj,
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower,
|
||||
bool as_promise) {
|
||||
const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
|
||||
// It so happens that in both the WebAssembly.instantiate, as well as
|
||||
// WebAssembly.Instance ctor, the positions of the ffi object and memory
|
||||
// are the same. If that changes later, we refactor the consts into
|
||||
@ -220,17 +210,6 @@ MaybeLocal<Value> InstantiateModuleImpl(
|
||||
Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]);
|
||||
ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
|
||||
}
|
||||
AllowWasmInstantiateCallback allow_instantiate =
|
||||
i_isolate->allow_wasm_instantiate_callback();
|
||||
if (allow_instantiate != nullptr &&
|
||||
!allow_instantiate(Local<WasmCompiledModule>::Cast(Utils::ToLocal(
|
||||
i::Handle<i::JSObject>::cast(i_module_obj))),
|
||||
Utils::ToLocal(ffi), as_promise)) {
|
||||
thrower->RangeError(
|
||||
"Wasm instantiation exceeds internal limits in this context for "
|
||||
"provided arguments");
|
||||
return nothing;
|
||||
}
|
||||
|
||||
i::MaybeHandle<i::JSObject> instance =
|
||||
i::wasm::WasmModule::Instantiate(i_isolate, thrower, i_module_obj, ffi);
|
||||
@ -337,7 +316,7 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
||||
if (!maybe_module.is_null()) {
|
||||
MaybeLocal<Value> instance = InstantiateModuleImpl(
|
||||
i_isolate, maybe_module.ToHandleChecked(), args, &thrower, false);
|
||||
i_isolate, maybe_module.ToHandleChecked(), args, &thrower);
|
||||
|
||||
if (instance.IsEmpty()) {
|
||||
DCHECK(thrower.error());
|
||||
@ -382,7 +361,7 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
i::Handle<i::WasmModuleObject> module_obj;
|
||||
if (want_pair) {
|
||||
i::MaybeHandle<i::WasmModuleObject> maybe_module_obj =
|
||||
CreateModuleObject(isolate, args[0], &thrower, true);
|
||||
CreateModuleObject(isolate, args[0], &thrower);
|
||||
if (!maybe_module_obj.ToHandle(&module_obj)) {
|
||||
DCHECK(thrower.error());
|
||||
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
||||
@ -393,7 +372,7 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
}
|
||||
DCHECK(!module_obj.is_null());
|
||||
MaybeLocal<Value> instance =
|
||||
InstantiateModuleImpl(i_isolate, module_obj, args, &thrower, true);
|
||||
InstantiateModuleImpl(i_isolate, module_obj, args, &thrower);
|
||||
if (instance.IsEmpty()) {
|
||||
DCHECK(thrower.error());
|
||||
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
|
||||
|
@ -1,101 +0,0 @@
|
||||
// Copyright 2017 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: --allow-natives-syntax --validate-asm
|
||||
|
||||
load("test/mjsunit/wasm/wasm-constants.js");
|
||||
load("test/mjsunit/wasm/wasm-module-builder.js");
|
||||
|
||||
let buffer = (() => {
|
||||
var builder = new WasmModuleBuilder();
|
||||
builder.addFunction("f", kSig_i_v)
|
||||
.addBody([kExprI32Const, 42])
|
||||
.exportAs("f");
|
||||
return builder.toBuffer();
|
||||
})();
|
||||
|
||||
// allow up to the buffer size
|
||||
%SetWasmCompileControls(buffer.byteLength, true);
|
||||
%SetWasmInstantiateControls();
|
||||
var m = new WebAssembly.Module(buffer);
|
||||
var i = new WebAssembly.Instance(m);
|
||||
assertEquals(i.exports.f(), 42);
|
||||
|
||||
// the buffer can't compile synchronously, but we allow async compile
|
||||
%SetWasmCompileControls(buffer.byteLength - 1, true);
|
||||
// test first that we can't sync-instantiate this module anymore
|
||||
try {
|
||||
i = new WebAssembly.Instance(m);
|
||||
} catch (e) {
|
||||
assertTrue(e instanceof RangeError);
|
||||
}
|
||||
|
||||
//...but we can async-instantiate it
|
||||
|
||||
WebAssembly.instantiate(m)
|
||||
.then(instance => i = instance,
|
||||
assertUnreachable);
|
||||
%RunMicrotasks();
|
||||
assertTrue(i instanceof WebAssembly.Instance);
|
||||
|
||||
try {
|
||||
m = new WebAssembly.Module(buffer);
|
||||
assertUnreachable();
|
||||
} catch (e) {
|
||||
assertTrue(e instanceof RangeError);
|
||||
}
|
||||
|
||||
WebAssembly.compile(buffer)
|
||||
.then(res => m = res,
|
||||
m = null);
|
||||
|
||||
%RunMicrotasks();
|
||||
assertTrue(m instanceof WebAssembly.Module)
|
||||
|
||||
WebAssembly.instantiate(buffer)
|
||||
.then(res => m = res.module,
|
||||
m = null);
|
||||
|
||||
%RunMicrotasks();
|
||||
assertTrue(m instanceof WebAssembly.Module);
|
||||
|
||||
// not even async compile works.
|
||||
var ex;
|
||||
%SetWasmCompileControls(buffer.byteLength - 1, false);
|
||||
WebAssembly.compile(buffer)
|
||||
.then(ex = null,
|
||||
e => ex = e);
|
||||
|
||||
%RunMicrotasks();
|
||||
assertTrue(ex instanceof RangeError);
|
||||
|
||||
WebAssembly.instantiate(buffer)
|
||||
.then(ex = null,
|
||||
e => ex = e);
|
||||
%RunMicrotasks();
|
||||
assertTrue(ex instanceof RangeError);
|
||||
|
||||
|
||||
// For asm-wasm, these controls are ignored.
|
||||
%SetWasmCompileControls(0, false);
|
||||
function assertValidAsm(func) {
|
||||
assertTrue(%IsAsmWasmCode(func));
|
||||
}
|
||||
|
||||
function assertWasm(expected, func) {
|
||||
assertEquals(
|
||||
expected, func(undefined, undefined, new ArrayBuffer(1024)).caller());
|
||||
assertValidAsm(func);
|
||||
}
|
||||
|
||||
function TestAsmWasmIsUnaffected() {
|
||||
"use asm";
|
||||
function caller() {
|
||||
return 43;
|
||||
}
|
||||
|
||||
return {caller: caller};
|
||||
}
|
||||
|
||||
assertWasm(43, TestAsmWasmIsUnaffected);
|
Loading…
Reference in New Issue
Block a user