Commit ad9ead76 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[wasm][interpreter] Support indirect function calls through all tables

R=clemensh@chromium.org

Bug: v8:7581
Change-Id: I6fd538f2e90bf5a4addcfe7d8f4b427850ac6fca
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1690960
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62596}
parent c1c6e3ed
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "src/wasm/wasm-module.h" #include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h" #include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-objects.h"
#include "src/zone/accounting-allocator.h" #include "src/zone/accounting-allocator.h"
#include "src/zone/zone-containers.h" #include "src/zone/zone-containers.h"
...@@ -3041,11 +3042,9 @@ class ThreadImpl { ...@@ -3041,11 +3042,9 @@ class ThreadImpl {
CallIndirectImmediate<Decoder::kNoValidate> imm( CallIndirectImmediate<Decoder::kNoValidate> imm(
kAllWasmFeatures, &decoder, code->at(pc)); kAllWasmFeatures, &decoder, code->at(pc));
uint32_t entry_index = Pop().to<uint32_t>(); uint32_t entry_index = Pop().to<uint32_t>();
// Assume only one table for now.
DCHECK_LE(module()->tables.size(), 1u);
CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC. CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC.
ExternalCallResult result = ExternalCallResult result =
CallIndirectFunction(0, entry_index, imm.sig_index); CallIndirectFunction(imm.table_index, entry_index, imm.sig_index);
switch (result.type) { switch (result.type) {
case ExternalCallResult::INTERNAL: case ExternalCallResult::INTERNAL:
// The import is a function of this instance. Call it directly. // The import is a function of this instance. Call it directly.
...@@ -3113,14 +3112,12 @@ class ThreadImpl { ...@@ -3113,14 +3112,12 @@ class ThreadImpl {
CallIndirectImmediate<Decoder::kNoValidate> imm( CallIndirectImmediate<Decoder::kNoValidate> imm(
kAllWasmFeatures, &decoder, code->at(pc)); kAllWasmFeatures, &decoder, code->at(pc));
uint32_t entry_index = Pop().to<uint32_t>(); uint32_t entry_index = Pop().to<uint32_t>();
// Assume only one table for now.
DCHECK_LE(module()->tables.size(), 1u);
CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC. CommitPc(pc); // TODO(wasm): Be more disciplined about committing PC.
// TODO(wasm): Calling functions needs some refactoring to avoid // TODO(wasm): Calling functions needs some refactoring to avoid
// multi-exit code like this. // multi-exit code like this.
ExternalCallResult result = ExternalCallResult result =
CallIndirectFunction(0, entry_index, imm.sig_index); CallIndirectFunction(imm.table_index, entry_index, imm.sig_index);
switch (result.type) { switch (result.type) {
case ExternalCallResult::INTERNAL: { case ExternalCallResult::INTERNAL: {
InterpreterCode* target = result.interpreter_code; InterpreterCode* target = result.interpreter_code;
...@@ -3731,25 +3728,24 @@ class ThreadImpl { ...@@ -3731,25 +3728,24 @@ class ThreadImpl {
ExternalCallResult CallIndirectFunction(uint32_t table_index, ExternalCallResult CallIndirectFunction(uint32_t table_index,
uint32_t entry_index, uint32_t entry_index,
uint32_t sig_index) { uint32_t sig_index) {
HandleScope handle_scope(isolate_); // Avoid leaking handles.
uint32_t expected_sig_id = module()->signature_ids[sig_index]; uint32_t expected_sig_id = module()->signature_ids[sig_index];
DCHECK_EQ(expected_sig_id, DCHECK_EQ(expected_sig_id,
module()->signature_map.Find(*module()->signatures[sig_index])); module()->signature_map.Find(*module()->signatures[sig_index]));
// The function table is stored in the instance.
// TODO(wasm): the wasm interpreter currently supports only one table.
CHECK_EQ(0, table_index);
// Bounds check against table size. // Bounds check against table size.
if (entry_index >= instance_object_->indirect_function_table_size()) { if (entry_index >=
static_cast<uint32_t>(WasmInstanceObject::IndirectFunctionTableSize(
isolate_, instance_object_, table_index))) {
return {ExternalCallResult::INVALID_FUNC}; return {ExternalCallResult::INVALID_FUNC};
} }
IndirectFunctionTableEntry entry(instance_object_, 0, entry_index); IndirectFunctionTableEntry entry(instance_object_, table_index,
entry_index);
// Signature check. // Signature check.
if (entry.sig_id() != static_cast<int32_t>(expected_sig_id)) { if (entry.sig_id() != static_cast<int32_t>(expected_sig_id)) {
return {ExternalCallResult::SIGNATURE_MISMATCH}; return {ExternalCallResult::SIGNATURE_MISMATCH};
} }
HandleScope handle_scope(isolate_); // Avoid leaking handles.
FunctionSig* signature = module()->signatures[sig_index]; FunctionSig* signature = module()->signatures[sig_index];
Handle<Object> object_ref = handle(entry.object_ref(), isolate_); Handle<Object> object_ref = handle(entry.object_ref(), isolate_);
WasmCode* code = GetTargetCode(isolate_, entry.target()); WasmCode* code = GetTargetCode(isolate_, entry.target());
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --expose-wasm --experimental-wasm-anyref --experimental-wasm-return-call
// Flags: --wasm-interpret-all
// This is just a wrapper for an existing reference types test case that runs
// with the --wasm-interpret-all flag added. If we ever decide to add a test
// variant for this, then we can remove this file.
load("test/mjsunit/wasm/indirect-call-non-zero-table.js");
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment