| 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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->TypeError("ArrayBuffer argument is empty"); | 74 thrower->CompileError("ArrayBuffer argument is empty"); |
| 75 } | 75 } |
| 76 } else { | 76 } else { |
| 77 thrower->TypeError("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 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( | 83 static i::MaybeHandle<i::WasmModuleObject> CreateModuleObject( |
| 84 v8::Isolate* isolate, const v8::Local<v8::Value> source, | 84 v8::Isolate* isolate, const v8::Local<v8::Value> source, |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 196 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { | 196 const v8::FunctionCallbackInfo<v8::Value>& args, ErrorThrower* thrower) { |
| 197 // It so happens that in both the WebAssembly.instantiate, as well as | 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 | 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 | 199 // are the same. If that changes later, we refactor the consts into |
| 200 // parameters. | 200 // parameters. |
| 201 static const int kFfiOffset = 1; | 201 static const int kFfiOffset = 1; |
| 202 static const int kMemOffset = 2; | 202 static const int kMemOffset = 2; |
| 203 | 203 |
| 204 MaybeLocal<Value> nothing; | 204 MaybeLocal<Value> nothing; |
| 205 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); | 205 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); |
| 206 if (args.Length() > kFfiOffset && args[kFfiOffset]->IsObject()) { | 206 if (args.Length() > kFfiOffset && !args[kFfiOffset]->IsUndefined()) { |
| 207 if (!args[kFfiOffset]->IsObject()) { |
| 208 thrower->TypeError("Argument %d must be an object", kFfiOffset); |
| 209 return nothing; |
| 210 } |
| 207 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]); | 211 Local<Object> obj = Local<Object>::Cast(args[kFfiOffset]); |
| 208 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | 212 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
| 209 } | 213 } |
| 210 | 214 |
| 211 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 215 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
| 212 if (args.Length() > kMemOffset && args[kMemOffset]->IsObject()) { | 216 if (args.Length() > kMemOffset && !args[kMemOffset]->IsUndefined()) { |
| 213 Local<Object> obj = Local<Object>::Cast(args[kMemOffset]); | 217 if (!args[kMemOffset]->IsObject()) { |
| 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", | 218 thrower->TypeError("Argument %d must be a WebAssembly.Memory", |
| 220 kMemOffset); | 219 kMemOffset); |
| 221 return nothing; | 220 return nothing; |
| 222 } | 221 } |
| 222 Local<Object> obj = Local<Object>::Cast(args[kMemOffset]); |
| 223 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
| 224 if (!i::WasmJs::IsWasmMemoryObject(i_isolate, mem_obj)) { |
| 225 thrower->TypeError("Argument %d must be a WebAssembly.Memory", |
| 226 kMemOffset); |
| 227 return nothing; |
| 228 } |
| 229 memory = i::Handle<i::JSArrayBuffer>( |
| 230 i::Handle<i::WasmMemoryObject>::cast(mem_obj)->buffer(), i_isolate); |
| 223 } | 231 } |
| 224 i::MaybeHandle<i::JSObject> instance = i::wasm::WasmModule::Instantiate( | 232 i::MaybeHandle<i::JSObject> instance = i::wasm::WasmModule::Instantiate( |
| 225 i_isolate, thrower, i_module_obj, ffi, memory); | 233 i_isolate, thrower, i_module_obj, ffi, memory); |
| 226 if (instance.is_null()) { | 234 if (instance.is_null()) { |
| 227 if (!thrower->error()) | 235 if (!thrower->error()) |
| 228 thrower->RuntimeError("Could not instantiate module"); | 236 thrower->RuntimeError("Could not instantiate module"); |
| 229 return nothing; | 237 return nothing; |
| 230 } | 238 } |
| 231 DCHECK(!i_isolate->has_pending_exception()); | 239 DCHECK(!i_isolate->has_pending_exception()); |
| 232 return Utils::ToLocal(instance.ToHandleChecked()); | 240 return Utils::ToLocal(instance.ToHandleChecked()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 Local<Object> module_obj = Local<Object>::Cast(args[0]); | 293 Local<Object> module_obj = Local<Object>::Cast(args[0]); |
| 286 i::Handle<i::WasmModuleObject> i_module_obj = | 294 i::Handle<i::WasmModuleObject> i_module_obj = |
| 287 i::Handle<i::WasmModuleObject>::cast(v8::Utils::OpenHandle(*module_obj)); | 295 i::Handle<i::WasmModuleObject>::cast(v8::Utils::OpenHandle(*module_obj)); |
| 288 | 296 |
| 289 i::Handle<i::JSArray> exports = i::wasm::GetExports(i_isolate, i_module_obj); | 297 i::Handle<i::JSArray> exports = i::wasm::GetExports(i_isolate, i_module_obj); |
| 290 | 298 |
| 291 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 299 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
| 292 return_value.Set(Utils::ToLocal(exports)); | 300 return_value.Set(Utils::ToLocal(exports)); |
| 293 } | 301 } |
| 294 | 302 |
| 295 void WebAssemblyInstanceCtor(const v8::FunctionCallbackInfo<v8::Value>& args) { | 303 void WebAssemblyInstance(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 296 HandleScope scope(args.GetIsolate()); | 304 HandleScope scope(args.GetIsolate()); |
| 297 v8::Isolate* isolate = args.GetIsolate(); | 305 v8::Isolate* isolate = args.GetIsolate(); |
| 298 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 306 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
| 299 | 307 |
| 300 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); | 308 ErrorThrower thrower(i_isolate, "WebAssembly.Instance()"); |
| 301 | 309 |
| 302 if (args.Length() < 1) { | 310 if (args.Length() < 1) { |
| 303 thrower.TypeError("Argument 0 must be a WebAssembly.Module"); | 311 thrower.TypeError("Argument 0 must be a WebAssembly.Module"); |
| 304 return; | 312 return; |
| 305 } | 313 } |
| (...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 Handle<JSFunction> function = | 723 Handle<JSFunction> function = |
| 716 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 724 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
| 717 v8::PropertyAttribute attributes = | 725 v8::PropertyAttribute attributes = |
| 718 static_cast<v8::PropertyAttribute>(v8::DontEnum); | 726 static_cast<v8::PropertyAttribute>(v8::DontEnum); |
| 719 Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name), | 727 Utils::ToLocal(object)->SetAccessorProperty(Utils::ToLocal(name), |
| 720 Utils::ToLocal(function), | 728 Utils::ToLocal(function), |
| 721 Local<Function>(), attributes); | 729 Local<Function>(), attributes); |
| 722 return function; | 730 return function; |
| 723 } | 731 } |
| 724 | 732 |
| 725 void WasmJs::InstallWasmModuleSymbolIfNeeded(Isolate* isolate, | 733 void WasmJs::Install(Isolate* isolate) { |
| 726 Handle<JSGlobalObject> global, | 734 Handle<JSGlobalObject> global = isolate->global_object(); |
| 727 Handle<Context> context) { | 735 Handle<Context> context(global->native_context(), isolate); |
| 728 if (!context->get(Context::WASM_MODULE_SYM_INDEX)->IsSymbol() || | 736 // TODO(titzer): once FLAG_expose_wasm is gone, this should become a DCHECK. |
| 729 !context->get(Context::WASM_INSTANCE_SYM_INDEX)->IsSymbol()) { | 737 if (context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) return; |
| 730 InstallWasmMapsIfNeeded(isolate, isolate->native_context()); | |
| 731 InstallWasmConstructors(isolate, isolate->global_object(), | |
| 732 isolate->native_context()); | |
| 733 } | |
| 734 } | |
| 735 | 738 |
| 736 void WasmJs::InstallWasmConstructors(Isolate* isolate, | 739 // Install Maps. |
| 737 Handle<JSGlobalObject> global, | 740 |
| 738 Handle<Context> context) { | 741 // TODO(titzer): Also make one for strict mode functions? |
| 742 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
| 743 |
| 744 InstanceType instance_type = prev_map->instance_type(); |
| 745 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
| 746 CHECK_EQ(0, internal_fields); |
| 747 int pre_allocated = |
| 748 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); |
| 749 int instance_size = 0; |
| 750 int in_object_properties = 0; |
| 751 int wasm_internal_fields = internal_fields + 1 // module instance object |
| 752 + 1 // function arity |
| 753 + 1; // function signature |
| 754 JSFunction::CalculateInstanceSizeHelper(instance_type, wasm_internal_fields, |
| 755 0, &instance_size, |
| 756 &in_object_properties); |
| 757 |
| 758 int unused_property_fields = in_object_properties - pre_allocated; |
| 759 Handle<Map> map = Map::CopyInitialMap( |
| 760 prev_map, instance_size, in_object_properties, unused_property_fields); |
| 761 |
| 762 context->set_wasm_function_map(*map); |
| 763 |
| 764 // Install symbols. |
| 765 |
| 739 Factory* factory = isolate->factory(); | 766 Factory* factory = isolate->factory(); |
| 740 // Create private symbols. | 767 // Create private symbols. |
| 741 Handle<Symbol> module_sym = factory->NewPrivateSymbol(); | 768 Handle<Symbol> module_sym = factory->NewPrivateSymbol(); |
| 742 context->set_wasm_module_sym(*module_sym); | 769 context->set_wasm_module_sym(*module_sym); |
| 743 | 770 |
| 744 Handle<Symbol> instance_sym = factory->NewPrivateSymbol(); | 771 Handle<Symbol> instance_sym = factory->NewPrivateSymbol(); |
| 745 context->set_wasm_instance_sym(*instance_sym); | 772 context->set_wasm_instance_sym(*instance_sym); |
| 746 | 773 |
| 747 Handle<Symbol> table_sym = factory->NewPrivateSymbol(); | 774 Handle<Symbol> table_sym = factory->NewPrivateSymbol(); |
| 748 context->set_wasm_table_sym(*table_sym); | 775 context->set_wasm_table_sym(*table_sym); |
| 749 | 776 |
| 750 Handle<Symbol> memory_sym = factory->NewPrivateSymbol(); | 777 Handle<Symbol> memory_sym = factory->NewPrivateSymbol(); |
| 751 context->set_wasm_memory_sym(*memory_sym); | 778 context->set_wasm_memory_sym(*memory_sym); |
| 752 | 779 |
| 753 // Bind the WebAssembly object. | 780 // Install the JS API. |
| 781 |
| 782 // Setup WebAssembly |
| 754 Handle<String> name = v8_str(isolate, "WebAssembly"); | 783 Handle<String> name = v8_str(isolate, "WebAssembly"); |
| 755 Handle<JSFunction> cons = factory->NewFunction(name); | 784 Handle<JSFunction> cons = factory->NewFunction(name); |
| 756 JSFunction::SetInstancePrototype( | 785 JSFunction::SetInstancePrototype( |
| 757 cons, Handle<Object>(context->initial_object_prototype(), isolate)); | 786 cons, Handle<Object>(context->initial_object_prototype(), isolate)); |
| 758 cons->shared()->set_instance_class_name(*name); | 787 cons->shared()->set_instance_class_name(*name); |
| 759 Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED); | 788 Handle<JSObject> webassembly = factory->NewJSObject(cons, TENURED); |
| 760 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | 789 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
| 761 JSObject::AddProperty(global, name, webassembly, attributes); | 790 JSObject::AddProperty(global, name, webassembly, attributes); |
| 762 | 791 |
| 763 // Setup compile | 792 // Setup compile |
| 764 InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1); | 793 InstallFunc(isolate, webassembly, "compile", WebAssemblyCompile, 1); |
| 765 | 794 |
| 766 // Setup validate | 795 // Setup validate |
| 767 InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1); | 796 InstallFunc(isolate, webassembly, "validate", WebAssemblyValidate, 1); |
| 768 | 797 |
| 769 // Setup instantiate | 798 // Setup instantiate |
| 770 InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1); | 799 InstallFunc(isolate, webassembly, "instantiate", WebAssemblyInstantiate, 1); |
| 771 | 800 |
| 772 // Setup Module | 801 // Setup Module |
| 773 Handle<JSFunction> module_constructor = | 802 Handle<JSFunction> module_constructor = |
| 774 InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1); | 803 InstallFunc(isolate, webassembly, "Module", WebAssemblyModule, 1); |
| 775 context->set_wasm_module_constructor(*module_constructor); | 804 context->set_wasm_module_constructor(*module_constructor); |
| 776 Handle<JSObject> module_proto = | 805 Handle<JSObject> module_proto = |
| 777 factory->NewJSObject(module_constructor, TENURED); | 806 factory->NewJSObject(module_constructor, TENURED); |
| 778 i::Handle<i::Map> map = isolate->factory()->NewMap( | 807 i::Handle<i::Map> module_map = isolate->factory()->NewMap( |
| 779 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + | 808 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
| 780 WasmModuleObject::kFieldCount * i::kPointerSize); | 809 WasmModuleObject::kFieldCount * i::kPointerSize); |
| 781 JSFunction::SetInitialMap(module_constructor, map, module_proto); | 810 JSFunction::SetInitialMap(module_constructor, module_map, module_proto); |
| 782 JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), | 811 JSObject::AddProperty(module_proto, isolate->factory()->constructor_string(), |
| 783 module_constructor, DONT_ENUM); | 812 module_constructor, DONT_ENUM); |
| 784 InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports, | 813 InstallFunc(isolate, module_constructor, "imports", WebAssemblyModuleImports, |
| 785 1); | 814 1); |
| 786 InstallFunc(isolate, module_constructor, "exports", WebAssemblyModuleExports, | 815 InstallFunc(isolate, module_constructor, "exports", WebAssemblyModuleExports, |
| 787 1); | 816 1); |
| 788 | 817 |
| 789 // Setup Instance | 818 // Setup Instance |
| 790 Handle<JSFunction> instance_constructor = | 819 Handle<JSFunction> instance_constructor = |
| 791 InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstanceCtor, 1); | 820 InstallFunc(isolate, webassembly, "Instance", WebAssemblyInstance, 1); |
| 792 context->set_wasm_instance_constructor(*instance_constructor); | 821 context->set_wasm_instance_constructor(*instance_constructor); |
| 822 Handle<JSObject> instance_proto = |
| 823 factory->NewJSObject(instance_constructor, TENURED); |
| 824 i::Handle<i::Map> instance_map = isolate->factory()->NewMap( |
| 825 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
| 826 WasmInstanceObject::kFieldCount * i::kPointerSize); |
| 827 JSFunction::SetInitialMap(instance_constructor, instance_map, instance_proto); |
| 828 JSObject::AddProperty(instance_proto, |
| 829 isolate->factory()->constructor_string(), |
| 830 instance_constructor, DONT_ENUM); |
| 793 | 831 |
| 794 // Setup Table | 832 // Setup Table |
| 795 Handle<JSFunction> table_constructor = | 833 Handle<JSFunction> table_constructor = |
| 796 InstallFunc(isolate, webassembly, "Table", WebAssemblyTable, 1); | 834 InstallFunc(isolate, webassembly, "Table", WebAssemblyTable, 1); |
| 797 context->set_wasm_table_constructor(*table_constructor); | 835 context->set_wasm_table_constructor(*table_constructor); |
| 798 Handle<JSObject> table_proto = | 836 Handle<JSObject> table_proto = |
| 799 factory->NewJSObject(table_constructor, TENURED); | 837 factory->NewJSObject(table_constructor, TENURED); |
| 800 map = isolate->factory()->NewMap( | 838 i::Handle<i::Map> table_map = isolate->factory()->NewMap( |
| 801 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + | 839 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
| 802 WasmTableObject::kFieldCount * i::kPointerSize); | 840 WasmTableObject::kFieldCount * i::kPointerSize); |
| 803 JSFunction::SetInitialMap(table_constructor, map, table_proto); | 841 JSFunction::SetInitialMap(table_constructor, table_map, table_proto); |
| 804 JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), | 842 JSObject::AddProperty(table_proto, isolate->factory()->constructor_string(), |
| 805 table_constructor, DONT_ENUM); | 843 table_constructor, DONT_ENUM); |
| 806 InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); | 844 InstallGetter(isolate, table_proto, "length", WebAssemblyTableGetLength); |
| 807 InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow, 1); | 845 InstallFunc(isolate, table_proto, "grow", WebAssemblyTableGrow, 1); |
| 808 InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet, 1); | 846 InstallFunc(isolate, table_proto, "get", WebAssemblyTableGet, 1); |
| 809 InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet, 2); | 847 InstallFunc(isolate, table_proto, "set", WebAssemblyTableSet, 2); |
| 810 | 848 |
| 811 // Setup Memory | 849 // Setup Memory |
| 812 Handle<JSFunction> memory_constructor = | 850 Handle<JSFunction> memory_constructor = |
| 813 InstallFunc(isolate, webassembly, "Memory", WebAssemblyMemory, 1); | 851 InstallFunc(isolate, webassembly, "Memory", WebAssemblyMemory, 1); |
| 814 context->set_wasm_memory_constructor(*memory_constructor); | 852 context->set_wasm_memory_constructor(*memory_constructor); |
| 815 Handle<JSObject> memory_proto = | 853 Handle<JSObject> memory_proto = |
| 816 factory->NewJSObject(memory_constructor, TENURED); | 854 factory->NewJSObject(memory_constructor, TENURED); |
| 817 map = isolate->factory()->NewMap( | 855 i::Handle<i::Map> memory_map = isolate->factory()->NewMap( |
| 818 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + | 856 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + |
| 819 WasmMemoryObject::kFieldCount * i::kPointerSize); | 857 WasmMemoryObject::kFieldCount * i::kPointerSize); |
| 820 JSFunction::SetInitialMap(memory_constructor, map, memory_proto); | 858 JSFunction::SetInitialMap(memory_constructor, memory_map, memory_proto); |
| 821 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), | 859 JSObject::AddProperty(memory_proto, isolate->factory()->constructor_string(), |
| 822 memory_constructor, DONT_ENUM); | 860 memory_constructor, DONT_ENUM); |
| 823 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow, 1); | 861 InstallFunc(isolate, memory_proto, "grow", WebAssemblyMemoryGrow, 1); |
| 824 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); | 862 InstallGetter(isolate, memory_proto, "buffer", WebAssemblyMemoryGetBuffer); |
| 825 | 863 |
| 826 // Setup errors | 864 // Setup errors |
| 827 attributes = static_cast<PropertyAttributes>(DONT_ENUM); | 865 attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
| 828 Handle<JSFunction> compile_error( | 866 Handle<JSFunction> compile_error( |
| 829 isolate->native_context()->wasm_compile_error_function()); | 867 isolate->native_context()->wasm_compile_error_function()); |
| 830 JSObject::AddProperty(webassembly, isolate->factory()->CompileError_string(), | 868 JSObject::AddProperty(webassembly, isolate->factory()->CompileError_string(), |
| 831 compile_error, attributes); | 869 compile_error, attributes); |
| 832 Handle<JSFunction> link_error( | 870 Handle<JSFunction> link_error( |
| 833 isolate->native_context()->wasm_link_error_function()); | 871 isolate->native_context()->wasm_link_error_function()); |
| 834 JSObject::AddProperty(webassembly, isolate->factory()->LinkError_string(), | 872 JSObject::AddProperty(webassembly, isolate->factory()->LinkError_string(), |
| 835 link_error, attributes); | 873 link_error, attributes); |
| 836 Handle<JSFunction> runtime_error( | 874 Handle<JSFunction> runtime_error( |
| 837 isolate->native_context()->wasm_runtime_error_function()); | 875 isolate->native_context()->wasm_runtime_error_function()); |
| 838 JSObject::AddProperty(webassembly, isolate->factory()->RuntimeError_string(), | 876 JSObject::AddProperty(webassembly, isolate->factory()->RuntimeError_string(), |
| 839 runtime_error, attributes); | 877 runtime_error, attributes); |
| 840 } | 878 } |
| 841 | 879 |
| 842 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | |
| 843 if (!FLAG_expose_wasm && !FLAG_validate_asm) { | |
| 844 return; | |
| 845 } | |
| 846 | |
| 847 // Setup wasm function map. | |
| 848 Handle<Context> context(global->native_context(), isolate); | |
| 849 InstallWasmMapsIfNeeded(isolate, context); | |
| 850 | |
| 851 if (FLAG_expose_wasm) { | |
| 852 InstallWasmConstructors(isolate, global, context); | |
| 853 } | |
| 854 } | |
| 855 | |
| 856 void WasmJs::InstallWasmMapsIfNeeded(Isolate* isolate, | |
| 857 Handle<Context> context) { | |
| 858 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { | |
| 859 // TODO(titzer): Move this to bootstrapper.cc?? | |
| 860 // TODO(titzer): Also make one for strict mode functions? | |
| 861 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); | |
| 862 | |
| 863 InstanceType instance_type = prev_map->instance_type(); | |
| 864 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); | |
| 865 CHECK_EQ(0, internal_fields); | |
| 866 int pre_allocated = | |
| 867 prev_map->GetInObjectProperties() - prev_map->unused_property_fields(); | |
| 868 int instance_size = 0; | |
| 869 int in_object_properties = 0; | |
| 870 int wasm_internal_fields = internal_fields + 1 // module instance object | |
| 871 + 1 // function arity | |
| 872 + 1; // function signature | |
| 873 JSFunction::CalculateInstanceSizeHelper(instance_type, wasm_internal_fields, | |
| 874 0, &instance_size, | |
| 875 &in_object_properties); | |
| 876 | |
| 877 int unused_property_fields = in_object_properties - pre_allocated; | |
| 878 Handle<Map> map = Map::CopyInitialMap( | |
| 879 prev_map, instance_size, in_object_properties, unused_property_fields); | |
| 880 | |
| 881 context->set_wasm_function_map(*map); | |
| 882 } | |
| 883 } | |
| 884 | |
| 885 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> symbol) { | 880 static bool HasBrand(i::Handle<i::Object> value, i::Handle<i::Symbol> symbol) { |
| 886 if (value->IsJSObject()) { | 881 if (value->IsJSObject()) { |
| 887 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); | 882 i::Handle<i::JSObject> object = i::Handle<i::JSObject>::cast(value); |
| 888 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, symbol); | 883 Maybe<bool> has_brand = i::JSObject::HasOwnProperty(object, symbol); |
| 889 if (has_brand.IsNothing()) return false; | 884 if (has_brand.IsNothing()) return false; |
| 890 if (has_brand.ToChecked()) return true; | 885 if (has_brand.ToChecked()) return true; |
| 891 } | 886 } |
| 892 return false; | 887 return false; |
| 893 } | 888 } |
| 894 | 889 |
| 895 bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) { | 890 bool WasmJs::IsWasmMemoryObject(Isolate* isolate, Handle<Object> value) { |
| 896 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); | 891 i::Handle<i::Symbol> symbol(isolate->context()->wasm_memory_sym(), isolate); |
| 897 return HasBrand(value, symbol); | 892 return HasBrand(value, symbol); |
| 898 } | 893 } |
| 899 | 894 |
| 900 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { | 895 bool WasmJs::IsWasmTableObject(Isolate* isolate, Handle<Object> value) { |
| 901 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); | 896 i::Handle<i::Symbol> symbol(isolate->context()->wasm_table_sym(), isolate); |
| 902 return HasBrand(value, symbol); | 897 return HasBrand(value, symbol); |
| 903 } | 898 } |
| 904 } // namespace internal | 899 } // namespace internal |
| 905 } // namespace v8 | 900 } // namespace v8 |
| OLD | NEW |