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

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

Issue 2810203002: Revert of [wasm] instantiate expressed in terms of compile (Closed)
Patch Set: Created 3 years, 8 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') | src/wasm/wasm-module.h » ('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 14 matching lines...) Expand all
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 34
35 #define ASSIGN(type, var, expr) \
36 Local<type> var; \
37 do { \
38 if (!expr.ToLocal(&var)) return; \
39 } while (false)
40
41 #define DO_BOOL(expr) \
42 do { \
43 bool ok; \
44 if (!expr.To(&ok) || !ok) return; \
45 } while (false)
46
47 // TODO(wasm): move brand check to the respective types, and don't throw 35 // TODO(wasm): move brand check to the respective types, and don't throw
48 // in it, rather, use a provided ErrorThrower, or let caller handle it. 36 // in it, rather, use a provided ErrorThrower, or let caller handle it.
49 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) { 37 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> sym) {
50 if (!value->IsJSObject()) return false; 38 if (!value->IsJSObject()) return false;
51 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); 39 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
52 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym); 40 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
53 return has_brand.FromMaybe(false); 41 return has_brand.FromMaybe(false);
54 } 42 }
55 43
56 static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym, 44 static bool BrandCheck(i::Handle<i::Object> value, i::Handle<i::Symbol> sym,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 110 }
123 if (length > i::wasm::kV8MaxWasmModuleSize) { 111 if (length > i::wasm::kV8MaxWasmModuleSize) {
124 thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)", 112 thrower->RangeError("buffer source exceeds maximum size of %zu (is %zu)",
125 i::wasm::kV8MaxWasmModuleSize, length); 113 i::wasm::kV8MaxWasmModuleSize, length);
126 } 114 }
127 if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr); 115 if (thrower->error()) return i::wasm::ModuleWireBytes(nullptr, nullptr);
128 // TODO(titzer): use the handle as well? 116 // TODO(titzer): use the handle as well?
129 return i::wasm::ModuleWireBytes(start, start + length); 117 return i::wasm::ModuleWireBytes(start, start + length);
130 } 118 }
131 119
132 i::MaybeHandle<i::JSReceiver> GetValueAsImports(const Local<Value>& arg, 120 i::MaybeHandle<i::JSReceiver> GetSecondArgumentAsImports(
133 ErrorThrower* thrower) { 121 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) {
134 if (arg->IsUndefined()) return {}; 122 if (args.Length() < 2) return {};
123 if (args[1]->IsUndefined()) return {};
135 124
136 if (!arg->IsObject()) { 125 if (!args[1]->IsObject()) {
137 thrower->TypeError("Argument 1 must be an object"); 126 thrower->TypeError("Argument 1 must be an object");
138 return {}; 127 return {};
139 } 128 }
140 Local<Object> obj = Local<Object>::Cast(arg); 129 Local<Object> obj = Local<Object>::Cast(args[1]);
141 return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); 130 return i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj));
142 } 131 }
143 132
144 // WebAssembly.compile(bytes) -> Promise 133 // WebAssembly.compile(bytes) -> Promise
145 void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) { 134 void WebAssemblyCompile(const v8::FunctionCallbackInfo<v8::Value>& args) {
146 v8::Isolate* isolate = args.GetIsolate(); 135 v8::Isolate* isolate = args.GetIsolate();
147 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 136 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
148 if (i_isolate->wasm_compile_callback()(args)) return; 137 if (i_isolate->wasm_compile_callback()(args)) return;
149 138
150 HandleScope scope(isolate); 139 HandleScope scope(isolate);
151 ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); 140 ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
152 141
153 Local<Context> context = isolate->GetCurrentContext(); 142 Local<Context> context = isolate->GetCurrentContext();
154 ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context)); 143 v8::Local<v8::Promise::Resolver> resolver;
144 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
155 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 145 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
156 return_value.Set(resolver->GetPromise()); 146 return_value.Set(resolver->GetPromise());
157 147
158 auto bytes = GetFirstArgumentAsBytes(args, &thrower); 148 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
159 if (thrower.error()) { 149 if (thrower.error()) {
160 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 150 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
161 CHECK_IMPLIES(!maybe.FromMaybe(false), 151 CHECK_IMPLIES(!maybe.FromMaybe(false),
162 i_isolate->has_scheduled_exception()); 152 i_isolate->has_scheduled_exception());
163 return; 153 return;
164 } 154 }
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 return; 246 return;
257 } 247 }
258 248
259 auto custom_sections = 249 auto custom_sections =
260 i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(), 250 i::wasm::GetCustomSections(i_isolate, maybe_module.ToHandleChecked(),
261 i::Handle<i::String>::cast(name), &thrower); 251 i::Handle<i::String>::cast(name), &thrower);
262 if (thrower.error()) return; 252 if (thrower.error()) return;
263 args.GetReturnValue().Set(Utils::ToLocal(custom_sections)); 253 args.GetReturnValue().Set(Utils::ToLocal(custom_sections));
264 } 254 }
265 255
266 // Entered as internal implementation detail of sync and async instantiate.
267 // args[0] *must* be a WebAssembly.Module.
268 void WebAssemblyInstantiateImpl(
269 const v8::FunctionCallbackInfo<v8::Value>& args) {
270 DCHECK_GE(args.Length(), 1);
271 Local<Value> module = args[0];
272 Local<Value> ffi = args.Data();
273
274 HandleScope scope(args.GetIsolate());
275 v8::Isolate* isolate = args.GetIsolate();
276 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
277 ErrorThrower thrower(i_isolate, "WebAssembly Instantiation");
278 i::MaybeHandle<i::JSReceiver> maybe_imports =
279 GetValueAsImports(ffi, &thrower);
280 if (thrower.error()) return;
281
282 i::Handle<i::WasmModuleObject> module_obj =
283 i::Handle<i::WasmModuleObject>::cast(
284 Utils::OpenHandle(Object::Cast(*module)));
285 i::MaybeHandle<i::Object> instance_object =
286 i::wasm::SyncInstantiate(i_isolate, &thrower, module_obj, maybe_imports,
287 i::MaybeHandle<i::JSArrayBuffer>());
288
289 if (instance_object.is_null()) {
290 // TODO(wasm): this *should* mean there's an error to throw, but
291 // we exit sometimes the instantiation pipeline without throwing.
292 // v8:6232.
293 return;
294 }
295 args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked()));
296 }
297
298 void WebAssemblyInstantiateToPair(
299 const v8::FunctionCallbackInfo<v8::Value>& args) {
300 DCHECK_GE(args.Length(), 1);
301 Local<Value> module = args[0];
302 Isolate* isolate = args.GetIsolate();
303 Local<Context> context = isolate->GetCurrentContext();
304
305 const uint8_t* instance_str = reinterpret_cast<const uint8_t*>("instance");
306 const uint8_t* module_str = reinterpret_cast<const uint8_t*>("module");
307 ASSIGN(Function, vanilla_instantiate,
308 Function::New(context, WebAssemblyInstantiateImpl, args.Data()));
309
310 ASSIGN(Value, instance,
311 vanilla_instantiate->Call(context, args.Holder(), 1, &module));
312 Local<Object> ret = Object::New(isolate);
313 ASSIGN(String, instance_name,
314 String::NewFromOneByte(isolate, instance_str,
315 NewStringType::kInternalized));
316 ASSIGN(String, module_name,
317 String::NewFromOneByte(isolate, module_str,
318 NewStringType::kInternalized));
319
320 DO_BOOL(ret->CreateDataProperty(context, instance_name, instance));
321 DO_BOOL(ret->CreateDataProperty(context, module_name, module));
322 args.GetReturnValue().Set(ret);
323 }
324
325 // new WebAssembly.Instance(module, imports) -> WebAssembly.Instance 256 // new WebAssembly.Instance(module, imports) -> WebAssembly.Instance
326 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { 257 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) {
327 HandleScope scope(args.GetIsolate()); 258 HandleScope scope(args.GetIsolate());
328 Isolate* isolate = args.GetIsolate(); 259 v8::Isolate* isolate = args.GetIsolate();
329 Local<Context> context = isolate->GetCurrentContext();
330 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 260 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
331 if (i_isolate->wasm_instance_callback()(args)) return; 261 if (i_isolate->wasm_instance_callback()(args)) return;
332 262
333 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); 263 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()");
334 264
335 auto maybe_module = GetFirstArgumentAsModule(args, &thrower); 265 auto maybe_module = GetFirstArgumentAsModule(args, &thrower);
336 if (thrower.error()) return; 266 if (thrower.error()) return;
337 267
338 // If args.Length < 2, this will be undefined - see FunctionCallbackInfo. 268 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
339 // We'll check for that in WebAssemblyInstantiateImpl. 269 if (thrower.error()) return;
340 Local<Value> data = args[1];
341 270
342 ASSIGN(Function, impl, 271 i::MaybeHandle<i::Object> instance_object = i::wasm::SyncInstantiate(
343 Function::New(context, WebAssemblyInstantiateImpl, data)); 272 i_isolate, &thrower, maybe_module.ToHandleChecked(), maybe_imports,
344 Local<Value> first_param = args[0]; 273 i::MaybeHandle<i::JSArrayBuffer>());
345 ASSIGN(Value, ret, impl->Call(context, args.Holder(), 1, &first_param)); 274 if (instance_object.is_null()) return;
346 args.GetReturnValue().Set(ret); 275 args.GetReturnValue().Set(Utils::ToLocal(instance_object.ToHandleChecked()));
347 } 276 }
348 277
349 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance 278 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
350 // WebAssembly.instantiate(bytes, imports) -> 279 // WebAssembly.instantiate(bytes, imports) ->
351 // {module: WebAssembly.Module, instance: WebAssembly.Instance} 280 // {module: WebAssembly.Module, instance: WebAssembly.Instance}
352 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { 281 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
353 v8::Isolate* isolate = args.GetIsolate(); 282 v8::Isolate* isolate = args.GetIsolate();
354 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 283 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
355 if (i_isolate->wasm_instantiate_callback()(args)) return; 284 if (i_isolate->wasm_instantiate_callback()(args)) return;
356 285
357 ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()"); 286 ErrorThrower thrower(i_isolate, "WebAssembly.instantiate()");
358 287
359 HandleScope scope(isolate); 288 HandleScope scope(isolate);
360 289
361 Local<Context> context = isolate->GetCurrentContext(); 290 Local<Context> context = isolate->GetCurrentContext();
362 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); 291 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
363 292
364 ASSIGN(Promise::Resolver, resolver, Promise::Resolver::New(context)); 293 v8::Local<v8::Promise::Resolver> resolver;
365 Local<Promise> module_promise = resolver->GetPromise(); 294 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
366 args.GetReturnValue().Set(module_promise); 295 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
296 return_value.Set(resolver->GetPromise());
367 297
368 if (args.Length() < 1) { 298 if (args.Length() < 1) {
369 thrower.TypeError( 299 thrower.TypeError(
370 "Argument 0 must be provided and must be either a buffer source or a " 300 "Argument 0 must be provided and must be either a buffer source or a "
371 "WebAssembly.Module object"); 301 "WebAssembly.Module object");
372 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 302 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
373 CHECK_IMPLIES(!maybe.FromMaybe(false), 303 CHECK_IMPLIES(!maybe.FromMaybe(false),
374 i_isolate->has_scheduled_exception()); 304 i_isolate->has_scheduled_exception());
375 return; 305 return;
376 } 306 }
377 307
378 Local<Value> first_arg_value = args[0]; 308 i::Handle<i::Object> first_arg = Utils::OpenHandle(*args[0]);
379 i::Handle<i::Object> first_arg = Utils::OpenHandle(*first_arg_value);
380 if (!first_arg->IsJSObject()) { 309 if (!first_arg->IsJSObject()) {
381 thrower.TypeError( 310 thrower.TypeError(
382 "Argument 0 must be a buffer source or a WebAssembly.Module object"); 311 "Argument 0 must be a buffer source or a WebAssembly.Module object");
383 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 312 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
384 CHECK_IMPLIES(!maybe.FromMaybe(false), 313 CHECK_IMPLIES(!maybe.FromMaybe(false),
385 i_isolate->has_scheduled_exception()); 314 i_isolate->has_scheduled_exception());
386 return; 315 return;
387 } 316 }
388 317
389 FunctionCallback instantiator = nullptr; 318 auto maybe_imports = GetSecondArgumentAsImports(args, &thrower);
319 if (thrower.error()) {
320 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
321 CHECK_IMPLIES(!maybe.FromMaybe(false),
322 i_isolate->has_scheduled_exception());
323 return;
324 }
325 i::Handle<i::JSPromise> promise = Utils::OpenHandle(*resolver->GetPromise());
390 if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) { 326 if (HasBrand(first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()))) {
391 module_promise = resolver->GetPromise(); 327 // WebAssembly.instantiate(module, imports) -> WebAssembly.Instance
392 DO_BOOL(resolver->Resolve(context, first_arg_value)); 328 auto module_object = GetFirstArgumentAsModule(args, &thrower);
393 instantiator = WebAssemblyInstantiateImpl; 329 i::wasm::AsyncInstantiate(i_isolate, promise,
330 module_object.ToHandleChecked(), maybe_imports);
394 } else { 331 } else {
395 ASSIGN(Function, async_compile, Function::New(context, WebAssemblyCompile)); 332 // WebAssembly.instantiate(bytes, imports) -> {module, instance}
396 ASSIGN(Value, async_compile_retval, 333 auto bytes = GetFirstArgumentAsBytes(args, &thrower);
397 async_compile->Call(context, args.Holder(), 1, &first_arg_value)); 334 if (thrower.error()) {
398 module_promise = Local<Promise>::Cast(async_compile_retval); 335 auto maybe = resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
399 instantiator = WebAssemblyInstantiateToPair; 336 CHECK_IMPLIES(!maybe.FromMaybe(false),
337 i_isolate->has_scheduled_exception());
338 return;
339 }
340 i::wasm::AsyncCompileAndInstantiate(i_isolate, promise, bytes,
341 maybe_imports);
400 } 342 }
401 DCHECK(!module_promise.IsEmpty());
402 DCHECK_NOT_NULL(instantiator);
403 // If args.Length < 2, this will be undefined - see FunctionCallbackInfo.
404 // We'll check for that in WebAssemblyInstantiateImpl.
405 Local<Value> data = args[1];
406 ASSIGN(Function, instantiate_impl,
407 Function::New(context, instantiator, data));
408 ASSIGN(Promise, result, module_promise->Then(context, instantiate_impl));
409 args.GetReturnValue().Set(result);
410 } 343 }
411 344
412 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, 345 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
413 Local<Context> context, Local<v8::Object> object, 346 Local<Context> context, Local<v8::Object> object,
414 Local<String> property, int* result, 347 Local<String> property, int* result,
415 int64_t lower_bound, uint64_t upper_bound) { 348 int64_t lower_bound, uint64_t upper_bound) {
416 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); 349 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property);
417 v8::Local<v8::Value> value; 350 v8::Local<v8::Value> value;
418 if (maybe.ToLocal(&value)) { 351 if (maybe.ToLocal(&value)) {
419 int64_t number; 352 int64_t number;
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
951 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); 884 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
952 return HasBrand(value, symbol); 885 return HasBrand(value, symbol);
953 } 886 }
954 887
955 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { 888 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
956 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); 889 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
957 return HasBrand(value, symbol); 890 return HasBrand(value, symbol);
958 } 891 }
959 } // namespace internal 892 } // namespace internal
960 } // namespace v8 893 } // namespace v8
OLDNEW
« no previous file with comments | « src/runtime/runtime-test.cc ('k') | src/wasm/wasm-module.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698