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