OLD | NEW |
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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 | 50 |
51 if (source->IsArrayBuffer()) { | 51 if (source->IsArrayBuffer()) { |
52 // A raw array buffer was passed. | 52 // A raw array buffer was passed. |
53 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source); | 53 Local<ArrayBuffer> buffer = Local<ArrayBuffer>::Cast(source); |
54 ArrayBuffer::Contents contents = buffer->GetContents(); | 54 ArrayBuffer::Contents contents = buffer->GetContents(); |
55 | 55 |
56 start = reinterpret_cast<const byte*>(contents.Data()); | 56 start = reinterpret_cast<const byte*>(contents.Data()); |
57 end = start + contents.ByteLength(); | 57 end = start + contents.ByteLength(); |
58 | 58 |
59 if (start == nullptr || end == start) { | 59 if (start == nullptr || end == start) { |
60 thrower->Error("ArrayBuffer argument is empty"); | 60 thrower->CompileError("ArrayBuffer argument is empty"); |
61 } | 61 } |
62 } else if (source->IsTypedArray()) { | 62 } else if (source->IsTypedArray()) { |
63 // A TypedArray was passed. | 63 // A TypedArray was passed. |
64 Local<TypedArray> array = Local<TypedArray>::Cast(source); | 64 Local<TypedArray> array = Local<TypedArray>::Cast(source); |
65 Local<ArrayBuffer> buffer = array->Buffer(); | 65 Local<ArrayBuffer> buffer = array->Buffer(); |
66 | 66 |
67 ArrayBuffer::Contents contents = buffer->GetContents(); | 67 ArrayBuffer::Contents contents = buffer->GetContents(); |
68 | 68 |
69 start = | 69 start = |
70 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset(); | 70 reinterpret_cast<const byte*>(contents.Data()) + array->ByteOffset(); |
71 end = start + array->ByteLength(); | 71 end = start + array->ByteLength(); |
72 | 72 |
73 if (start == nullptr || end == start) { | 73 if (start == nullptr || end == start) { |
74 thrower->Error("ArrayBuffer argument is empty"); | 74 thrower->TypeError("ArrayBuffer argument is empty"); |
75 } | 75 } |
76 } else { | 76 } else { |
77 thrower->Error("Argument 0 must be an ArrayBuffer or Uint8Array"); | 77 thrower->TypeError("Argument 0 must be an ArrayBuffer or Uint8Array"); |
78 } | 78 } |
79 | 79 |
80 return {start, end}; | 80 return {start, end}; |
81 } | 81 } |
82 | 82 |
83 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 83 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
84 HandleScope scope(args.GetIsolate()); | 84 HandleScope scope(args.GetIsolate()); |
85 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 85 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
86 ErrorThrower thrower(isolate, "Wasm.verifyModule()"); | 86 ErrorThrower thrower(isolate, "Wasm.verifyModule()"); |
87 | 87 |
88 if (args.Length() < 1) { | 88 if (args.Length() < 1) { |
89 thrower.TypeError("Argument 0 must be a buffer source"); | 89 thrower.TypeError("Argument 0 must be a buffer source"); |
90 return; | 90 return; |
91 } | 91 } |
92 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | 92 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); |
93 if (thrower.error()) return; | 93 if (thrower.error()) return; |
94 | 94 |
95 i::Zone zone(isolate->allocator()); | 95 i::Zone zone(isolate->allocator()); |
96 internal::wasm::ModuleResult result = | 96 internal::wasm::ModuleResult result = |
97 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, | 97 internal::wasm::DecodeWasmModule(isolate, &zone, buffer.start, buffer.end, |
98 true, internal::wasm::kWasmOrigin); | 98 true, internal::wasm::kWasmOrigin); |
99 | 99 |
100 if (result.failed()) { | 100 if (result.failed()) { |
101 thrower.Failed("", result); | 101 thrower.CompileFailed("", result); |
102 } | 102 } |
103 | 103 |
104 if (result.val) delete result.val; | 104 if (result.val) delete result.val; |
105 } | 105 } |
106 | 106 |
107 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { | 107 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { |
108 HandleScope scope(args.GetIsolate()); | 108 HandleScope scope(args.GetIsolate()); |
109 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 109 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
110 ErrorThrower thrower(isolate, "Wasm.verifyFunction()"); | 110 ErrorThrower thrower(isolate, "Wasm.verifyFunction()"); |
111 | 111 |
112 if (args.Length() < 1) { | 112 if (args.Length() < 1) { |
113 thrower.TypeError("Argument 0 must be a buffer source"); | 113 thrower.TypeError("Argument 0 must be a buffer source"); |
114 return; | 114 return; |
115 } | 115 } |
116 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | 116 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); |
117 if (thrower.error()) return; | 117 if (thrower.error()) return; |
118 | 118 |
119 internal::wasm::FunctionResult result; | 119 internal::wasm::FunctionResult result; |
120 { | 120 { |
121 // Verification of a single function shouldn't allocate. | 121 // Verification of a single function shouldn't allocate. |
122 i::DisallowHeapAllocation no_allocation; | 122 i::DisallowHeapAllocation no_allocation; |
123 i::Zone zone(isolate->allocator()); | 123 i::Zone zone(isolate->allocator()); |
124 result = internal::wasm::DecodeWasmFunction(isolate, &zone, nullptr, | 124 result = internal::wasm::DecodeWasmFunction(isolate, &zone, nullptr, |
125 buffer.start, buffer.end); | 125 buffer.start, buffer.end); |
126 } | 126 } |
127 | 127 |
128 if (result.failed()) { | 128 if (result.failed()) { |
129 thrower.Failed("", result); | 129 thrower.CompileFailed("", result); |
130 } | 130 } |
131 | 131 |
132 if (result.val) delete result.val; | 132 if (result.val) delete result.val; |
133 } | 133 } |
134 | 134 |
135 i::MaybeHandle<i::JSObject> InstantiateModule( | 135 i::MaybeHandle<i::JSObject> InstantiateModule( |
136 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, | 136 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, |
137 const byte* end, ErrorThrower* thrower) { | 137 const byte* end, ErrorThrower* thrower) { |
138 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 138 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
139 | 139 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 | 327 |
328 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 328 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
329 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | 329 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { |
330 Local<Object> obj = Local<Object>::Cast(args[2]); | 330 Local<Object> obj = Local<Object>::Cast(args[2]); |
331 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | 331 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
332 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | 332 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); |
333 } | 333 } |
334 i::MaybeHandle<i::JSObject> instance = i::wasm::WasmModule::Instantiate( | 334 i::MaybeHandle<i::JSObject> instance = i::wasm::WasmModule::Instantiate( |
335 i_isolate, &thrower, module_obj, ffi, memory); | 335 i_isolate, &thrower, module_obj, ffi, memory); |
336 if (instance.is_null()) { | 336 if (instance.is_null()) { |
337 if (!thrower.error()) thrower.Error("Could not instantiate module"); | 337 if (!thrower.error()) thrower.RuntimeError("Could not instantiate module"); |
338 return; | 338 return; |
339 } | 339 } |
| 340 DCHECK(!i_isolate->has_pending_exception()); |
340 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 341 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
341 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); | 342 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); |
342 } | 343 } |
343 | 344 |
344 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, | 345 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, |
345 Local<Context> context, Local<v8::Object> object, | 346 Local<Context> context, Local<v8::Object> object, |
346 Local<String> property, int* result, int lower_bound, | 347 Local<String> property, int* result, int lower_bound, |
347 int upper_bound) { | 348 int upper_bound) { |
348 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); | 349 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); |
349 v8::Local<v8::Value> value; | 350 v8::Local<v8::Value> value; |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 438 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
438 return_value.Set(Utils::ToLocal(table_obj)); | 439 return_value.Set(Utils::ToLocal(table_obj)); |
439 } | 440 } |
440 | 441 |
441 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { | 442 void WebAssemblyMemory(const v8::FunctionCallbackInfo<v8::Value>& args) { |
442 v8::Isolate* isolate = args.GetIsolate(); | 443 v8::Isolate* isolate = args.GetIsolate(); |
443 HandleScope scope(isolate); | 444 HandleScope scope(isolate); |
444 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | 445 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
445 "WebAssembly.Module()"); | 446 "WebAssembly.Module()"); |
446 if (args.Length() < 1 || !args[0]->IsObject()) { | 447 if (args.Length() < 1 || !args[0]->IsObject()) { |
447 thrower.TypeError("Argument 0 must be a table descriptor"); | 448 thrower.TypeError("Argument 0 must be a memory descriptor"); |
448 return; | 449 return; |
449 } | 450 } |
450 Local<Context> context = isolate->GetCurrentContext(); | 451 Local<Context> context = isolate->GetCurrentContext(); |
451 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); | 452 Local<v8::Object> descriptor = args[0]->ToObject(context).ToLocalChecked(); |
452 // The descriptor's 'initial'. | 453 // The descriptor's 'initial'. |
453 int initial; | 454 int initial; |
454 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, | 455 if (!GetIntegerProperty(isolate, &thrower, context, descriptor, |
455 v8_str(isolate, "initial"), &initial, 0, 65536)) { | 456 v8_str(isolate, "initial"), &initial, 0, 65536)) { |
456 return; | 457 return; |
457 } | 458 } |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 context->set_wasm_memory_constructor(*memory_constructor); | 658 context->set_wasm_memory_constructor(*memory_constructor); |
658 Handle<JSObject> memory_proto = | 659 Handle<JSObject> memory_proto = |
659 factory->NewJSObject(memory_constructor, TENURED); | 660 factory->NewJSObject(memory_constructor, TENURED); |
660 map = isolate->factory()->NewMap( | 661 map = isolate->factory()->NewMap( |
661 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); | 662 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + 2 * i::kPointerSize); |
662 JSFunction::SetInitialMap(memory_constructor, map, memory_proto); | 663 JSFunction::SetInitialMap(memory_constructor, map, memory_proto); |
663 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), | 664 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), |
664 memory_constructor, DONT_ENUM); | 665 memory_constructor, DONT_ENUM); |
665 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow); | 666 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow); |
666 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); | 667 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); |
| 668 |
| 669 // Setup errors |
| 670 attributes = static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
| 671 Handle<JSFunction> compile_error( |
| 672 isolate->native_context()->wasm_compile_error_function()); |
| 673 JSObject::AddProperty(wasm_object, isolate->factory()->CompileError_string(), |
| 674 compile_error, attributes); |
| 675 Handle<JSFunction> runtime_error( |
| 676 isolate->native_context()->wasm_runtime_error_function()); |
| 677 JSObject::AddProperty(wasm_object, isolate->factory()->RuntimeError_string(), |
| 678 runtime_error, attributes); |
667 } | 679 } |
668 | 680 |
669 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 681 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
670 if (!FLAG_expose_wasm && !FLAG_validate_asm) { | 682 if (!FLAG_expose_wasm && !FLAG_validate_asm) { |
671 return; | 683 return; |
672 } | 684 } |
673 | 685 |
674 Factory* factory = isolate->factory(); | 686 Factory* factory = isolate->factory(); |
675 | 687 |
676 // Setup wasm function map. | 688 // Setup wasm function map. |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, | 766 Handle<JSArrayBuffer> WasmJs::GetWasmMemoryArrayBuffer(Isolate* isolate, |
755 Handle<Object> value) { | 767 Handle<Object> value) { |
756 DCHECK(IsWasmMemoryObject(isolate, value)); | 768 DCHECK(IsWasmMemoryObject(isolate, value)); |
757 Handle<Object> buf( | 769 Handle<Object> buf( |
758 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), | 770 JSObject::cast(*value)->GetInternalField(kWasmMemoryBufferFieldIndex), |
759 isolate); | 771 isolate); |
760 return Handle<JSArrayBuffer>::cast(buf); | 772 return Handle<JSArrayBuffer>::cast(buf); |
761 } | 773 } |
762 } // namespace internal | 774 } // namespace internal |
763 } // namespace v8 | 775 } // namespace v8 |
OLD | NEW |