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

Side by Side Diff: src/wasm/wasm-js.cc

Issue 2699843003: [wasm] Embedder can control what buffers wasm compilation works on. (Closed)
Patch Set: static initializers 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/api-natives.h" 5 #include "src/api-natives.h"
6 #include "src/api.h" 6 #include "src/api.h"
7 #include "src/asmjs/asm-js.h" 7 #include "src/asmjs/asm-js.h"
8 #include "src/asmjs/asm-typer.h" 8 #include "src/asmjs/asm-typer.h"
9 #include "src/asmjs/asm-wasm-builder.h" 9 #include "src/asmjs/asm-wasm-builder.h"
10 #include "src/assert-scope.h" 10 #include "src/assert-scope.h"
(...skipping 13 matching lines...) Expand all
24 #include "src/wasm/wasm-objects.h" 24 #include "src/wasm/wasm-objects.h"
25 #include "src/wasm/wasm-result.h" 25 #include "src/wasm/wasm-result.h"
26 26
27 typedef uint8_t byte; 27 typedef uint8_t byte;
28 28
29 using v8::internal::wasm::ErrorThrower; 29 using v8::internal::wasm::ErrorThrower;
30 30
31 namespace v8 { 31 namespace v8 {
32 32
33 namespace { 33 namespace {
34
35 #define RANGE_ERROR_MSG \
36 "Wasm compilation exceeds internal limits in this context for the provided " \
37 "arguments"
38
34 // TODO(wasm): move brand check to the respective types, and don't throw 39 // TODO(wasm): move brand check to the respective types, and don't throw
35 // in it, rather, use a provided ErrorThrower, or let caller handle it. 40 // in it, rather, use a provided ErrorThrower, or let caller handle it.
36 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) { 41 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
37 if (!value->IsJSObject()) return false; 42 if (!value->IsJSObject()) return false;
38 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); 43 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
39 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym); 44 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
40 return has_brand.FromMaybe(false); 45 return has_brand.FromMaybe(false);
41 } 46 }
42 47
43 static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym, 48 static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym,
(...skipping 22 matching lines...) Expand all
66 i::handle(i_context->wasm_module_sym()), thrower, 71 i::handle(i_context->wasm_module_sym()), thrower,
67 "Argument 0 must be a WebAssembly.Module")) { 72 "Argument 0 must be a WebAssembly.Module")) {
68 return {}; 73 return {};
69 } 74 }
70 75
71 Local<Object> module_obj = Local<Object>::Cast(args[0]); 76 Local<Object> module_obj = Local<Object>::Cast(args[0]);
72 return i::Handle<i::WasmModuleObject>::cast( 77 return i::Handle<i::WasmModuleObject>::cast(
73 v8::Utils::OpenHandle(*module_obj)); 78 v8::Utils::OpenHandle(*module_obj));
74 } 79 }
75 80
81 bool IsCompilationAllowed(i::Isolate* isolate, ErrorThrower* thrower,
82 v8::Local<v8::Value> source, bool is_async) {
83 // Allow caller to do one final check on thrower state, rather than
84 // one at each step. No information is lost - failure reason is captured
85 // in the thrower state.
86 if (thrower->error()) return false;
87
88 AllowWasmCompileCallback callback = isolate->allow_wasm_compile_callback();
89 if (callback != nullptr &&
90 !callback(reinterpret_cast<v8::Isolate*>(isolate), source, is_async)) {
91 thrower->RangeError(RANGE_ERROR_MSG);
92 return false;
93 }
94 return true;
95 }
96
97 bool IsInstantiationAllowed(i::Isolate* isolate, ErrorThrower* thrower,
98 v8::Local<v8::Value> module_or_bytes,
99 i::MaybeHandle<i::JSReceiver> ffi, bool is_async) {
100 // Allow caller to do one final check on thrower state, rather than
101 // one at each step. No information is lost - failure reason is captured
102 // in the thrower state.
103 if (thrower->error()) return false;
104 v8::MaybeLocal<v8::Value> v8_ffi;
105 if (!ffi.is_null()) {
106 v8_ffi = v8::Local<v8::Value>::Cast(Utils::ToLocal(ffi.ToHandleChecked()));
107 }
108 AllowWasmInstantiateCallback callback =
109 isolate->allow_wasm_instantiate_callback();
110 if (callback != nullptr &&
111 !callback(reinterpret_cast<v8::Isolate*>(isolate), module_or_bytes,
112 v8_ffi, is_async)) {
113 thrower->RangeError(RANGE_ERROR_MSG);
114 return false;
115 }
116 return true;
117 }
118
76 i::wasm::ModuleWireBytes GetFirstArgumentAsBytes( 119 i::wasm::ModuleWireBytes GetFirstArgumentAsBytes(
77 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { 120 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
78 if (args.Length() < 1) { 121 if (args.Length() < 1) {
79 thrower->TypeError("Argument 0 must be a buffer source"); 122 thrower->TypeError("Argument 0 must be a buffer source");
80 return i::wasm::ModuleWireBytes(nullptr, nullptr); 123 return i::wasm::ModuleWireBytes(nullptr, nullptr);
81 } 124 }
82 125
83 const byte* start = nullptr; 126 const byte* start = nullptr;
84 const byte* end = nullptr; 127 const byte* end = nullptr;
85 v8::Local<v8::Value> source = args[0]; 128 v8::Local<v8::Value> source = args[0];
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 HandleScope scope(isolate); 175 HandleScope scope(isolate);
133 ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); 176 ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
134 177
135 Local<Context> context = isolate->GetCurrentContext(); 178 Local<Context> context = isolate->GetCurrentContext();
136 v8::Local<v8::Promise::Resolver> resolver; 179 v8::Local<v8::Promise::Resolver> resolver;
137 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; 180 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
138 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 181 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
139 return_value.Set(resolver->GetPromise()); 182 return_value.Set(resolver->GetPromise());
140 183
141 auto bytes = GetFirstArgumentAsBytes(args, &thrower); 184 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
142 if (thrower.error()) { 185 if (!IsCompilationAllowed(i_isolate, &thrower, args[0], true)) {
143 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 186 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
144 return; 187 return;
145 } 188 }
189 DCHECK(!thrower.error());
146 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); 190 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
147 i::wasm::AsyncCompile(i_isolate, promise, bytes); 191 i::wasm::AsyncCompile(i_isolate, promise, bytes);
148 } 192 }
149 193
150 // WebAssembly.validate(bytes) -> bool 194 // WebAssembly.validate(bytes) -> bool
151 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { 195 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
152 v8::Isolate* isolate = args.GetIsolate(); 196 v8::Isolate* isolate = args.GetIsolate();
153 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 197 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
154 HandleScope scope(isolate); 198 HandleScope scope(isolate);
155 ErrorThrower thrower(i_isolate, "WebAssembly.validate()"); 199 ErrorThrower thrower(i_isolate, "WebAssembly.validate()");
(...skipping 12 matching lines...) Expand all
168 } 212 }
169 213
170 // new WebAssembly.Module(bytes) -> WebAssembly.Module 214 // new WebAssembly.Module(bytes) -> WebAssembly.Module
171 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { 215 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
172 v8::Isolate* isolate = args.GetIsolate(); 216 v8::Isolate* isolate = args.GetIsolate();
173 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 217 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
174 HandleScope scope(isolate); 218 HandleScope scope(isolate);
175 ErrorThrower thrower(i_isolate, "WebAssembly.Module()"); 219 ErrorThrower thrower(i_isolate, "WebAssembly.Module()");
176 220
177 auto bytes = GetFirstArgumentAsBytes(args, &thrower); 221 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
178 if (thrower.error()) return; 222 if (!IsCompilationAllowed(i_isolate, &thrower, args[0], false)) return;
179 223
224 DCHECK(!thrower.error());
180 i::MaybeHandle<i::Object> module_obj = 225 i::MaybeHandle<i::Object> module_obj =
181 i::wasm::SyncCompile(i_isolate, &thrower, bytes); 226 i::wasm::SyncCompile(i_isolate, &thrower, bytes);
182 if (module_obj.is_null()) return; 227 if (module_obj.is_null()) return;
183 228
184 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 229 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
185 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); 230 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
186 } 231 }
187 232
188 // WebAssembly.Module.imports(module) -> Array<Import> 233 // WebAssembly.Module.imports(module) -> Array<Import>
189 void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) { 234 void WebAssemblyModuleImports(const v8::FunctionCallbackInfo<v8::Value>& args) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
244 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { 289 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
245 HandleScope scope(args.GetIsolate()); 290 HandleScope scope(args.GetIsolate());
246 v8::Isolate* isolate = args.GetIsolate(); 291 v8::Isolate* isolate = args.GetIsolate();
247 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 292 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
248 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); 293 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
249 294
250 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 295 auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
251 if (thrower.error()) return; 296 if (thrower.error()) return;
252 297
253 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); 298 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
254 if (thrower.error()) return; 299 if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports,
300 false)) {
301 return;
302 }
303 DCHECK(!thrower.error());
255 304
256 i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate( 305 i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate(
257 i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports, 306 i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports,
258 i::MaybeHandle<i::JSArrayBuffer>()); 307 i::MaybeHandle<i::JSArrayBuffer>());
259 if (instance_object.is_null()) return; 308 if (instance_object.is_null()) return;
260 args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked())); 309 args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked()));
261 } 310 }
262 311
263 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance 312 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
264 // WebAssembly.instantiate(bytes, imports) -> 313 // WebAssembly.instantiate(bytes, imports) ->
(...skipping 27 matching lines...) Expand all
292 "Argument 0 must be a buffer source or a WebAssembly.Module object"); 341 "Argument 0 must be a buffer source or a WebAssembly.Module object");
293 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 342 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
294 return; 343 return;
295 } 344 }
296 345
297 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower); 346 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
298 if (thrower.error()) { 347 if (thrower.error()) {
299 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 348 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
300 return; 349 return;
301 } 350 }
351 if (!IsInstantiationAllowed(i_isolate, &thrower, args[0], maybe_imports,
352 true)) {
353 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
354 return;
355 }
302 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise()); 356 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
303
304 if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) { 357 if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) {
305 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance 358 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
306 auto module_object = GetFirstArgumentAsModule(args, &thrower); 359 auto module_object = GetFirstArgumentAsModule(args, &thrower);
307 i::wasm::AsyncInstantiate(i_isolate, promise, 360 i::wasm::AsyncInstantiate(i_isolate, promise,
308 module_object.ToHandleChecked(), maybe_imports); 361 module_object.ToHandleChecked(), maybe_imports);
309 } else { 362 } else {
310 // WebAssembly.instantiate(bytes, imports) -> {module, instance} 363 // WebAssembly.instantiate(bytes, imports) -> {module, instance}
311 auto bytes = GetFirstArgumentAsBytes(args, &thrower); 364 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
312 if (thrower.error()) { 365 if (thrower.error()) {
313 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 366 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); 912 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
860 return HasBrand(value, symbol); 913 return HasBrand(value, symbol);
861 } 914 }
862 915
863 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { 916 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
864 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); 917 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
865 return HasBrand(value, symbol); 918 return HasBrand(value, symbol);
866 } 919 }
867 } // namespace internal 920 } // namespace internal
868 } // namespace v8 921 } // namespace v8
OLDNEW
« 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