| 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 |