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

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

Issue 2644993002: [wasm] WebAssembly.instantiate has a pair-returning overload (Closed)
Patch Set: tests 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') | test/mjsunit/wasm/js-api.js » ('J')
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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 return_value.Set(v8::False(isolate)); 173 return_value.Set(v8::False(isolate));
163 } 174 }
164 } 175 }
165 176
166 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { 177 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) {
167 v8::Isolate* isolate = args.GetIsolate(); 178 v8::Isolate* isolate = args.GetIsolate();
168 HandleScope scope(isolate); 179 HandleScope scope(isolate);
169 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), 180 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate),
170 "WebAssembly.Module()"); 181 "WebAssembly.Module()");
171 182
172 if (args.Length() < 1) { 183 if (args.Length() != 1) {
rossberg 2017/01/20 09:56:54 JavaScript always allows unused extra arguments, s
Mircea Trofin 2017/01/20 16:29:53 Done.
173 thrower.TypeError("Argument 0 must be a buffer source"); 184 thrower.TypeError("Argument 0 must be a buffer source");
174 return; 185 return;
175 } 186 }
176 187
177 if (args.Length() > 2) {
178 thrower.LinkError(
179 "WebAssembly.instantiate accepts no more than 2 parameters");
180 return;
181 }
182 i::MaybeHandle<i::JSObject> module_obj = 188 i::MaybeHandle<i::JSObject> module_obj =
183 CreateModuleObject(isolate, args[0], &thrower); 189 CreateModuleObject(isolate, args[0], &thrower);
184 if (module_obj.is_null()) return; 190 if (module_obj.is_null()) return;
185 191
186 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 192 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
187 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); 193 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked()));
188 } 194 }
189 195
190 MaybeLocal<Value> InstantiateModuleImpl( 196 MaybeLocal<Value> InstantiateModuleImpl(
191 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj, 197 i::Isolate* i_isolate, i::Handle<i::WasmModuleObject> i_module_obj,
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 } 324 }
319 325
320 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { 326 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) {
321 v8::Isolate* isolate = args.GetIsolate(); 327 v8::Isolate* isolate = args.GetIsolate();
322 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); 328 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
323 329
324 HandleScope scope(isolate); 330 HandleScope scope(isolate);
325 ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); 331 ErrorThrower thrower(i_isolate, "WebAssembly.compile()");
326 332
327 Local<Context> context = isolate->GetCurrentContext(); 333 Local<Context> context = isolate->GetCurrentContext();
334 i::Handle<i::Context> i_context = Utils::OpenHandle(*context);
335
328 v8::Local<v8::Promise::Resolver> resolver; 336 v8::Local<v8::Promise::Resolver> resolver;
329 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; 337 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return;
330 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); 338 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue();
331 return_value.Set(resolver->GetPromise()); 339 return_value.Set(resolver->GetPromise());
332 340
333 if (args.Length() < 1) { 341 if (args.Length() < 1) {
334 thrower.TypeError("Argument 0 must be a buffer source"); 342 thrower.TypeError(
343 "Argument 0 must be provided and must be either a buffer source or a "
344 "WebAssembly.Module object");
335 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 345 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
336 return; 346 return;
337 } 347 }
338 348
339 i::MaybeHandle<i::WasmModuleObject> module_obj = 349 i::Handle<i::Object> first_arg = Utils::OpenHandle(*args[0]);
340 CreateModuleObject(isolate, args[0], &thrower); 350 if (!first_arg->IsJSObject()) {
341 if (module_obj.is_null()) { 351 thrower.TypeError(
342 DCHECK(thrower.error()); 352 "Argument 0 must be a buffer source or a WebAssembly.Module object");
343 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 353 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
344 return; 354 return;
345 } 355 }
346 356 bool want_pair = !BrandCheck(
347 MaybeLocal<Value> instance = InstantiateModuleImpl( 357 isolate, first_arg, i::Handle<i::Symbol>(i_context->wasm_module_sym()));
348 i_isolate, module_obj.ToHandleChecked(), args, &thrower); 358 i::Handle<i::WasmModuleObject> module_obj;
359 if (want_pair) {
360 i::MaybeHandle<i::WasmModuleObject> maybe_module_obj =
361 CreateModuleObject(isolate, args[0], &thrower);
362 if (!maybe_module_obj.ToHandle(&module_obj)) {
363 DCHECK(thrower.error());
364 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
365 return;
366 }
367 } else {
368 module_obj = i::Handle<i::WasmModuleObject>::cast(first_arg);
369 }
370 DCHECK(!module_obj.is_null());
371 MaybeLocal<Value> instance =
372 InstantiateModuleImpl(i_isolate, module_obj, args, &thrower);
349 if (instance.IsEmpty()) { 373 if (instance.IsEmpty()) {
350 DCHECK(thrower.error()); 374 DCHECK(thrower.error());
351 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); 375 resolver->Reject(context, Utils::ToLocal(thrower.Reify()));
352 } else { 376 } else {
353 DCHECK(!thrower.error()); 377 DCHECK(!thrower.error());
354 resolver->Resolve(context, instance.ToLocalChecked()); 378 Local<Value> retval;
379 if (want_pair) {
380 i::Handle<i::JSFunction> object_function = i::Handle<i::JSFunction>(
381 i_isolate->native_context()->object_function(), i_isolate);
382
383 i::Handle<i::JSObject> i_retval =
384 i_isolate->factory()->NewJSObject(object_function, i::TENURED);
385 i::Handle<i::String> module_property_name =
386 i_isolate->factory()->InternalizeUtf8String("module");
387 i::Handle<i::String> instance_property_name =
388 i_isolate->factory()->InternalizeUtf8String("instance");
389 i::JSObject::AddProperty(i_retval, module_property_name, module_obj,
390 i::NONE);
391 i::JSObject::AddProperty(i_retval, instance_property_name,
392 Utils::OpenHandle(*instance.ToLocalChecked()),
393 i::NONE);
394 retval = Utils::ToLocal(i_retval);
395 } else {
396 retval = instance.ToLocalChecked();
397 }
398 DCHECK(!retval.IsEmpty());
399 resolver->Resolve(context, retval);
355 } 400 }
356 } 401 }
357 402
358 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, 403 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower,
359 Local<Context> context, Local<v8::Object> object, 404 Local<Context> context, Local<v8::Object> object,
360 Local<String> property, int* result, 405 Local<String> property, int* result,
361 int64_t lower_bound, uint64_t upper_bound) { 406 int64_t lower_bound, uint64_t upper_bound) {
362 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); 407 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property);
363 v8::Local<v8::Value> value; 408 v8::Local<v8::Value> value;
364 if (maybe.ToLocal(&value)) { 409 if (maybe.ToLocal(&value)) {
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); 948 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate);
904 return HasBrand(value, symbol); 949 return HasBrand(value, symbol);
905 } 950 }
906 951
907 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { 952 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) {
908 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); 953 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate);
909 return HasBrand(value, symbol); 954 return HasBrand(value, symbol);
910 } 955 }
911 } // namespace internal 956 } // namespace internal
912 } // namespace v8 957 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/wasm/js-api.js » ('j') | test/mjsunit/wasm/js-api.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698