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 <setjmp.h> |
| 6 #include <signal.h> |
| 7 #include <stdio.h> |
| 8 |
| 9 #include <iostream> |
| 10 |
5 #include "src/api-natives.h" | 11 #include "src/api-natives.h" |
6 #include "src/api.h" | 12 #include "src/api.h" |
7 #include "src/asmjs/asm-js.h" | 13 #include "src/asmjs/asm-js.h" |
8 #include "src/asmjs/asm-typer.h" | 14 #include "src/asmjs/asm-typer.h" |
9 #include "src/asmjs/asm-wasm-builder.h" | 15 #include "src/asmjs/asm-wasm-builder.h" |
10 #include "src/assert-scope.h" | 16 #include "src/assert-scope.h" |
11 #include "src/ast/ast.h" | 17 #include "src/ast/ast.h" |
| 18 #include "src/ast/scopes.h" |
| 19 #include "src/code-stubs.h" |
12 #include "src/execution.h" | 20 #include "src/execution.h" |
13 #include "src/factory.h" | 21 #include "src/factory.h" |
14 #include "src/handles.h" | 22 #include "src/handles.h" |
15 #include "src/isolate.h" | 23 #include "src/isolate.h" |
16 #include "src/objects.h" | 24 #include "src/objects.h" |
17 #include "src/parsing/parse-info.h" | 25 #include "src/parsing/parse-info.h" |
18 | 26 |
19 #include "src/wasm/encoder.h" | 27 #include "src/wasm/encoder.h" |
20 #include "src/wasm/module-decoder.h" | 28 #include "src/wasm/module-decoder.h" |
21 #include "src/wasm/wasm-js.h" | 29 #include "src/wasm/wasm-js.h" |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 Handle<String> name = v8_str(isolate, str); | 340 Handle<String> name = v8_str(isolate, str); |
333 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); | 341 Handle<FunctionTemplateInfo> temp = NewTemplate(isolate, func); |
334 Handle<JSFunction> function = | 342 Handle<JSFunction> function = |
335 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); | 343 ApiNatives::InstantiateFunction(temp).ToHandleChecked(); |
336 PropertyAttributes attributes = | 344 PropertyAttributes attributes = |
337 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 345 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
338 JSObject::AddProperty(object, name, function, attributes); | 346 JSObject::AddProperty(object, name, function, attributes); |
339 return function; | 347 return function; |
340 } | 348 } |
341 | 349 |
| 350 static void TrapHandler(int signum, siginfo_t* info, void* arg) { |
| 351 ucontext_t* uc = reinterpret_cast<ucontext_t*>(arg); |
| 352 |
| 353 fprintf(stderr, "Return address was %p\n", |
| 354 reinterpret_cast<void*>(uc->uc_mcontext.gregs[REG_RIP])); |
| 355 |
| 356 auto fault_addr = uc->uc_mcontext.gregs[REG_RIP]; |
| 357 |
| 358 Code* code = nullptr; |
| 359 |
| 360 // Check if this is a wasm fault. |
| 361 if (nullptr == wasm::gTrapHandlers) { |
| 362 std::cerr << "No handler data" << std::endl; |
| 363 } |
| 364 for (auto* handler_data = wasm::gTrapHandlers; handler_data; |
| 365 handler_data = handler_data->next) { |
| 366 std::cerr << "Testing fault against " |
| 367 << reinterpret_cast<void*>( |
| 368 handler_data->code->instruction_start()) |
| 369 << " - " |
| 370 << reinterpret_cast<void*>(handler_data->code->instruction_end()) |
| 371 << std::endl; |
| 372 |
| 373 if (handler_data->code->contains(reinterpret_cast<byte*>(fault_addr))) { |
| 374 code = handler_data->code; |
| 375 break; |
| 376 } |
| 377 } |
| 378 |
| 379 if (nullptr != code) { |
| 380 for (RelocIterator it(code, -1); !it.done(); it.next()) { |
| 381 auto* rinfo = it.rinfo(); |
| 382 // rinfo->Print(isolate, std::cerr); |
| 383 fprintf(stderr, " = %p\n", reinterpret_cast<void*>(rinfo->data())); |
| 384 |
| 385 if (reinterpret_cast<intptr_t>(rinfo->pc()) == fault_addr) { |
| 386 auto jmp_offset = rinfo->data(); |
| 387 auto landing_addr = fault_addr + jmp_offset; |
| 388 |
| 389 uc->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<greg_t>(landing_addr); |
| 390 return; |
| 391 } |
| 392 } |
| 393 |
| 394 // So this is a weird thing. If we got here, we decided the fault |
| 395 // was in WASM code, but we couldn't find an entry in the |
| 396 // RelocInfo for its address. This is bad. |
| 397 __builtin_trap(); |
| 398 } |
| 399 |
| 400 // If we get here, it's not a wasm fault, so we go to the next handler. |
| 401 // |
| 402 // TODO(eholk): we simulate going to the next handler by trapping |
| 403 // here instead. We need to actually save the old handler and then |
| 404 // call it. |
| 405 __builtin_trap(); |
| 406 } |
| 407 |
342 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { | 408 void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) { |
343 if (!FLAG_expose_wasm && !FLAG_validate_asm) { | 409 if (!FLAG_expose_wasm && !FLAG_validate_asm) { |
344 return; | 410 return; |
345 } | 411 } |
346 | 412 |
347 Factory* factory = isolate->factory(); | 413 Factory* factory = isolate->factory(); |
348 | 414 |
349 // Setup wasm function map. | 415 // Setup wasm function map. |
350 Handle<Context> context(global->native_context(), isolate); | 416 Handle<Context> context(global->native_context(), isolate); |
351 InstallWasmFunctionMap(isolate, context); | 417 InstallWasmFunctionMap(isolate, context); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); | 470 InstallFunc(isolate, wasm_object, "Module", WebAssemblyModule); |
405 Handle<JSFunction> instance_constructor = | 471 Handle<JSFunction> instance_constructor = |
406 InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); | 472 InstallFunc(isolate, wasm_object, "Instance", WebAssemblyInstance); |
407 i::Handle<i::Map> map = isolate->factory()->NewMap( | 473 i::Handle<i::Map> map = isolate->factory()->NewMap( |
408 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize); | 474 i::JS_OBJECT_TYPE, i::JSObject::kHeaderSize + i::kPointerSize); |
409 module_constructor->set_prototype_or_initial_map(*map); | 475 module_constructor->set_prototype_or_initial_map(*map); |
410 map->SetConstructor(*module_constructor); | 476 map->SetConstructor(*module_constructor); |
411 | 477 |
412 context->set_wasm_module_constructor(*module_constructor); | 478 context->set_wasm_module_constructor(*module_constructor); |
413 context->set_wasm_instance_constructor(*instance_constructor); | 479 context->set_wasm_instance_constructor(*instance_constructor); |
| 480 |
| 481 { |
| 482 // Add the Wasm.experimentalVersion property. |
| 483 Handle<String> name = v8_str(isolate, "experimentalVersion"); |
| 484 PropertyAttributes attributes = |
| 485 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
| 486 Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate); |
| 487 JSObject::AddProperty(wasm_object, name, value, attributes); |
| 488 } |
| 489 |
| 490 { |
| 491 struct sigaction action; |
| 492 action.sa_sigaction = TrapHandler; |
| 493 action.sa_flags = SA_SIGINFO; |
| 494 sigemptyset(&action.sa_mask); |
| 495 // TODO(eholk): check the return value |
| 496 sigaction(SIGSEGV, &action, NULL); |
| 497 } |
414 } | 498 } |
415 | 499 |
416 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { | 500 void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) { |
417 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { | 501 if (!context->get(Context::WASM_FUNCTION_MAP_INDEX)->IsMap()) { |
418 // TODO(titzer): Move this to bootstrapper.cc?? | 502 // TODO(titzer): Move this to bootstrapper.cc?? |
419 // TODO(titzer): Also make one for strict mode functions? | 503 // TODO(titzer): Also make one for strict mode functions? |
420 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); | 504 Handle<Map> prev_map = Handle<Map>(context->sloppy_function_map(), isolate); |
421 | 505 |
422 InstanceType instance_type = prev_map->instance_type(); | 506 InstanceType instance_type = prev_map->instance_type(); |
423 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); | 507 int internal_fields = JSObject::GetInternalFieldCount(*prev_map); |
(...skipping 12 matching lines...) Expand all Loading... |
436 int unused_property_fields = in_object_properties - pre_allocated; | 520 int unused_property_fields = in_object_properties - pre_allocated; |
437 Handle<Map> map = Map::CopyInitialMap( | 521 Handle<Map> map = Map::CopyInitialMap( |
438 prev_map, instance_size, in_object_properties, unused_property_fields); | 522 prev_map, instance_size, in_object_properties, unused_property_fields); |
439 | 523 |
440 context->set_wasm_function_map(*map); | 524 context->set_wasm_function_map(*map); |
441 } | 525 } |
442 } | 526 } |
443 | 527 |
444 } // namespace internal | 528 } // namespace internal |
445 } // namespace v8 | 529 } // namespace v8 |
OLD | NEW |