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

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

Issue 2699843003: [wasm] Embedder can control what buffers wasm compilation works on. (Closed)
Patch Set: RangeError 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
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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 thrower->TypeError("Argument 0 must be a buffer source"); 72 thrower->TypeError("Argument 0 must be a buffer source");
73 } 73 }
74 if (start == nullptr || end == start) { 74 if (start == nullptr || end == start) {
75 thrower->CompileError("BufferSource argument is empty"); 75 thrower->CompileError("BufferSource argument is empty");
76 } 76 }
77 return {start, end}; 77 return {start, end};
78 } 78 }
79 79
80 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( 80 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject(
81 v8::Isolate* isolate, const v8::Local<v8::Value> source, 81 v8::Isolate* isolate, const v8::Local<v8::Value> source,
82 ErrorThrower* thrower) { 82 ErrorThrower* thrower, bool async) {
83 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 83 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
84 i::MaybeHandle<i::JSObject> nothing; 84 i::MaybeHandle<i::WasmModuleObject> nothing;
85
86 AllowWasmCompileCallback callback =
87 reinterpret_cast<i::Isolate*>(isolate)->allow_wasm_compile_callback();
88 if (callback != nullptr && !callback(source, async)) {
89 thrower->RangeError(
90 "Wasm compilation disallowed in this context for provided argument");
bradnelson 2017/02/18 00:28:42 How about: Wasm compilation exceeds internal limit
Mircea Trofin 2017/02/18 00:41:47 Done.
91 return nothing;
92 }
85 93
86 RawBuffer buffer = GetRawBufferSource(source, thrower); 94 RawBuffer buffer = GetRawBufferSource(source, thrower);
87 if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>(); 95 if (buffer.start == nullptr) return i::MaybeHandle<i::WasmModuleObject>();
88 96
89 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); 97 DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
90 return i::wasm::CreateModuleObjectFromBytes( 98 return i::wasm::CreateModuleObjectFromBytes(
91 i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin, 99 i_isolate, buffer.start, buffer.end, thrower, i::wasm::kWasmOrigin,
92 i::Handle<i::Script>::null(), i::Vector<const byte>::empty()); 100 i::Handle<i::Script>::null(), i::Vector<const byte>::empty());
93 } 101 }
94 102
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; 140 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
133 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 141 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
134 return_value.Set(resolver->GetPromise()); 142 return_value.Set(resolver->GetPromise());
135 143
136 if (args.Length() < 1) { 144 if (args.Length() < 1) {
137 thrower.TypeError("Argument 0 must be a buffer source"); 145 thrower.TypeError("Argument 0 must be a buffer source");
138 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 146 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
139 return; 147 return;
140 } 148 }
141 i::MaybeHandle<i::JSObject> module_obj = 149 i::MaybeHandle<i::JSObject> module_obj =
142 CreateModuleObject(isolate, args[0], &thrower); 150 CreateModuleObject(isolate, args[0], &thrower, true);
143 151
144 if (thrower.error()) { 152 if (thrower.error()) {
145 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 153 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
146 } else { 154 } else {
147 resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked())); 155 resolver->Resolve(context, Utils::ToLocal(module_obj.ToHandleChecked()));
148 } 156 }
149 } 157 }
150 158
151 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) { 159 void WebAssemblyValidate(const v8::FunctionCallbackInfo<v8::Value>& args) {
152 v8::Isolate* isolate = args.GetIsolate(); 160 v8::Isolate* isolate = args.GetIsolate();
(...skipping 20 matching lines...) Expand all
173 HandleScope scope(isolate); 181 HandleScope scope(isolate);
174 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 182 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
175 "WebAssembly.Module()"); 183 "WebAssembly.Module()");
176 184
177 if (args.Length() < 1) { 185 if (args.Length() < 1) {
178 thrower.TypeError("Argument 0 must be a buffer source"); 186 thrower.TypeError("Argument 0 must be a buffer source");
179 return; 187 return;
180 } 188 }
181 189
182 i::MaybeHandle<i::JSObject> module_obj = 190 i::MaybeHandle<i::JSObject> module_obj =
183 CreateModuleObject(isolate, args[0], &thrower); 191 CreateModuleObject(isolate, args[0], &thrower, false);
184 if (module_obj.is_null()) return; 192 if (module_obj.is_null()) return;
185 193
186 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 194 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
187 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); 195 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
188 } 196 }
189 197
190 MaybeLocal<Value> InstantiateModuleImpl( 198 MaybeLocal<Value> InstantiateModuleImpl(
191 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj, 199 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj,
192 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { 200 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower,
201 bool as_promise) {
193 // It so happens that in both the WebAssembly.instantiate, as well as 202 // It so happens that in both the WebAssembly.instantiate, as well as
194 // WebAssembly.Instance ctor, the positions of the ffi object and memory 203 // WebAssembly.Instance ctor, the positions of the ffi object and memory
195 // are the same. If that changes later, we refactor the consts into 204 // are the same. If that changes later, we refactor the consts into
196 // parameters. 205 // parameters.
197 static const int kFfiOffset = 1; 206 static const int kFfiOffset = 1;
198 207
199 MaybeLocal<Value> nothing; 208 MaybeLocal<Value> nothing;
200 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); 209 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null();
201 // This is a first - level validation of the argument. If present, we only 210 // This is a first - level validation of the argument. If present, we only
202 // check its type. {Instantiate} will further check that if the module 211 // check its type. {Instantiate} will further check that if the module
203 // has imports, the argument must be present, as well as piecemeal 212 // has imports, the argument must be present, as well as piecemeal
204 // import satisfaction. 213 // import satisfaction.
205 if (args.Length() > kFfiOffset && !args[kFfiOffset]->IsUndefined()) { 214 if (args.Length() > kFfiOffset && !args[kFfiOffset]->IsUndefined()) {
206 if (!args[kFfiOffset]->IsObject()) { 215 if (!args[kFfiOffset]->IsObject()) {
207 thrower->TypeError("Argument %d must be an object", kFfiOffset); 216 thrower->TypeError("Argument %d must be an object", kFfiOffset);
208 return nothing; 217 return nothing;
209 } 218 }
210 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]); 219 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]);
211 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); 220 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
212 } 221 }
222 AllowWasmInstantiateCallback allow_instantiate =
223 i_isolate->allow_wasm_instantiate_callback();
224 if (allow_instantiate != nullptr &&
225 !allow_instantiate(Local<WasmCompiledModule>::Cast(Utils::ToLocal(
226 i::Handle<i::JSObject>::cast(i_module_obj))),
227 Utils::ToLocal(ffi), as_promise)) {
228 thrower->RangeError(
229 "WebAssembly Instantiation is not permitted in this context");
bradnelson 2017/02/18 00:28:42 How about: Wasm instantiation exceeds internal lim
Mircea Trofin 2017/02/18 00:41:47 Done.
230 return nothing;
231 }
213 232
214 i::MaybeHandle<i::JSObject> instance = 233 i::MaybeHandle<i::JSObject> instance =
215 i::wasm::WasmModule::Instantiate(i_isolate, thrower, i_module_obj, ffi); 234 i::wasm::WasmModule::Instantiate(i_isolate, thrower, i_module_obj, ffi);
216 if (instance.is_null()) { 235 if (instance.is_null()) {
217 if (!thrower->error()) 236 if (!thrower->error())
218 thrower->RuntimeError("Could not instantiate module"); 237 thrower->RuntimeError("Could not instantiate module");
219 return nothing; 238 return nothing;
220 } 239 }
221 DCHECK(!i_isolate->has_pending_exception()); 240 DCHECK(!i_isolate->has_pending_exception());
222 return Utils::ToLocal(instance.ToHandleChecked()); 241 return Utils::ToLocal(instance.ToHandleChecked());
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { 328 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
310 HandleScope scope(args.GetIsolate()); 329 HandleScope scope(args.GetIsolate());
311 v8::Isolate* isolate = args.GetIsolate(); 330 v8::Isolate* isolate = args.GetIsolate();
312 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 331 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
313 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); 332 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
314 333
315 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 334 auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
316 335
317 if (!maybe_module.is_null()) { 336 if (!maybe_module.is_null()) {
318 MaybeLocal<Value> instance = InstantiateModuleImpl( 337 MaybeLocal<Value> instance = InstantiateModuleImpl(
319 i_isolate, maybe_module.ToHandleChecked(), args, &thrower); 338 i_isolate, maybe_module.ToHandleChecked(), args, &thrower, false);
320 339
321 if (instance.IsEmpty()) { 340 if (instance.IsEmpty()) {
322 DCHECK(thrower.error()); 341 DCHECK(thrower.error());
323 return; 342 return;
324 } 343 }
325 args.GetReturnValue().Set(instance.ToLocalChecked()); 344 args.GetReturnValue().Set(instance.ToLocalChecked());
326 } 345 }
327 } 346 }
328 347
329 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { 348 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
(...skipping 24 matching lines...) Expand all
354 thrower.TypeError( 373 thrower.TypeError(
355 "Argument 0 must be a buffer source or a WebAssembly.Module object"); 374 "Argument 0 must be a buffer source or a WebAssembly.Module object");
356 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 375 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
357 return; 376 return;
358 } 377 }
359 bool want_pair = 378 bool want_pair =
360 !HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym())); 379 !HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()));
361 i::Handle<i::WasmModuleObject> module_obj; 380 i::Handle<i::WasmModuleObject> module_obj;
362 if (want_pair) { 381 if (want_pair) {
363 i::MaybeHandle<i::WasmModuleObject> maybe_module_obj = 382 i::MaybeHandle<i::WasmModuleObject> maybe_module_obj =
364 CreateModuleObject(isolate, args[0], &thrower); 383 CreateModuleObject(isolate, args[0], &thrower, true);
365 if (!maybe_module_obj.ToHandle(&module_obj)) { 384 if (!maybe_module_obj.ToHandle(&module_obj)) {
366 DCHECK(thrower.error()); 385 DCHECK(thrower.error());
367 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 386 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
368 return; 387 return;
369 } 388 }
370 } else { 389 } else {
371 module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg); 390 module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg);
372 } 391 }
373 DCHECK(!module_obj.is_null()); 392 DCHECK(!module_obj.is_null());
374 MaybeLocal<Value> instance = 393 MaybeLocal<Value> instance =
375 InstantiateModuleImpl(i_isolate, module_obj, args, &thrower); 394 InstantiateModuleImpl(i_isolate, module_obj, args, &thrower, true);
376 if (instance.IsEmpty()) { 395 if (instance.IsEmpty()) {
377 DCHECK(thrower.error()); 396 DCHECK(thrower.error());
378 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 397 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
379 } else { 398 } else {
380 DCHECK(!thrower.error()); 399 DCHECK(!thrower.error());
381 Local<Value> retval; 400 Local<Value> retval;
382 if (want_pair) { 401 if (want_pair) {
383 i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>( 402 i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>(
384 i_isolate->native_context()->object_function(), i_isolate); 403 i_isolate->native_context()->object_function(), i_isolate);
385 404
(...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); 954 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
936 return HasBrand(value, symbol); 955 return HasBrand(value, symbol);
937 } 956 }
938 957
939 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { 958 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
940 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); 959 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
941 return HasBrand(value, symbol); 960 return HasBrand(value, symbol);
942 } 961 }
943 } // namespace internal 962 } // namespace internal
944 } // namespace v8 963 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698