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/assert-scope.h" | 7 #include "src/assert-scope.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
10 #include "src/execution.h" | 10 #include "src/execution.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 if (start == nullptr || end == start) { | 70 if (start == nullptr || end == start) { |
71 thrower.Error("ArrayBuffer argument is empty"); | 71 thrower.Error("ArrayBuffer argument is empty"); |
72 } | 72 } |
73 } else { | 73 } else { |
74 thrower.Error("Argument 0 must be an ArrayBuffer or Uint8Array"); | 74 thrower.Error("Argument 0 must be an ArrayBuffer or Uint8Array"); |
75 } | 75 } |
76 | 76 |
77 return {start, end}; | 77 return {start, end}; |
78 } | 78 } |
79 | 79 |
| 80 i::Handle<i::JSArrayBuffer> GetMemoryArgument( |
| 81 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 82 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
| 83 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { |
| 84 Local<Object> obj = Local<Object>::Cast(args[2]); |
| 85 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
| 86 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); |
| 87 } |
| 88 return memory; |
| 89 } |
| 90 |
| 91 i::Handle<i::JSObject> GetForeignArgument( |
| 92 const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 93 i::Handle<i::JSObject> foreign; |
| 94 if (args.Length() > 1 && args[1]->IsObject()) { |
| 95 Local<Object> local_foreign = Local<Object>::Cast(args[1]); |
| 96 i::Handle<i::Object> foreign_obj = v8::Utils::OpenHandle(*local_foreign); |
| 97 foreign = i::Handle<i::JSObject>(i::JSObject::cast(*foreign_obj)); |
| 98 } |
| 99 return foreign; |
| 100 } |
| 101 |
80 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 102 void VerifyModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
81 HandleScope scope(args.GetIsolate()); | 103 HandleScope scope(args.GetIsolate()); |
82 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 104 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
83 ErrorThrower thrower(isolate, "WASM.verifyModule()"); | 105 ErrorThrower thrower(isolate, "WASM.verifyModule()"); |
84 | 106 |
85 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 107 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
86 if (thrower.error()) return; | 108 if (thrower.error()) return; |
87 | 109 |
88 i::Zone zone(isolate->allocator()); | 110 i::Zone zone(isolate->allocator()); |
89 internal::wasm::ModuleResult result = | 111 internal::wasm::ModuleResult result = |
(...skipping 24 matching lines...) Expand all Loading... |
114 buffer.start, buffer.end); | 136 buffer.start, buffer.end); |
115 } | 137 } |
116 | 138 |
117 if (result.failed()) { | 139 if (result.failed()) { |
118 thrower.Failed("", result); | 140 thrower.Failed("", result); |
119 } | 141 } |
120 | 142 |
121 if (result.val) delete result.val; | 143 if (result.val) delete result.val; |
122 } | 144 } |
123 | 145 |
124 v8::internal::wasm::ZoneBuffer* TranslateAsmModule( | 146 static bool ParseAsmModule(i::ParseInfo* info, ErrorThrower* thrower) { |
125 i::ParseInfo* info, ErrorThrower* thrower, | |
126 i::Handle<i::FixedArray>* foreign_args) { | |
127 info->set_global(); | 147 info->set_global(); |
128 info->set_lazy(false); | 148 info->set_lazy(false); |
129 info->set_allow_lazy_parsing(false); | 149 info->set_allow_lazy_parsing(false); |
130 info->set_toplevel(true); | 150 info->set_toplevel(true); |
131 | 151 |
132 if (!i::Compiler::ParseAndAnalyze(info)) { | 152 if (!i::Compiler::ParseAndAnalyze(info)) { |
133 return nullptr; | 153 return false; |
134 } | 154 } |
135 | 155 |
136 if (info->scope()->declarations()->length() == 0) { | 156 if (info->scope()->declarations()->length() == 0) { |
137 thrower->Error("Asm.js validation failed: no declarations in scope"); | 157 thrower->Error("Asm.js validation failed: no declarations in scope"); |
138 return nullptr; | 158 return false; |
139 } | 159 } |
140 | 160 |
141 info->set_literal( | 161 info->set_literal( |
142 info->scope()->declarations()->at(0)->AsFunctionDeclaration()->fun()); | 162 info->scope()->declarations()->at(0)->AsFunctionDeclaration()->fun()); |
143 | 163 return true; |
144 v8::internal::AsmTyper typer(info->isolate(), info->zone(), *(info->script()), | |
145 info->literal()); | |
146 if (i::FLAG_enable_simd_asmjs) { | |
147 typer.set_allow_simd(true); | |
148 } | |
149 if (!typer.Validate()) { | |
150 thrower->Error("Asm.js validation failed: %s", typer.error_message()); | |
151 return nullptr; | |
152 } | |
153 | |
154 v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), | |
155 info->literal(), &typer); | |
156 | |
157 return builder.Run(foreign_args); | |
158 } | 164 } |
159 | 165 |
160 i::MaybeHandle<i::JSObject> InstantiateModuleCommon( | 166 i::MaybeHandle<i::JSObject> InstantiateModuleCommon( |
161 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, | 167 i::Isolate* isolate, i::Handle<i::JSArrayBuffer> memory, |
162 const byte* end, ErrorThrower* thrower, | 168 i::Handle<i::JSObject> foreign, const byte* start, const byte* end, |
163 internal::wasm::ModuleOrigin origin) { | 169 ErrorThrower* thrower, internal::wasm::ModuleOrigin origin) { |
164 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | |
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 // Decode but avoid a redundant pass over function bodies for verification. | 170 // Decode but avoid a redundant pass over function bodies for verification. |
174 // Verification will happen during compilation. | 171 // Verification will happen during compilation. |
175 i::Zone zone(isolate->allocator()); | 172 i::Zone zone(isolate->allocator()); |
176 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( | 173 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( |
177 isolate, &zone, start, end, false, origin); | 174 isolate, &zone, start, end, false, origin); |
178 | 175 |
179 i::MaybeHandle<i::JSObject> object; | 176 i::MaybeHandle<i::JSObject> object; |
180 if (result.failed() && origin == internal::wasm::kAsmJsOrigin) { | 177 if (result.failed() && origin == internal::wasm::kAsmJsOrigin) { |
181 thrower->Error("Asm.js converted module failed to decode"); | 178 thrower->Error("Asm.js converted module failed to decode"); |
182 } else if (result.failed()) { | 179 } else if (result.failed()) { |
183 thrower->Failed("", result); | 180 thrower->Failed("", result); |
184 } else { | 181 } else { |
185 // Success. Instantiate the module and return the object. | 182 // Success. Instantiate the module and return the object. |
186 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); | 183 object = result.val->Instantiate(isolate, foreign, memory); |
187 if (args.Length() > 1 && args[1]->IsObject()) { | |
188 Local<Object> obj = Local<Object>::Cast(args[1]); | |
189 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | |
190 } | |
191 | |
192 object = result.val->Instantiate(isolate, ffi, memory); | |
193 | |
194 if (!object.is_null()) { | |
195 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); | |
196 } | |
197 } | 184 } |
198 | 185 |
199 if (result.val) delete result.val; | 186 if (result.val) delete result.val; |
200 return object; | 187 return object; |
201 } | 188 } |
202 | 189 |
203 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { | 190 void InstantiateModuleFromAsm(const v8::FunctionCallbackInfo<v8::Value>& args) { |
204 HandleScope scope(args.GetIsolate()); | 191 HandleScope scope(args.GetIsolate()); |
205 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 192 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
206 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); | 193 ErrorThrower thrower(isolate, "WASM.instantiateModuleFromAsm()"); |
207 | 194 |
208 if (!args[0]->IsString()) { | 195 if (!args[0]->IsString()) { |
209 thrower.Error("Asm module text should be a string"); | 196 thrower.Error("Asm module text should be a string"); |
210 return; | 197 return; |
211 } | 198 } |
212 | 199 |
| 200 i::Handle<i::JSArrayBuffer> memory = GetMemoryArgument(args); |
| 201 i::Handle<i::JSObject> foreign = GetForeignArgument(args); |
| 202 |
213 i::Factory* factory = isolate->factory(); | 203 i::Factory* factory = isolate->factory(); |
214 i::Zone zone(isolate->allocator()); | 204 i::Zone zone(isolate->allocator()); |
215 Local<String> source = Local<String>::Cast(args[0]); | 205 Local<String> source = Local<String>::Cast(args[0]); |
216 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); | 206 i::Handle<i::Script> script = factory->NewScript(Utils::OpenHandle(*source)); |
217 i::ParseInfo info(&zone, script); | 207 i::ParseInfo info(&zone, script); |
218 | 208 |
219 i::Handle<i::Object> foreign; | 209 if (!ParseAsmModule(&info, &thrower)) { |
220 if (args.Length() > 1 && args[1]->IsObject()) { | |
221 Local<Object> local_foreign = Local<Object>::Cast(args[1]); | |
222 foreign = v8::Utils::OpenHandle(*local_foreign); | |
223 } | |
224 | |
225 i::Handle<i::FixedArray> foreign_args; | |
226 auto module = TranslateAsmModule(&info, &thrower, &foreign_args); | |
227 if (module == nullptr) { | |
228 return; | 210 return; |
229 } | 211 } |
230 | 212 |
231 i::MaybeHandle<i::Object> maybe_module_object = | 213 i::Handle<i::FixedArray> wasm_data; |
232 InstantiateModuleCommon(args, module->begin(), module->end(), &thrower, | 214 if (!i::WasmJs::ConvertAsmToWasm(&info, &wasm_data)) { |
233 internal::wasm::kAsmJsOrigin); | 215 thrower.Error("Asm.js failed to validate"); |
234 if (maybe_module_object.is_null()) { | |
235 return; | 216 return; |
236 } | 217 } |
237 | 218 |
238 i::Handle<i::Name> name = | 219 i::Handle<i::Object> result; |
239 factory->NewStringFromStaticChars("__foreign_init__"); | 220 if (!i::WasmJs::InstantiateAsmWasm(isolate, wasm_data, memory, foreign, |
| 221 &result)) { |
| 222 thrower.Error("Unabled to instiate Asm.js"); |
| 223 return; |
| 224 } |
240 | 225 |
241 i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked(); | 226 if (!result.is_null()) { |
242 i::MaybeHandle<i::Object> maybe_init = | 227 args.GetReturnValue().Set(v8::Utils::ToLocal(result)); |
243 i::Object::GetProperty(module_object, name); | |
244 DCHECK(!maybe_init.is_null()); | |
245 | |
246 i::Handle<i::Object> init = maybe_init.ToHandleChecked(); | |
247 i::Handle<i::Object> undefined = isolate->factory()->undefined_value(); | |
248 i::Handle<i::Object>* foreign_args_array = | |
249 new i::Handle<i::Object>[foreign_args->length()]; | |
250 for (int j = 0; j < foreign_args->length(); j++) { | |
251 if (!foreign.is_null()) { | |
252 i::MaybeHandle<i::Name> name = i::Object::ToName( | |
253 isolate, i::Handle<i::Object>(foreign_args->get(j), isolate)); | |
254 if (!name.is_null()) { | |
255 i::MaybeHandle<i::Object> val = | |
256 i::Object::GetProperty(foreign, name.ToHandleChecked()); | |
257 if (!val.is_null()) { | |
258 foreign_args_array[j] = val.ToHandleChecked(); | |
259 continue; | |
260 } | |
261 } | |
262 } | |
263 foreign_args_array[j] = undefined; | |
264 } | |
265 i::MaybeHandle<i::Object> retval = i::Execution::Call( | |
266 isolate, init, undefined, foreign_args->length(), foreign_args_array); | |
267 delete[] foreign_args_array; | |
268 | |
269 if (retval.is_null()) { | |
270 thrower.Error( | |
271 "WASM.instantiateModuleFromAsm(): foreign init function failed"); | |
272 } | 228 } |
273 } | 229 } |
274 | 230 |
275 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 231 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
276 HandleScope scope(args.GetIsolate()); | 232 HandleScope scope(args.GetIsolate()); |
277 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 233 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
278 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); | 234 ErrorThrower thrower(isolate, "WASM.instantiateModule()"); |
279 | 235 |
280 RawBuffer buffer = GetRawBufferArgument(thrower, args); | 236 RawBuffer buffer = GetRawBufferArgument(thrower, args); |
281 if (buffer.start == nullptr) return; | 237 if (buffer.start == nullptr) return; |
282 | 238 |
283 InstantiateModuleCommon(args, buffer.start, buffer.end, &thrower, | 239 i::Handle<i::JSArrayBuffer> memory = GetMemoryArgument(args); |
284 internal::wasm::kWasmOrigin); | 240 i::Handle<i::JSObject> foreign = GetForeignArgument(args); |
| 241 |
| 242 i::MaybeHandle<i::Object> result = InstantiateModuleCommon( |
| 243 isolate, memory, foreign, buffer.start, buffer.end, &thrower, |
| 244 internal::wasm::kWasmOrigin); |
| 245 |
| 246 if (!result.is_null()) { |
| 247 args.GetReturnValue().Set(v8::Utils::ToLocal(result.ToHandleChecked())); |
| 248 } |
285 } | 249 } |
286 } // namespace | 250 } // namespace |
287 | 251 |
288 // TODO(titzer): we use the API to create the function template because the | 252 // TODO(titzer): we use the API to create the function template because the |
289 // internal guts are too ugly to replicate here. | 253 // internal guts are too ugly to replicate here. |
290 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, | 254 static i::Handle<i::FunctionTemplateInfo> NewTemplate(i::Isolate* i_isolate, |
291 FunctionCallback func) { | 255 FunctionCallback func) { |
292 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); | 256 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate); |
293 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); | 257 Local<FunctionTemplate> local = FunctionTemplate::New(isolate, func); |
294 return v8::Utils::OpenHandle(*local); | 258 return v8::Utils::OpenHandle(*local); |
295 } | 259 } |
296 | 260 |
297 namespace internal { | 261 namespace internal { |
298 static Handle<String> v8_str(Isolate* isolate, const char* str) { | 262 static Handle<String> v8_str(Isolate* isolate, const char* str) { |
299 return isolate->factory()->NewStringFromAsciiChecked(str); | 263 return isolate->factory()->NewStringFromAsciiChecked(str); |
300 } | 264 } |
301 | 265 |
302 static void InstallFunc(Isolate* isolate, Handle<JSObject> object, | 266 static void InstallFunc(Isolate* isolate, Handle<JSObject> object, |
303 const char* str, FunctionCallback func) { | 267 const char* str, FunctionCallback func) { |
304 Handle<String> name = v8_str(isolate, str); | 268 Handle<String> name = v8_str(isolate, str); |
305 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); | 269 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
306 Handle<JSFunction> function = | 270 Handle<JSFunction> function = |
307 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 271 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
308 PropertyAttributes attributes = | 272 PropertyAttributes attributes = |
309 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 273 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
310 JSObject::AddProperty(object, name, function, attributes); | 274 JSObject::AddProperty(object, name, function, attributes); |
311 } | 275 } |
312 | 276 |
313 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 277 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
| 278 if (!FLAG_expose_wasm && !FLAG_validate_asm) { |
| 279 return; |
| 280 } |
| 281 |
314 // Setup wasm function map. | 282 // Setup wasm function map. |
315 Handle<Context> context(global->native_context(), isolate); | 283 Handle<Context> context(global->native_context(), isolate); |
316 InstallWasmFunctionMap(isolate, context); | 284 InstallWasmFunctionMap(isolate, context); |
317 | 285 |
| 286 if (!FLAG_expose_wasm) { |
| 287 return; |
| 288 } |
| 289 |
318 // Bind the WASM object. | 290 // Bind the WASM object. |
319 Factory* factory = isolate->factory(); | 291 Factory* factory = isolate->factory(); |
320 Handle<String> name = v8_str(isolate, "Wasm"); | 292 Handle<String> name = v8_str(isolate, "Wasm"); |
321 Handle<JSFunction> cons = factory->NewFunction(name); | 293 Handle<JSFunction> cons = factory->NewFunction(name); |
322 JSFunction::SetInstancePrototype( | 294 JSFunction::SetInstancePrototype( |
323 cons, Handle<Object>(context->initial_object_prototype(), isolate)); | 295 cons, Handle<Object>(context->initial_object_prototype(), isolate)); |
324 cons->shared()->set_instance_class_name(*name); | 296 cons->shared()->set_instance_class_name(*name); |
325 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); | 297 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); |
326 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | 298 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
327 JSObject::AddProperty(global, name, wasm_object, attributes); | 299 JSObject::AddProperty(global, name, wasm_object, attributes); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
361 &in_object_properties); | 333 &in_object_properties); |
362 | 334 |
363 int unused_property_fields = in_object_properties - pre_allocated; | 335 int unused_property_fields = in_object_properties - pre_allocated; |
364 Handle<Map> map = Map::CopyInitialMap( | 336 Handle<Map> map = Map::CopyInitialMap( |
365 prev_map, instance_size, in_object_properties, unused_property_fields); | 337 prev_map, instance_size, in_object_properties, unused_property_fields); |
366 | 338 |
367 context->set_wasm_function_map(*map); | 339 context->set_wasm_function_map(*map); |
368 } | 340 } |
369 } | 341 } |
370 | 342 |
| 343 bool WasmJs::ConvertAsmToWasm(ParseInfo* info, Handle<FixedArray>* wasm_data) { |
| 344 ErrorThrower thrower(info->isolate(), "Asm.js -> WebAssembly conversion"); |
| 345 AsmTyper typer(info->isolate(), info->zone(), *(info->script()), |
| 346 info->literal()); |
| 347 if (i::FLAG_enable_simd_asmjs) { |
| 348 typer.set_allow_simd(true); |
| 349 } |
| 350 if (!typer.Validate()) { |
| 351 DCHECK(!info->isolate()->has_pending_exception()); |
| 352 PrintF("Validation of asm.js module failed: %s", typer.error_message()); |
| 353 return false; |
| 354 } |
| 355 v8::internal::wasm::AsmWasmBuilder builder(info->isolate(), info->zone(), |
| 356 info->literal(), &typer); |
| 357 i::Handle<i::FixedArray> foreign_globals; |
| 358 auto module = builder.Run(&foreign_globals); |
| 359 size_t byte_length = module->end() - module->begin(); |
| 360 Handle<JSArrayBuffer> buffer = info->isolate()->factory()->NewJSArrayBuffer(); |
| 361 JSArrayBuffer::SetupAllocatingData(buffer, info->isolate(), byte_length, |
| 362 false, SharedFlag::kNotShared); |
| 363 uint8_t* module_bytes = reinterpret_cast<uint8_t*>(buffer->backing_store()); |
| 364 memcpy(module_bytes, module->begin(), byte_length); |
| 365 *wasm_data = info->isolate()->factory()->NewFixedArray(2); |
| 366 (*wasm_data)->set(0, *buffer); |
| 367 (*wasm_data)->set(1, *foreign_globals); |
| 368 return true; |
| 369 } |
| 370 |
| 371 bool WasmJs::InstantiateAsmWasm(i::Isolate* isolate, |
| 372 Handle<FixedArray> wasm_data, |
| 373 Handle<JSArrayBuffer> memory, |
| 374 Handle<JSObject> foreign, |
| 375 Handle<Object>* result) { |
| 376 i::Handle<i::JSArrayBuffer> module_bytes( |
| 377 i::JSArrayBuffer::cast(wasm_data->get(0))); |
| 378 i::Handle<i::FixedArray> foreign_globals( |
| 379 i::FixedArray::cast(wasm_data->get(1))); |
| 380 |
| 381 ErrorThrower thrower(isolate, "Asm.js -> WebAssembly instantiation"); |
| 382 i::Factory* factory = isolate->factory(); |
| 383 |
| 384 const byte* module_start = |
| 385 reinterpret_cast<const byte*>(module_bytes->backing_store()); |
| 386 size_t module_length = |
| 387 static_cast<size_t>(module_bytes->byte_length()->Number()); |
| 388 const byte* module_end = module_start + module_length; |
| 389 i::MaybeHandle<i::JSObject> maybe_module_object = InstantiateModuleCommon( |
| 390 isolate, memory, foreign, module_start, module_end, &thrower, |
| 391 internal::wasm::kAsmJsOrigin); |
| 392 if (maybe_module_object.is_null()) { |
| 393 return false; |
| 394 } |
| 395 |
| 396 i::Handle<i::Name> name = |
| 397 factory->NewStringFromStaticChars("__foreign_init__"); |
| 398 |
| 399 i::Handle<i::Object> module_object = maybe_module_object.ToHandleChecked(); |
| 400 i::MaybeHandle<i::Object> maybe_init = |
| 401 i::Object::GetProperty(module_object, name); |
| 402 DCHECK(!maybe_init.is_null()); |
| 403 |
| 404 i::Handle<i::Object> init = maybe_init.ToHandleChecked(); |
| 405 i::Handle<i::Object> undefined(isolate->heap()->undefined_value(), isolate); |
| 406 i::Handle<i::Object>* foreign_args_array = |
| 407 new i::Handle<i::Object>[foreign_globals->length()]; |
| 408 for (int j = 0; j < foreign_globals->length(); j++) { |
| 409 if (!foreign.is_null()) { |
| 410 i::MaybeHandle<i::Name> name = i::Object::ToName( |
| 411 isolate, i::Handle<i::Object>(foreign_globals->get(j), isolate)); |
| 412 if (!name.is_null()) { |
| 413 i::MaybeHandle<i::Object> val = |
| 414 i::Object::GetProperty(foreign, name.ToHandleChecked()); |
| 415 if (!val.is_null()) { |
| 416 foreign_args_array[j] = val.ToHandleChecked(); |
| 417 continue; |
| 418 } |
| 419 } |
| 420 } |
| 421 foreign_args_array[j] = undefined; |
| 422 } |
| 423 i::MaybeHandle<i::Object> retval = i::Execution::Call( |
| 424 isolate, init, undefined, foreign_globals->length(), foreign_args_array); |
| 425 delete[] foreign_args_array; |
| 426 |
| 427 if (retval.is_null()) { |
| 428 thrower.Error( |
| 429 "WASM.instantiateModuleFromAsm(): foreign init function failed"); |
| 430 return false; |
| 431 } else { |
| 432 *result = maybe_module_object.ToHandleChecked(); |
| 433 } |
| 434 |
| 435 return true; |
| 436 } |
| 437 |
371 } // namespace internal | 438 } // namespace internal |
372 } // namespace v8 | 439 } // namespace v8 |
OLD | NEW |