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

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

Issue 2644993002: [wasm] WebAssembly.instantiate has a pair-returning overload (Closed)
Patch Set: feedback Created 3 years, 11 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 | « no previous file | test/mjsunit/wasm/js-api.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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 Local<TypedArray> array = Local<TypedArray>::Cast(source); 61 Local<TypedArray> array = Local<TypedArray>::Cast(source);
62 Local<ArrayBuffer> buffer = array->Buffer(); 62 Local<ArrayBuffer> buffer = array->Buffer();
63 63
64 ArrayBuffer::Contents contents = buffer->GetContents(); 64 ArrayBuffer::Contents contents = buffer->GetContents();
65 65
66 start = 66 start =
67 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset(); 67 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset();
68 end = start + array->ByteLength(); 68 end = start + array->ByteLength();
69 69
70 } else { 70 } else {
71 thrower->TypeError("Argument 0 must be an ArrayBuffer or Uint8Array"); 71 thrower->TypeError("Argument 0 must be a buffer source");
72 } 72 }
73 if (start == nullptr || end == start) { 73 if (start == nullptr || end == start) {
74 thrower->CompileError("BufferSource argument is empty"); 74 thrower->CompileError("BufferSource argument is empty");
75 } 75 }
76 return {start, end}; 76 return {start, end};
77 } 77 }
78 78
79 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( 79 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject(
80 v8::Isolate* isolate, const v8::Local<v8::Value> source, 80 v8::Isolate* isolate, const v8::Local<v8::Value> source,
81 ErrorThrower* thrower) { 81 ErrorThrower* thrower) {
(...skipping 17 matching lines...) Expand all
99 99
100 RawBuffer buffer = GetRawBufferSource(source, thrower); 100 RawBuffer buffer = GetRawBufferSource(source, thrower);
101 if (buffer.start == nullptr) return false; 101 if (buffer.start == nullptr) return false;
102 102
103 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); 103 DCHECK(source->IsArrayBuffer() || source->IsTypedArray());
104 return i::wasm::ValidateModuleBytes(i_isolate, buffer.start, buffer.end, 104 return i::wasm::ValidateModuleBytes(i_isolate, buffer.start, buffer.end,
105 thrower, 105 thrower,
106 i::wasm::ModuleOrigin::kWasmOrigin); 106 i::wasm::ModuleOrigin::kWasmOrigin);
107 } 107 }
108 108
109 // TODO(wasm): move brand check to the respective types, and don't throw
110 // in it, rather, use a provided ErrorThrower, or let caller handle it.
111 static bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value,
112 i::Handle<i::Symbol> sym) {
113 if (!value->IsJSObject()) return false;
114 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
115 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
116 if (has_brand.IsNothing()) return false;
117 return has_brand.ToChecked();
118 }
119
109 static bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value, 120 static bool BrandCheck(Isolate* isolate, i::Handle<i::Object> value,
110 i::Handle<i::Symbol> sym, const char* msg) { 121 i::Handle<i::Symbol> sym, const char* msg) {
111 if (value->IsJSObject()) { 122 if (value->IsJSObject()) {
112 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); 123 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value);
113 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym); 124 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, sym);
114 if (has_brand.IsNothing()) return false; 125 if (has_brand.IsNothing()) return false;
115 if (has_brand.ToChecked()) return true; 126 if (has_brand.ToChecked()) return true;
116 } 127 }
117 v8::Local<v8::Value> e = v8::Exception::TypeError(v8_str(isolate, msg)); 128 v8::Local<v8::Value> e = v8::Exception::TypeError(v8_str(isolate, msg));
118 isolate->ThrowException(e); 129 isolate->ThrowException(e);
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 v8::Isolate* isolate = args.GetIsolate(); 181 v8::Isolate* isolate = args.GetIsolate();
171 HandleScope scope(isolate); 182 HandleScope scope(isolate);
172 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 183 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
173 "WebAssembly.Module()"); 184 "WebAssembly.Module()");
174 185
175 if (args.Length() < 1) { 186 if (args.Length() < 1) {
176 thrower.TypeError("Argument 0 must be a buffer source"); 187 thrower.TypeError("Argument 0 must be a buffer source");
177 return; 188 return;
178 } 189 }
179 190
180 if (args.Length() > 2) {
181 thrower.LinkError(
182 "WebAssembly.instantiate accepts no more than 2 parameters");
183 return;
184 }
185 i::MaybeHandle<i::JSObject> module_obj = 191 i::MaybeHandle<i::JSObject> module_obj =
186 CreateModuleObject(isolate, args[0], &thrower); 192 CreateModuleObject(isolate, args[0], &thrower);
187 if (module_obj.is_null()) return; 193 if (module_obj.is_null()) return;
188 194
189 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 195 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
190 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); 196 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
191 } 197 }
192 198
193 MaybeLocal<Value> InstantiateModuleImpl( 199 MaybeLocal<Value> InstantiateModuleImpl(
194 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj, 200 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj,
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 } 327 }
322 328
323 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { 329 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
324 v8::Isolate* isolate = args.GetIsolate(); 330 v8::Isolate* isolate = args.GetIsolate();
325 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 331 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
326 332
327 HandleScope scope(isolate); 333 HandleScope scope(isolate);
328 ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); 334 ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
329 335
330 Local<Context> context = isolate->GetCurrentContext(); 336 Local<Context> context = isolate->GetCurrentContext();
337 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
338
331 v8::Local<v8::Promise::Resolver> resolver; 339 v8::Local<v8::Promise::Resolver> resolver;
332 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; 340 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
333 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 341 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
334 return_value.Set(resolver->GetPromise()); 342 return_value.Set(resolver->GetPromise());
335 343
336 if (args.Length() < 1) { 344 if (args.Length() < 1) {
337 thrower.TypeError("Argument 0 must be a buffer source"); 345 thrower.TypeError(
346 "Argument 0 must be provided and must be either a buffer source or a "
347 "WebAssembly.Module object");
338 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 348 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
339 return; 349 return;
340 } 350 }
341 351
342 i::MaybeHandle<i::WasmModuleObject> module_obj = 352 i::Handle<i::Object> first_arg = Utils::OpenHandle(*args[0]);
343 CreateModuleObject(isolate, args[0], &thrower); 353 if (!first_arg->IsJSObject()) {
344 if (module_obj.is_null()) { 354 thrower.TypeError(
345 DCHECK(thrower.error()); 355 "Argument 0 must be a buffer source or a WebAssembly.Module object");
346 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 356 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
347 return; 357 return;
348 } 358 }
349 359 bool want_pair = !BrandCheck(
350 MaybeLocal<Value> instance = InstantiateModuleImpl( 360 isolate, first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()));
351 i_isolate, module_obj.ToHandleChecked(), args, &thrower); 361 i::Handle<i::WasmModuleObject> module_obj;
362 if (want_pair) {
363 i::MaybeHandle<i::WasmModuleObject> maybe_module_obj =
364 CreateModuleObject(isolate, args[0], &thrower);
365 if (!maybe_module_obj.ToHandle(&module_obj)) {
366 DCHECK(thrower.error());
367 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
368 return;
369 }
370 } else {
371 module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg);
372 }
373 DCHECK(!module_obj.is_null());
374 MaybeLocal<Value> instance =
375 InstantiateModuleImpl(i_isolate, module_obj, args, &thrower);
352 if (instance.IsEmpty()) { 376 if (instance.IsEmpty()) {
353 DCHECK(thrower.error()); 377 DCHECK(thrower.error());
354 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 378 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
355 } else { 379 } else {
356 DCHECK(!thrower.error()); 380 DCHECK(!thrower.error());
357 resolver->Resolve(context, instance.ToLocalChecked()); 381 Local<Value> retval;
382 if (want_pair) {
383 i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>(
384 i_isolate->native_context()->object_function(), i_isolate);
385
386 i::Handle<i::JSObject> i_retval =
387 i_isolate->factory()->NewJSObject(object_function, i::TENURED);
388 i::Handle<i::String> module_property_name =
389 i_isolate->factory()->InternalizeUtf8String("module");
390 i::Handle<i::String> instance_property_name =
391 i_isolate->factory()->InternalizeUtf8String("instance");
392 i::JSObject::AddProperty(i_retval, module_property_name, module_obj,
393 i::NONE);
394 i::JSObject::AddProperty(i_retval, instance_property_name,
395 Utils::OpenHandle(*instance.ToLocalChecked()),
396 i::NONE);
397 retval = Utils::ToLocal(i_retval);
398 } else {
399 retval = instance.ToLocalChecked();
400 }
401 DCHECK(!retval.IsEmpty());
402 resolver->Resolve(context, retval);
358 } 403 }
359 } 404 }
360 405
361 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, 406 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
362 Local<Context> context, Local<v8::Object> object, 407 Local<Context> context, Local<v8::Object> object,
363 Local<String> property, int* result, 408 Local<String> property, int* result,
364 int64_t lower_bound, uint64_t upper_bound) { 409 int64_t lower_bound, uint64_t upper_bound) {
365 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); 410 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property);
366 v8::Local<v8::Value> value; 411 v8::Local<v8::Value> value;
367 if (maybe.ToLocal(&value)) { 412 if (maybe.ToLocal(&value)) {
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); 951 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
907 return HasBrand(value, symbol); 952 return HasBrand(value, symbol);
908 } 953 }
909 954
910 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { 955 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
911 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); 956 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
912 return HasBrand(value, symbol); 957 return HasBrand(value, symbol);
913 } 958 }
914 } // namespace internal 959 } // namespace internal
915 } // namespace v8 960 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/wasm/js-api.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698