Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Unified Diff: src/wasm/wasm-js.cc

Issue 2709613008: Merged: [wasm] Embedder can control what buffers wasm compilation works on. (Closed)
Patch Set: Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime/runtime-test.cc ('k') | test/mjsunit/wasm/test-wasm-compilation-control.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/wasm/wasm-js.cc
diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
index fd8065d24240b5e3278a260d7bcf4f65901dc6bf..e909655e483e06d71c526558725a79d1b4ce2193 100644
--- a/src/wasm/wasm-js.cc
+++ b/src/wasm/wasm-js.cc
@@ -30,6 +30,11 @@ using v8::internal::wasm::ErrorThrower;
namespace v8 {
namespace {
+
+#define RANGE_ERROR_MSG \
+ "Wasm compilation exceeds internal limits in this context for the provided " \
+ "arguments"
+
i::Handle<i::String> v8_str(i::Isolate* isolate, const char* str) {
return isolate->factory()->NewStringFromAsciiChecked(str);
}
@@ -43,6 +48,100 @@ struct RawBuffer {
size_t size() { return static_cast<size_t>(end - start); }
};
+bool IsCompilationAllowed(i::Isolate* isolate, ErrorThrower* thrower,
+ v8::Local<v8::Value> source, bool is_async) {
+ // Allow caller to do one final check on thrower state, rather than
+ // one at each step. No information is lost - failure reason is captured
+ // in the thrower state.
+ if (thrower->error()) return false;
+
+ AllowWasmCompileCallback callback = isolate->allow_wasm_compile_callback();
+ if (callback != nullptr &&
+ !callback(reinterpret_cast<v8::Isolate*>(isolate), source, is_async)) {
+ thrower->RangeError(RANGE_ERROR_MSG);
+ return false;
+ }
+ return true;
+}
+
+bool IsInstantiationAllowed(i::Isolate* isolate, ErrorThrower* thrower,
+ v8::Local<v8::Value> module_or_bytes,
+ i::MaybeHandle<i::JSReceiver> ffi, bool is_async) {
+ // Allow caller to do one final check on thrower state, rather than
+ // one at each step. No information is lost - failure reason is captured
+ // in the thrower state.
+ if (thrower->error()) return false;
+ v8::MaybeLocal<v8::Value> v8_ffi;
+ if (!ffi.is_null()) {
+ v8_ffi = v8::Local<v8::Value>::Cast(Utils::ToLocal(ffi.ToHandleChecked()));
+ }
+ AllowWasmInstantiateCallback callback =
+ isolate->allow_wasm_instantiate_callback();
+ if (callback != nullptr &&
+ !callback(reinterpret_cast<v8::Isolate*>(isolate), module_or_bytes,
+ v8_ffi, is_async)) {
+ thrower->RangeError(RANGE_ERROR_MSG);
+ return false;
+ }
+ return true;
+}
+
+i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
+ const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
+ if (args.Length() < 1) {
+ thrower->TypeError("Argument 0 must be a buffer source");
+ return i::wasm::ModuleWireBytes(nullptr, nullptr);
+ }
+
+ const byte* start = nullptr;
+ size_t length = 0;
+ v8::Local<v8::Value> source = args[0];
+ if (source->IsArrayBuffer()) {
+ // A raw array buffer was passed.
+ Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source);
+ ArrayBuffer::Contents contents = buffer->GetContents();
+
+ start = reinterpret_cast<const byte*>(contents.Data());
+ length = contents.ByteLength();
+ } else if (source->IsTypedArray()) {
+ // A TypedArray was passed.
+ Local<TypedArray> array = Local<TypedArray>::Cast(source);
+ Local<ArrayBuffer> buffer = array->Buffer();
+
+ ArrayBuffer::Contents contents = buffer->GetContents();
+
+ start =
+ reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset();
+ length = array->ByteLength();
+ } else {
+ thrower->TypeError("Argument 0 must be a buffer source");
+ }
+ DCHECK_IMPLIES(length, start != nullptr);
+ if (length == 0) {
+ thrower->CompileError("BufferSource argument is empty");
+ }
+ if (length > i::wasm::kV8MaxWasmModuleSize) {
+ thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)",
+ i::wasm::kV8MaxWasmModuleSize, length);
+ }
+ if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr);
+ // TODO(titzer): use the handle as well?
+ return i::wasm::ModuleWireBytes(start, start + length);
+}
+
+i::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports(
+ const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
+ if (args.Length() < 2) return {};
+ if (args[1]->IsUndefined()) return {};
+
+ if (!args[1]->IsObject()) {
+ thrower->TypeError("Argument 1 must be an object");
+ return {};
+ }
+ Local<Object> obj = Local<Object>::Cast(args[1]);
+ return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
+}
+
RawBuffer GetRawBufferSource(
v8::Local<v8::Value> source, ErrorThrower* thrower) {
const byte* start = nullptr;
@@ -132,6 +231,7 @@ static bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value,
void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
"WebAssembly.compile()");
@@ -147,6 +247,11 @@ void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
return;
}
+ auto bytes = GetFirstArgumentAsBytes(args, &thrower);
JaideepBajwa 2017/02/25 05:13:57 USE(bytes); to suppress compiler unused variable w
+ if (!IsCompilationAllowed(i_isolate, &thrower, args[0], true)) {
+ resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
+ return;
+ }
i::MaybeHandle<i::JSObject> module_obj =
CreateModuleObject(isolate, args[0], &thrower);
@@ -179,6 +284,7 @@ void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::Isolate* isolate = args.GetIsolate();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
HandleScope scope(isolate);
ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
"WebAssembly.Module()");
@@ -187,6 +293,8 @@ void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
thrower.TypeError("Argument 0 must be a buffer source");
return;
}
+ auto bytes = GetFirstArgumentAsBytes(args, &thrower);
JaideepBajwa 2017/02/25 05:13:57 USE(bytes); to suppress compiler unused variable w
+ if (!IsCompilationAllowed(i_isolate, &thrower, args[0], false)) return;
i::MaybeHandle<i::JSObject> module_obj =
CreateModuleObject(isolate, args[0], &thrower);
@@ -325,6 +433,13 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
auto maybe_module = GetFirstArgumentAsModule(args, thrower);
+ if (thrower.error()) return;
+ auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
+ if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports,
+ false)) {
+ return;
+ }
+ DCHECK(!thrower.error());
if (!maybe_module.is_null()) {
MaybeLocal<Value> instance = InstantiateModuleImpl(
@@ -367,8 +482,19 @@ void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
return;
}
+
bool want_pair = !BrandCheck(
isolate, first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()));
+ auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
+ if (thrower.error()) {
+ resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
+ return;
+ }
+ if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports,
+ true)) {
+ resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
+ return;
+ }
i::Handle<i::WasmModuleObject> module_obj;
if (want_pair) {
i::MaybeHandle<i::WasmModuleObject> maybe_module_obj =
« no previous file with comments | « src/runtime/runtime-test.cc ('k') | test/mjsunit/wasm/test-wasm-compilation-control.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698