| Index: src/wasm/wasm-js.cc
|
| diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc
|
| index 853a77f3ccaedfdb094c22b462885392812112a3..372df4056dc1304d312633fb819c445b16107452 100644
|
| --- a/src/wasm/wasm-js.cc
|
| +++ b/src/wasm/wasm-js.cc
|
| @@ -2,6 +2,12 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include <setjmp.h>
|
| +#include <signal.h>
|
| +#include <stdio.h>
|
| +
|
| +#include <iostream>
|
| +
|
| #include "src/api-natives.h"
|
| #include "src/api.h"
|
| #include "src/asmjs/asm-js.h"
|
| @@ -9,6 +15,8 @@
|
| #include "src/asmjs/asm-wasm-builder.h"
|
| #include "src/assert-scope.h"
|
| #include "src/ast/ast.h"
|
| +#include "src/ast/scopes.h"
|
| +#include "src/code-stubs.h"
|
| #include "src/execution.h"
|
| #include "src/factory.h"
|
| #include "src/handles.h"
|
| @@ -339,6 +347,64 @@ static Handle<JSFunction> InstallFunc(Isolate* isolate, Handle<JSObject> object,
|
| return function;
|
| }
|
|
|
| +static void TrapHandler(int signum, siginfo_t* info, void* arg) {
|
| + ucontext_t* uc = reinterpret_cast<ucontext_t*>(arg);
|
| +
|
| + fprintf(stderr, "Return address was %p\n",
|
| + reinterpret_cast<void*>(uc->uc_mcontext.gregs[REG_RIP]));
|
| +
|
| + auto fault_addr = uc->uc_mcontext.gregs[REG_RIP];
|
| +
|
| + Code* code = nullptr;
|
| +
|
| + // Check if this is a wasm fault.
|
| + if (nullptr == wasm::gTrapHandlers) {
|
| + std::cerr << "No handler data" << std::endl;
|
| + }
|
| + for (auto* handler_data = wasm::gTrapHandlers; handler_data;
|
| + handler_data = handler_data->next) {
|
| + std::cerr << "Testing fault against "
|
| + << reinterpret_cast<void*>(
|
| + handler_data->code->instruction_start())
|
| + << " - "
|
| + << reinterpret_cast<void*>(handler_data->code->instruction_end())
|
| + << std::endl;
|
| +
|
| + if (handler_data->code->contains(reinterpret_cast<byte*>(fault_addr))) {
|
| + code = handler_data->code;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + if (nullptr != code) {
|
| + for (RelocIterator it(code, -1); !it.done(); it.next()) {
|
| + auto* rinfo = it.rinfo();
|
| + // rinfo->Print(isolate, std::cerr);
|
| + fprintf(stderr, " = %p\n", reinterpret_cast<void*>(rinfo->data()));
|
| +
|
| + if (reinterpret_cast<intptr_t>(rinfo->pc()) == fault_addr) {
|
| + auto jmp_offset = rinfo->data();
|
| + auto landing_addr = fault_addr + jmp_offset;
|
| +
|
| + uc->uc_mcontext.gregs[REG_RIP] = reinterpret_cast<greg_t>(landing_addr);
|
| + return;
|
| + }
|
| + }
|
| +
|
| + // So this is a weird thing. If we got here, we decided the fault
|
| + // was in WASM code, but we couldn't find an entry in the
|
| + // RelocInfo for its address. This is bad.
|
| + __builtin_trap();
|
| + }
|
| +
|
| + // If we get here, it's not a wasm fault, so we go to the next handler.
|
| + //
|
| + // TODO(eholk): we simulate going to the next handler by trapping
|
| + // here instead. We need to actually save the old handler and then
|
| + // call it.
|
| + __builtin_trap();
|
| +}
|
| +
|
| void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) {
|
| if (!FLAG_expose_wasm && !FLAG_validate_asm) {
|
| return;
|
| @@ -411,6 +477,24 @@ void WasmJs::Install(Isolate* isolate, Handle<JSGlobalObject> global) {
|
|
|
| context->set_wasm_module_constructor(*module_constructor);
|
| context->set_wasm_instance_constructor(*instance_constructor);
|
| +
|
| + {
|
| + // Add the Wasm.experimentalVersion property.
|
| + Handle<String> name = v8_str(isolate, "experimentalVersion");
|
| + PropertyAttributes attributes =
|
| + static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY);
|
| + Handle<Smi> value = Handle<Smi>(Smi::FromInt(wasm::kWasmVersion), isolate);
|
| + JSObject::AddProperty(wasm_object, name, value, attributes);
|
| + }
|
| +
|
| + {
|
| + struct sigaction action;
|
| + action.sa_sigaction = TrapHandler;
|
| + action.sa_flags = SA_SIGINFO;
|
| + sigemptyset(&action.sa_mask);
|
| + // TODO(eholk): check the return value
|
| + sigaction(SIGSEGV, &action, NULL);
|
| + }
|
| }
|
|
|
| void WasmJs::InstallWasmFunctionMap(Isolate* isolate, Handle<Context> context) {
|
|
|