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 |