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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 170 void WebAssemblyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
171 v8::Isolate* isolate = args.GetIsolate(); | 171 v8::Isolate* isolate = args.GetIsolate(); |
172 HandleScope scope(isolate); | 172 HandleScope scope(isolate); |
173 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), | 173 ErrorThrower thrower(reinterpret_cast<i::Isolate*>(isolate), |
174 "WebAssembly.Module()"); | 174 "WebAssembly.Module()"); |
175 | 175 |
176 if (args.Length() < 1) { | 176 if (args.Length() < 1) { |
177 thrower.TypeError("Argument 0 must be a buffer source"); | 177 thrower.TypeError("Argument 0 must be a buffer source"); |
178 return; | 178 return; |
179 } | 179 } |
| 180 |
| 181 if (args.Length() > 2) { |
| 182 thrower.LinkError( |
| 183 "WebAssembly.instantiate accepts no more than 2 parameters"); |
| 184 return; |
| 185 } |
180 i::MaybeHandle<i::JSObject> module_obj = | 186 i::MaybeHandle<i::JSObject> module_obj = |
181 CreateModuleObject(isolate, args[0], &thrower); | 187 CreateModuleObject(isolate, args[0], &thrower); |
182 if (module_obj.is_null()) return; | 188 if (module_obj.is_null()) return; |
183 | 189 |
184 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 190 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
185 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); | 191 return_value.Set(Utils::ToLocal(module_obj.ToHandleChecked())); |
186 } | 192 } |
187 | 193 |
188 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { | 194 MaybeLocal<Value> InstantiateModuleImpl( |
| 195 i::Isolate* i_isolate, i::Handle<i::JSObject> i_module_obj, |
| 196 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { |
| 197 // It so happens that in both the WebAssembly.instantiate, as well as |
| 198 // WebAssembly.Instance ctor, the positions of the ffi object and memory |
| 199 // are the same. If that changes later, we refactor the consts into |
| 200 // parameters. |
| 201 static const int kFfiOffset = 1; |
| 202 static const int kMemOffset = 2; |
| 203 |
| 204 MaybeLocal<Value> nothing; |
| 205 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); |
| 206 if (args.Length() > kFfiOffset && args[kFfiOffset]->IsObject()) { |
| 207 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]); |
| 208 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
| 209 } |
| 210 |
| 211 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
| 212 if (args.Length() > kMemOffset && args[kMemOffset]->IsObject()) { |
| 213 Local<Object> obj = Local<Object>::Cast(args[kMemOffset]); |
| 214 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
| 215 if (i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) { |
| 216 memory = i::Handle<i::JSArrayBuffer>( |
| 217 i::Handle<i::WasmMemoryObject>::cast(mem_obj)->buffer(), i_isolate); |
| 218 } else { |
| 219 thrower->TypeError("Argument %d must be a WebAssembly.Memory", |
| 220 kMemOffset); |
| 221 return nothing; |
| 222 } |
| 223 } |
| 224 i::MaybeHandle<i::JSObject> instance = i::wasm::WasmModule::Instantiate( |
| 225 i_isolate, thrower, i_module_obj, ffi, memory); |
| 226 if (instance.is_null()) { |
| 227 if (!thrower->error()) |
| 228 thrower->RuntimeError("Could not instantiate module"); |
| 229 return nothing; |
| 230 } |
| 231 DCHECK(!i_isolate->has_pending_exception()); |
| 232 return Utils::ToLocal(instance.ToHandleChecked()); |
| 233 } |
| 234 |
| 235 void WebAssemblyInstanceCtor(const v8::FunctionCallbackInfo<v8::Value>& args) { |
189 HandleScope scope(args.GetIsolate()); | 236 HandleScope scope(args.GetIsolate()); |
190 v8::Isolate* isolate = args.GetIsolate(); | 237 v8::Isolate* isolate = args.GetIsolate(); |
191 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 238 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
192 | 239 |
193 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); | 240 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); |
194 | 241 |
195 if (args.Length() < 1) { | 242 if (args.Length() < 1) { |
196 thrower.TypeError("Argument 0 must be a WebAssembly.Module"); | 243 thrower.TypeError("Argument 0 must be a WebAssembly.Module"); |
197 return; | 244 return; |
198 } | 245 } |
199 | 246 |
200 Local<Context> context = isolate->GetCurrentContext(); | 247 Local<Context> context = isolate->GetCurrentContext(); |
201 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); | 248 i::Handle<i::Context> i_context = Utils::OpenHandle(*context); |
202 if (!BrandCheck(isolate, Utils::OpenHandle(*args[0]), | 249 if (!BrandCheck(isolate, Utils::OpenHandle(*args[0]), |
203 i::Handle<i::Symbol>(i_context->wasm_module_sym()), | 250 i::Handle<i::Symbol>(i_context->wasm_module_sym()), |
204 "Argument 0 must be a WebAssembly.Module")) { | 251 "Argument 0 must be a WebAssembly.Module")) { |
205 return; | 252 return; |
206 } | 253 } |
207 | 254 |
208 Local<Object> obj = Local<Object>::Cast(args[0]); | 255 Local<Object> module_obj = Local<Object>::Cast(args[0]); |
209 i::Handle<i::JSObject> i_obj = | 256 i::Handle<i::JSObject> i_module_obj = |
210 i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); | 257 i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*module_obj)); |
211 | 258 |
212 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); | 259 MaybeLocal<Value> instance = |
213 if (args.Length() > 1 && args[1]->IsObject()) { | 260 InstantiateModuleImpl(i_isolate, i_module_obj, args, &thrower); |
214 Local<Object> obj = Local<Object>::Cast(args[1]); | 261 if (instance.IsEmpty()) return; |
215 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | 262 |
| 263 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 264 return_value.Set(instance.ToLocalChecked()); |
| 265 } |
| 266 |
| 267 void WebAssemblyInstantiate(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 268 v8::Isolate* isolate = args.GetIsolate(); |
| 269 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 270 |
| 271 HandleScope scope(isolate); |
| 272 ErrorThrower thrower(i_isolate, "WebAssembly.compile()"); |
| 273 |
| 274 if (args.Length() < 1) { |
| 275 thrower.TypeError("Argument 0 must be a buffer source"); |
| 276 return; |
216 } | 277 } |
| 278 i::MaybeHandle<i::JSObject> module_obj = |
| 279 CreateModuleObject(isolate, args[0], &thrower); |
217 | 280 |
218 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 281 Local<Context> context = isolate->GetCurrentContext(); |
219 if (args.Length() > 2 && args[2]->IsObject()) { | 282 v8::Local<v8::Promise::Resolver> resolver; |
220 Local<Object> obj = Local<Object>::Cast(args[2]); | 283 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) return; |
221 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | 284 if (module_obj.is_null()) { |
222 if (i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) { | 285 DCHECK(thrower.error()); |
223 memory = i::Handle<i::JSArrayBuffer>( | 286 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
224 i::Handle<i::WasmMemoryObject>::cast(mem_obj)->buffer(), i_isolate); | 287 } else { |
| 288 MaybeLocal<Value> instance = InstantiateModuleImpl( |
| 289 i_isolate, module_obj.ToHandleChecked(), args, &thrower); |
| 290 if (instance.IsEmpty()) { |
| 291 DCHECK(thrower.error()); |
| 292 resolver->Reject(context, Utils::ToLocal(thrower.Reify())); |
225 } else { | 293 } else { |
226 thrower.TypeError("Argument 2 must be a WebAssembly.Memory"); | 294 DCHECK(!thrower.error()); |
227 return; | 295 resolver->Resolve(context, instance.ToLocalChecked()); |
228 } | 296 } |
229 } | 297 } |
230 i::MaybeHandle<i::JSObject> instance = | |
231 i::wasm::WasmModule::Instantiate(i_isolate, &thrower, i_obj, ffi, memory); | |
232 if (instance.is_null()) { | |
233 if (!thrower.error()) thrower.RuntimeError("Could not instantiate module"); | |
234 return; | |
235 } | |
236 DCHECK(!i_isolate->has_pending_exception()); | |
237 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 298 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
238 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); | 299 return_value.Set(resolver->GetPromise()); |
239 } | 300 } |
240 | 301 |
241 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, | 302 bool GetIntegerProperty(v8::Isolate* isolate, ErrorThrower* thrower, |
242 Local<Context> context, Local<v8::Object> object, | 303 Local<Context> context, Local<v8::Object> object, |
243 Local<String> property, int* result, int lower_bound, | 304 Local<String> property, int* result, int lower_bound, |
244 int upper_bound) { | 305 int upper_bound) { |
245 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); | 306 v8::MaybeLocal<v8::Value> maybe = object->Get(context, property); |
246 v8::Local<v8::Value> value; | 307 v8::Local<v8::Value> value; |
247 if (maybe.ToLocal(&value)) { | 308 if (maybe.ToLocal(&value)) { |
248 int64_t number; | 309 int64_t number; |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 JSFunction::SetInstancePrototype( | 695 JSFunction::SetInstancePrototype( |
635 cons, Handle<Object>(context->initial_object_prototype(), isolate)); | 696 cons, Handle<Object>(context->initial_object_prototype(), isolate)); |
636 cons->shared()->set_instance_class_name(*name); | 697 cons->shared()->set_instance_class_name(*name); |
637 Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED); | 698 Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED); |
638 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | 699 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
639 JSObject::AddProperty(global, name, webassembly, attributes); | 700 JSObject::AddProperty(global, name, webassembly, attributes); |
640 | 701 |
641 // Setup compile | 702 // Setup compile |
642 InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1); | 703 InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1); |
643 | 704 |
644 // Setup compile | 705 // Setup validate |
645 InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1); | 706 InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1); |
646 | 707 |
| 708 // Setup instantiate |
| 709 InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1); |
| 710 |
647 // Setup Module | 711 // Setup Module |
648 Handle<JSFunction> module_constructor = | 712 Handle<JSFunction> module_constructor = |
649 InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1); | 713 InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1); |
650 context->set_wasm_module_constructor(*module_constructor); | 714 context->set_wasm_module_constructor(*module_constructor); |
651 Handle<JSObject> module_proto = | 715 Handle<JSObject> module_proto = |
652 factory->NewJSObject(module_constructor, TENURED); | 716 factory->NewJSObject(module_constructor, TENURED); |
653 i::Handle<i::Map> map = isolate->factory()->NewMap( | 717 i::Handle<i::Map> map = isolate->factory()->NewMap( |
654 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + | 718 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
655 WasmModuleObject::kFieldCount * i::kPointerSize); | 719 WasmModuleObject::kFieldCount * i::kPointerSize); |
656 JSFunction::SetInitialMap(module_constructor, map, module_proto); | 720 JSFunction::SetInitialMap(module_constructor, map, module_proto); |
657 JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), | 721 JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), |
658 module_constructor, DONT_ENUM); | 722 module_constructor, DONT_ENUM); |
659 | 723 |
660 // Setup Instance | 724 // Setup Instance |
661 Handle<JSFunction> instance_constructor = | 725 Handle<JSFunction> instance_constructor = |
662 InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance, 1); | 726 InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstanceCtor, 1); |
663 context->set_wasm_instance_constructor(*instance_constructor); | 727 context->set_wasm_instance_constructor(*instance_constructor); |
664 | 728 |
665 // Setup Table | 729 // Setup Table |
666 Handle<JSFunction> table_constructor = | 730 Handle<JSFunction> table_constructor = |
667 InstallFunc(isolate, webassembly, "Table", WebAssemblyTable, 1); | 731 InstallFunc(isolate, webassembly, "Table", WebAssemblyTable, 1); |
668 context->set_wasm_table_constructor(*table_constructor); | 732 context->set_wasm_table_constructor(*table_constructor); |
669 Handle<JSObject> table_proto = | 733 Handle<JSObject> table_proto = |
670 factory->NewJSObject(table_constructor, TENURED); | 734 factory->NewJSObject(table_constructor, TENURED); |
671 map = isolate->factory()->NewMap( | 735 map = isolate->factory()->NewMap( |
672 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + | 736 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); | 831 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); |
768 return HasBrand(value, symbol); | 832 return HasBrand(value, symbol); |
769 } | 833 } |
770 | 834 |
771 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { | 835 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { |
772 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); | 836 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); |
773 return HasBrand(value, symbol); | 837 return HasBrand(value, symbol); |
774 } | 838 } |
775 } // namespace internal | 839 } // namespace internal |
776 } // namespace v8 | 840 } // namespace v8 |
OLD | NEW |