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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 | 126 |
127 i::MaybeHandle<i::JSObject> InstantiateModule( | 127 i::MaybeHandle<i::JSObject> InstantiateModule( |
128 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, | 128 const v8::FunctionCallbackInfo<v8::Value>& args, const byte* start, |
129 const byte* end, ErrorThrower* thrower, | 129 const byte* end, ErrorThrower* thrower, |
130 internal::wasm::ModuleOrigin origin = i::wasm::kWasmOrigin) { | 130 internal::wasm::ModuleOrigin origin = i::wasm::kWasmOrigin) { |
131 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 131 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
132 | 132 |
133 // Decode but avoid a redundant pass over function bodies for verification. | 133 // Decode but avoid a redundant pass over function bodies for verification. |
134 // Verification will happen during compilation. | 134 // Verification will happen during compilation. |
135 i::Zone zone(isolate->allocator()); | 135 i::Zone zone(isolate->allocator()); |
136 internal::wasm::ModuleResult result = internal::wasm::DecodeWasmModule( | 136 i::MaybeHandle<i::JSObject> module_object = |
137 isolate, &zone, start, end, false, origin); | 137 i::wasm::CreateModuleObjectFromBytes(isolate, start, end, thrower, |
138 | 138 origin); |
139 i::MaybeHandle<i::JSObject> object; | 139 i::MaybeHandle<i::JSObject> object; |
140 if (result.failed()) { | 140 if (!module_object.is_null()) { |
141 thrower->Failed("", result); | |
142 } else { | |
143 // Success. Instantiate the module and return the object. | 141 // Success. Instantiate the module and return the object. |
144 i::Handle<i::JSObject> ffi = i::Handle<i::JSObject>::null(); | 142 i::Handle<i::JSObject> ffi = i::Handle<i::JSObject>::null(); |
145 if (args.Length() > 1 && args[1]->IsObject()) { | 143 if (args.Length() > 1 && args[1]->IsObject()) { |
146 Local<Object> obj = Local<Object>::Cast(args[1]); | 144 Local<Object> obj = Local<Object>::Cast(args[1]); |
147 ffi = i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); | 145 ffi = i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); |
148 } | 146 } |
149 | 147 |
150 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 148 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
151 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | 149 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { |
152 Local<Object> obj = Local<Object>::Cast(args[2]); | 150 Local<Object> obj = Local<Object>::Cast(args[2]); |
153 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | 151 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
154 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | 152 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); |
155 } | 153 } |
156 | 154 |
157 i::MaybeHandle<i::FixedArray> compiled_module = | 155 object = i::wasm::WasmModule::Instantiate( |
158 result.val->CompileFunctions(isolate, thrower); | 156 isolate, module_object.ToHandleChecked(), ffi, memory); |
159 if (!thrower->error()) { | 157 if (!object.is_null()) { |
160 DCHECK(!compiled_module.is_null()); | 158 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); |
161 object = i::wasm::WasmModule::Instantiate( | |
162 isolate, compiled_module.ToHandleChecked(), ffi, memory); | |
163 if (!object.is_null()) { | |
164 args.GetReturnValue().Set(v8::Utils::ToLocal(object.ToHandleChecked())); | |
165 } | |
166 } | 159 } |
167 } | 160 } |
168 | |
169 if (result.val) delete result.val; | |
170 return object; | 161 return object; |
171 } | 162 } |
172 | 163 |
173 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { | 164 void InstantiateModule(const v8::FunctionCallbackInfo<v8::Value>& args) { |
174 HandleScope scope(args.GetIsolate()); | 165 HandleScope scope(args.GetIsolate()); |
175 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); | 166 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(args.GetIsolate()); |
176 ErrorThrower thrower(isolate, "Wasm.instantiateModule()"); | 167 ErrorThrower thrower(isolate, "Wasm.instantiateModule()"); |
177 | 168 |
178 if (args.Length() < 1) { | 169 if (args.Length() < 1) { |
179 thrower.Error("Argument 0 must be a buffer source"); | 170 thrower.Error("Argument 0 must be a buffer source"); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
269 Local<Object> obj = Local<Object>::Cast(args[0]); | 260 Local<Object> obj = Local<Object>::Cast(args[0]); |
270 | 261 |
271 i::Handle<i::JSObject> module_obj = | 262 i::Handle<i::JSObject> module_obj = |
272 i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); | 263 i::Handle<i::JSObject>::cast(v8::Utils::OpenHandle(*obj)); |
273 if (module_obj->GetInternalFieldCount() < 1 || | 264 if (module_obj->GetInternalFieldCount() < 1 || |
274 !module_obj->GetInternalField(0)->IsFixedArray()) { | 265 !module_obj->GetInternalField(0)->IsFixedArray()) { |
275 thrower.Error("Argument 0 is an invalid WebAssembly.Module"); | 266 thrower.Error("Argument 0 is an invalid WebAssembly.Module"); |
276 return; | 267 return; |
277 } | 268 } |
278 | 269 |
279 i::Handle<i::FixedArray> compiled_code = i::Handle<i::FixedArray>( | |
280 i::FixedArray::cast(module_obj->GetInternalField(0))); | |
281 | |
282 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); | 270 i::Handle<i::JSReceiver> ffi = i::Handle<i::JSObject>::null(); |
283 if (args.Length() > 1 && args[1]->IsObject()) { | 271 if (args.Length() > 1 && args[1]->IsObject()) { |
284 Local<Object> obj = Local<Object>::Cast(args[1]); | 272 Local<Object> obj = Local<Object>::Cast(args[1]); |
285 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); | 273 ffi = i::Handle<i::JSReceiver>::cast(v8::Utils::OpenHandle(*obj)); |
286 } | 274 } |
287 | 275 |
288 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); | 276 i::Handle<i::JSArrayBuffer> memory = i::Handle<i::JSArrayBuffer>::null(); |
289 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { | 277 if (args.Length() > 2 && args[2]->IsArrayBuffer()) { |
290 Local<Object> obj = Local<Object>::Cast(args[2]); | 278 Local<Object> obj = Local<Object>::Cast(args[2]); |
291 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); | 279 i::Handle<i::Object> mem_obj = v8::Utils::OpenHandle(*obj); |
292 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); | 280 memory = i::Handle<i::JSArrayBuffer>(i::JSArrayBuffer::cast(*mem_obj)); |
293 } | 281 } |
294 i::MaybeHandle<i::JSObject> instance = | 282 i::MaybeHandle<i::JSObject> instance = |
295 i::wasm::WasmModule::Instantiate(i_isolate, compiled_code, ffi, memory); | 283 i::wasm::WasmModule::Instantiate(i_isolate, module_obj, ffi, memory); |
296 if (instance.is_null()) { | 284 if (instance.is_null()) { |
297 thrower.Error("Could not instantiate module"); | 285 thrower.Error("Could not instantiate module"); |
298 return; | 286 return; |
299 } | 287 } |
300 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); | 288 v8::ReturnValue<v8::Value> return_value = args.GetReturnValue(); |
301 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); | 289 return_value.Set(Utils::ToLocal(instance.ToHandleChecked())); |
302 } | 290 } |
303 } // namespace | 291 } // namespace |
304 | 292 |
305 // TODO(titzer): we use the API to create the function template because the | 293 // TODO(titzer): we use the API to create the function template because the |
(...skipping 15 matching lines...) Expand all Loading... |
321 Handle<String> name = v8_str(isolate, str); | 309 Handle<String> name = v8_str(isolate, str); |
322 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); | 310 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
323 Handle<JSFunction> function = | 311 Handle<JSFunction> function = |
324 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 312 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
325 PropertyAttributes attributes = | 313 PropertyAttributes attributes = |
326 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 314 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
327 JSObject::AddProperty(object, name, function, attributes); | 315 JSObject::AddProperty(object, name, function, attributes); |
328 return function; | 316 return function; |
329 } | 317 } |
330 | 318 |
| 319 void WasmJs::SetupIsolateForWasm(Isolate* isolate) { |
| 320 InstallWasmFunctionMap(isolate, isolate->native_context()); |
| 321 InstallWasmModuleSymbol(isolate, isolate->global_object(), |
| 322 isolate->native_context()); |
| 323 } |
| 324 |
| 325 void WasmJs::InstallWasmModuleSymbol(Isolate* isolate, |
| 326 Handle<JSGlobalObject> global, |
| 327 Handle<Context> context) { |
| 328 Factory* factory = isolate->factory(); |
| 329 // Create private symbols. |
| 330 Handle<Symbol> module_sym = factory->NewPrivateSymbol(); |
| 331 Handle<Symbol> instance_sym = factory->NewPrivateSymbol(); |
| 332 context->set_wasm_module_sym(*module_sym); |
| 333 context->set_wasm_instance_sym(*instance_sym); |
| 334 |
| 335 // Bind the WebAssembly object. |
| 336 Handle<String> name = v8_str(isolate, "WebAssembly"); |
| 337 Handle<JSFunction> cons = factory->NewFunction(name); |
| 338 JSFunction::SetInstancePrototype( |
| 339 cons, Handle<Object>(context->initial_object_prototype(), isolate)); |
| 340 cons->shared()->set_instance_class_name(*name); |
| 341 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); |
| 342 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); |
| 343 JSObject::AddProperty(global, name, wasm_object, attributes); |
| 344 |
| 345 // Install static methods on WebAssembly object. |
| 346 InstallFunc(isolate, wasm_object, "compile", WebAssemblyCompile); |
| 347 Handle<JSFunction> module_constructor = |
| 348 InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); |
| 349 Handle<JSFunction> instance_constructor = |
| 350 InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); |
| 351 i::Handle<i::Map> map = isolate->factory()->NewMap( |
| 352 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize); |
| 353 module_constructor->set_prototype_or_initial_map(*map); |
| 354 map->SetConstructor(*module_constructor); |
| 355 |
| 356 context->set_wasm_module_constructor(*module_constructor); |
| 357 context->set_wasm_instance_constructor(*instance_constructor); |
| 358 } |
| 359 |
331 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 360 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
332 if (!FLAG_expose_wasm && !FLAG_validate_asm) { | 361 if (!FLAG_expose_wasm && !FLAG_validate_asm) { |
333 return; | 362 return; |
334 } | 363 } |
335 | 364 |
336 Factory* factory = isolate->factory(); | 365 Factory* factory = isolate->factory(); |
337 | 366 |
338 // Setup wasm function map. | 367 // Setup wasm function map. |
339 Handle<Context> context(global->native_context(), isolate); | 368 Handle<Context> context(global->native_context(), isolate); |
340 InstallWasmFunctionMap(isolate, context); | 369 InstallWasmFunctionMap(isolate, context); |
(...skipping 22 matching lines...) Expand all Loading... |
363 { | 392 { |
364 // Add the Wasm.experimentalVersion property. | 393 // Add the Wasm.experimentalVersion property. |
365 Handle<String> name = v8_str(isolate, "experimentalVersion"); | 394 Handle<String> name = v8_str(isolate, "experimentalVersion"); |
366 PropertyAttributes attributes = | 395 PropertyAttributes attributes = |
367 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 396 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
368 Handle<Smi> value = | 397 Handle<Smi> value = |
369 Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); | 398 Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); |
370 JSObject::AddProperty(wasm_object, name, value, attributes); | 399 JSObject::AddProperty(wasm_object, name, value, attributes); |
371 } | 400 } |
372 } | 401 } |
373 | 402 InstallWasmModuleSymbol(isolate, global, context); |
374 // Create private symbols. | |
375 Handle<Symbol> module_sym = isolate->factory()->NewPrivateSymbol(); | |
376 Handle<Symbol> instance_sym = isolate->factory()->NewPrivateSymbol(); | |
377 context->set_wasm_module_sym(*module_sym); | |
378 context->set_wasm_instance_sym(*instance_sym); | |
379 | |
380 // Bind the WebAssembly object. | |
381 Handle<String> name = v8_str(isolate, "WebAssembly"); | |
382 Handle<JSFunction> cons = factory->NewFunction(name); | |
383 JSFunction::SetInstancePrototype( | |
384 cons, Handle<Object>(context->initial_object_prototype(), isolate)); | |
385 cons->shared()->set_instance_class_name(*name); | |
386 Handle<JSObject> wasm_object = factory->NewJSObject(cons, TENURED); | |
387 PropertyAttributes attributes = static_cast<PropertyAttributes>(DONT_ENUM); | |
388 JSObject::AddProperty(global, name, wasm_object, attributes); | |
389 | |
390 // Install static methods on WebAssembly object. | |
391 InstallFunc(isolate, wasm_object, "compile", WebAssemblyCompile); | |
392 Handle<JSFunction> module_constructor = | |
393 InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); | |
394 Handle<JSFunction> instance_constructor = | |
395 InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); | |
396 i::Handle<i::Map> map = isolate->factory()->NewMap( | |
397 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize); | |
398 module_constructor->set_prototype_or_initial_map(*map); | |
399 map->SetConstructor(*module_constructor); | |
400 | |
401 context->set_wasm_module_constructor(*module_constructor); | |
402 context->set_wasm_instance_constructor(*instance_constructor); | |
403 } | 403 } |
404 | 404 |
405 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { | 405 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { |
406 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { | 406 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { |
407 // TODO(titzer): Move this to bootstrapper.cc?? | 407 // TODO(titzer): Move this to bootstrapper.cc?? |
408 // TODO(titzer): Also make one for strict mode functions? | 408 // TODO(titzer): Also make one for strict mode functions? |
409 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); | 409 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
410 | 410 |
411 InstanceType instance_type = prev_map->instance_type(); | 411 InstanceType instance_type = prev_map->instance_type(); |
412 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); | 412 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
(...skipping 12 matching lines...) Expand all Loading... |
425 int unused_property_fields = in_object_properties - pre_allocated; | 425 int unused_property_fields = in_object_properties - pre_allocated; |
426 Handle<Map> map = Map::CopyInitialMap( | 426 Handle<Map> map = Map::CopyInitialMap( |
427 prev_map, instance_size, in_object_properties, unused_property_fields); | 427 prev_map, instance_size, in_object_properties, unused_property_fields); |
428 | 428 |
429 context->set_wasm_function_map(*map); | 429 context->set_wasm_function_map(*map); |
430 } | 430 } |
431 } | 431 } |
432 | 432 |
433 } // namespace internal | 433 } // namespace internal |
434 } // namespace v8 | 434 } // namespace v8 |
OLD | NEW |