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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 if (start == nullptr || end == start) { | 85 if (start == nullptr || end == start) { |
86 thrower->TypeError("ArrayBuffer argument is empty"); | 86 thrower->TypeError("ArrayBuffer argument is empty"); |
87 } | 87 } |
88 } else { | 88 } else { |
89 thrower->TypeError("Argument 0 must be an ArrayBuffer or Uint8Array"); | 89 thrower->TypeError("Argument 0 must be an ArrayBuffer or Uint8Array"); |
90 } | 90 } |
91 | 91 |
92 return {start, end}; | 92 return {start, end}; |
93 } | 93 } |
94 | 94 |
95 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
96 HandleScope scope(args.GetIsolate()); | |
97 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | |
98 ErrorThrower thrower(isolate, "Wasm.verifyModule()"); | |
99 | |
100 if (args.Length() < 1) { | |
101 thrower.TypeError("Argument 0 must be a buffer source"); | |
102 return; | |
103 } | |
104 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | |
105 if (thrower.error()) return; | |
106 | |
107 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( | |
108 isolate, buffer.start, buffer.end, true, internal::wasm::kWasmOrigin); | |
109 | |
110 if (result.failed()) { | |
111 thrower.CompileFailed("", result); | |
112 } | |
113 | |
114 if (result.val) delete result.val; | |
115 } | |
116 | |
117 void VerifyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
118 HandleScope scope(args.GetIsolate()); | |
119 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | |
120 ErrorThrower thrower(isolate, "Wasm.verifyFunction()"); | |
121 | |
122 if (args.Length() < 1) { | |
123 thrower.TypeError("Argument 0 must be a buffer source"); | |
124 return; | |
125 } | |
126 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | |
127 if (thrower.error()) return; | |
128 | |
129 internal::wasm::FunctionResult result; | |
130 { | |
131 // Verification of a single function shouldn't allocate. | |
132 i::DisallowHeapAllocation no_allocation; | |
133 i::Zone zone(isolate->allocator(), ZONE_NAME); | |
134 result = internal::wasm::DecodeWasmFunction(isolate, &zone, nullptr, | |
135 buffer.start, buffer.end); | |
136 } | |
137 | |
138 if (result.failed()) { | |
139 thrower.CompileFailed("", result); | |
140 } | |
141 | |
142 if (result.val) delete result.val; | |
143 } | |
144 | |
145 i::MaybeHandle<i::JSObject> InstantiateModule( | |
146 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, | |
147 const byte* end, ErrorThrower* thrower) { | |
148 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | |
149 | |
150 // Decode but avoid a redundant pass over function bodies for verification. | |
151 // Verification will happen during compilation. | |
152 i::Zone zone(isolate->allocator(), ZONE_NAME); | |
153 i::MaybeHandle<i::JSObject> module_object = | |
154 i::wasm::CreateModuleObjectFromBytes( | |
155 isolate, start, end, thrower, i::wasm::kWasmOrigin, | |
156 i::Handle<i::Script>::null(), nullptr, nullptr); | |
157 i::MaybeHandle<i::JSObject> object; | |
158 if (!module_object.is_null()) { | |
159 // Success. Instantiate the module and return the object. | |
160 i::Handle<i::JSObject> ffi = i::Handle<i::JSObject>::null(); | |
161 if (args.Length() > 1 && args[1]->IsObject()) { | |
162 Local<Object> obj = Local<Object>::Cast(args[1]); | |
163 ffi = i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); | |
164 } | |
165 | |
166 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | |
167 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | |
168 Local<Object> obj = Local<Object>::Cast(args[2]); | |
169 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | |
170 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | |
171 } | |
172 | |
173 object = i::wasm::WasmModule::Instantiate( | |
174 isolate, thrower, module_object.ToHandleChecked(), ffi, memory); | |
175 if (!object.is_null()) { | |
176 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); | |
177 } | |
178 } | |
179 return object; | |
180 } | |
181 | |
182 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | |
183 HandleScope scope(args.GetIsolate()); | |
184 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | |
185 ErrorThrower thrower(isolate, "Wasm.instantiateModule()"); | |
186 | |
187 if (args.Length() < 1) { | |
188 thrower.TypeError("Argument 0 must be a buffer source"); | |
189 return; | |
190 } | |
191 RawBuffer buffer = GetRawBufferSource(args[0], &thrower); | |
192 if (buffer.start == nullptr) return; | |
193 | |
194 InstantiateModule(args, buffer.start, buffer.end, &thrower); | |
195 } | |
196 | |
197 static i::MaybeHandle<i::JSObject> CreateModuleObject( | 95 static i::MaybeHandle<i::JSObject> CreateModuleObject( |
198 v8::Isolate* isolate, const v8::Local<v8::Value> source, | 96 v8::Isolate* isolate, const v8::Local<v8::Value> source, |
199 ErrorThrower* thrower) { | 97 ErrorThrower* thrower) { |
200 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); | 98 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate); |
201 i::MaybeHandle<i::JSObject> nothing; | 99 i::MaybeHandle<i::JSObject> nothing; |
202 | 100 |
203 RawBuffer buffer = GetRawBufferSource(source, thrower); | 101 RawBuffer buffer = GetRawBufferSource(source, thrower); |
204 if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>(); | 102 if (buffer.start == nullptr) return i::MaybeHandle<i::JSObject>(); |
205 | 103 |
206 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); | 104 DCHECK(source->IsArrayBuffer() || source->IsTypedArray()); |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 isolate->native_context()->wasm_runtime_error_function()); | 768 isolate->native_context()->wasm_runtime_error_function()); |
871 JSObject::AddProperty(webassembly, isolate->factory()->RuntimeError_string(), | 769 JSObject::AddProperty(webassembly, isolate->factory()->RuntimeError_string(), |
872 runtime_error, attributes); | 770 runtime_error, attributes); |
873 } | 771 } |
874 | 772 |
875 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 773 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
876 if (!FLAG_expose_wasm && !FLAG_validate_asm) { | 774 if (!FLAG_expose_wasm && !FLAG_validate_asm) { |
877 return; | 775 return; |
878 } | 776 } |
879 | 777 |
880 Factory* factory = isolate->factory(); | |
881 | |
882 // Setup wasm function map. | 778 // Setup wasm function map. |
883 Handle<Context> context(global->native_context(), isolate); | 779 Handle<Context> context(global->native_context(), isolate); |
884 InstallWasmMapsIfNeeded(isolate, context); | 780 InstallWasmMapsIfNeeded(isolate, context); |
885 | 781 |
886 if (!FLAG_expose_wasm) { | 782 if (FLAG_expose_wasm) { |
887 return; | 783 InstallWasmConstructors(isolate, global, context); |
888 } | 784 } |
889 | |
890 // Bind the experimental "Wasm" object. | |
891 // TODO(rossberg, titzer): remove once it's no longer needed. | |
892 { | |
893 Handle<String> name = v8_str(isolate, "Wasm"); | |
894 Handle<JSFunction> cons = factory->NewFunction(name); | |
895 JSFunction::SetInstancePrototype( | |
896 cons, Handle<Object>(context->initial_object_prototype(), isolate)); | |
897 cons->shared()->set_instance_class_name(*name); | |
898 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); | |
899 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | |
900 JSObject::AddProperty(global, name, wasm_object, attributes); | |
901 | |
902 // Install functions on the WASM object. | |
903 InstallFunc(isolate, wasm_object, "verifyModule", VerifyModule); | |
904 InstallFunc(isolate, wasm_object, "verifyFunction", VerifyFunction); | |
905 InstallFunc(isolate, wasm_object, "instantiateModule", InstantiateModule); | |
906 | |
907 { | |
908 // Add the Wasm.experimentalVersion property. | |
909 Handle<String> name = v8_str(isolate, "experimentalVersion"); | |
910 PropertyAttributes attributes = | |
911 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | |
912 Handle<Smi> value = | |
913 Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); | |
914 JSObject::AddProperty(wasm_object, name, value, attributes); | |
915 } | |
916 } | |
917 InstallWasmConstructors(isolate, global, context); | |
918 } | 785 } |
919 | 786 |
920 void WasmJs::InstallWasmMapsIfNeeded(Isolate* isolate, | 787 void WasmJs::InstallWasmMapsIfNeeded(Isolate* isolate, |
921 Handle<Context> context) { | 788 Handle<Context> context) { |
922 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { | 789 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { |
923 // TODO(titzer): Move this to bootstrapper.cc?? | 790 // TODO(titzer): Move this to bootstrapper.cc?? |
924 // TODO(titzer): Also make one for strict mode functions? | 791 // TODO(titzer): Also make one for strict mode functions? |
925 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); | 792 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
926 | 793 |
927 InstanceType instance_type = prev_map->instance_type(); | 794 InstanceType instance_type = prev_map->instance_type(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 if (!memory_object->IsUndefined(isolate)) { | 854 if (!memory_object->IsUndefined(isolate)) { |
988 DCHECK(IsWasmMemoryObject(isolate, memory_object)); | 855 DCHECK(IsWasmMemoryObject(isolate, memory_object)); |
989 // TODO(gdeepti): This should be a weak list of instance objects | 856 // TODO(gdeepti): This should be a weak list of instance objects |
990 // for instances that share memory. | 857 // for instances that share memory. |
991 JSObject::cast(*memory_object) | 858 JSObject::cast(*memory_object) |
992 ->SetInternalField(kWasmMemoryInstanceObject, *instance); | 859 ->SetInternalField(kWasmMemoryInstanceObject, *instance); |
993 } | 860 } |
994 } | 861 } |
995 } // namespace internal | 862 } // namespace internal |
996 } // namespace v8 | 863 } // namespace v8 |
OLD | NEW |