Commit 3668b2c0 authored by titzer's avatar titzer Committed by Commit bot

[wasm] Fix CallIndirect with the case of no indirect function table.

R=ahaas@chromium.org,bradnelson@chromium.org
BUG=

Review URL: https://codereview.chromium.org/1648503003

Cr-Commit-Position: refs/heads/master@{#33592}
parent d0e01b0b
......@@ -105,6 +105,9 @@ class WasmTrapHelper : public ZoneObject {
// Make the current control path trap to unreachable.
void Unreachable() { ConnectTrap(kTrapUnreachable); }
// Always trap with the given reason.
void TrapAlways(TrapReason reason) { ConnectTrap(reason); }
// Add a check that traps if {node} is equal to {val}.
Node* TrapIfEq32(TrapReason reason, Node* node, int32_t val) {
Int32Matcher m(node);
......@@ -165,6 +168,28 @@ class WasmTrapHelper : public ZoneObject {
*effect_ptr = before;
}
Node* GetTrapValue(wasm::FunctionSig* sig) {
if (sig->return_count() > 0) {
switch (sig->GetReturn()) {
case wasm::kAstI32:
return jsgraph()->Int32Constant(0xdeadbeef);
case wasm::kAstI64:
return jsgraph()->Int64Constant(0xdeadbeefdeadbeef);
case wasm::kAstF32:
return jsgraph()->Float32Constant(bit_cast<float>(0xdeadbeef));
case wasm::kAstF64:
return jsgraph()->Float64Constant(
bit_cast<double>(0xdeadbeefdeadbeef));
break;
default:
UNREACHABLE();
return nullptr;
}
} else {
return jsgraph()->Int32Constant(0xdeadbeef);
}
}
private:
WasmGraphBuilder* builder_;
JSGraph* jsgraph_;
......@@ -227,29 +252,7 @@ class WasmTrapHelper : public ZoneObject {
end = thrw;
} else {
// End the control flow with returning 0xdeadbeef
Node* ret_value;
if (builder_->GetFunctionSignature()->return_count() > 0) {
switch (builder_->GetFunctionSignature()->GetReturn()) {
case wasm::kAstI32:
ret_value = jsgraph()->Int32Constant(0xdeadbeef);
break;
case wasm::kAstI64:
ret_value = jsgraph()->Int64Constant(0xdeadbeefdeadbeef);
break;
case wasm::kAstF32:
ret_value = jsgraph()->Float32Constant(bit_cast<float>(0xdeadbeef));
break;
case wasm::kAstF64:
ret_value = jsgraph()->Float64Constant(
bit_cast<double>(0xdeadbeefdeadbeef));
break;
default:
UNREACHABLE();
ret_value = nullptr;
}
} else {
ret_value = jsgraph()->Int32Constant(0xdeadbeef);
}
Node* ret_value = GetTrapValue(builder_->GetFunctionSignature());
end = graph()->NewNode(jsgraph()->common()->Return(), ret_value,
*effect_ptr, *control_ptr);
}
......@@ -1465,20 +1468,26 @@ Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args) {
Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) {
DCHECK_NOT_NULL(args[0]);
DCHECK(module_ && module_->instance);
MachineOperatorBuilder* machine = jsgraph()->machine();
// Compute the code object by loading it from the function table.
Node* key = args[0];
Node* table = FunctionTable();
// Bounds check the index.
int table_size = static_cast<int>(module_->FunctionTableSize());
{
if (table_size > 0) {
// Bounds check against the table size.
Node* size = Int32Constant(static_cast<int>(table_size));
Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
trap_->AddTrapIfFalse(kTrapFuncInvalid, in_bounds);
} else {
// No function table. Generate a trap and return a constant.
trap_->AddTrapIfFalse(kTrapFuncInvalid, Int32Constant(0));
return trap_->GetTrapValue(module_->GetSignature(index));
}
Node* table = FunctionTable();
// Load signature from the table and check.
// The table is a FixedArray; signatures are encoded as SMIs.
......
......@@ -180,7 +180,8 @@ struct ModuleEnv {
return module->signatures->at(index);
}
size_t FunctionTableSize() {
return module ? module->function_table->size() : 0;
return module && module->function_table ? module->function_table->size()
: 0;
}
Handle<Code> GetFunctionCode(uint32_t index);
......
......@@ -2938,6 +2938,27 @@ TEST(Run_Wasm_MultipleCallIndirect) {
CHECK_TRAP(r.Call(2, 1, 0));
}
TEST(Run_Wasm_CallIndirect_NoTable) {
WasmRunner<int32_t> r(MachineType::Int32());
TestSignatures sigs;
TestingModule module;
r.env()->module = &module;
// One function.
WasmFunctionCompiler t1(sigs.i_ii());
BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)));
t1.CompileAndAdd(&module, /*sig_index*/ 1);
// Signature table.
module.AddSignature(sigs.f_ff());
module.AddSignature(sigs.i_ii());
// Builder the caller function.
BUILD(r, WASM_CALL_INDIRECT(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22)));
CHECK_TRAP(r.Call(0));
CHECK_TRAP(r.Call(1));
CHECK_TRAP(r.Call(2));
}
TEST(Run_Wasm_F32Trunc) {
WasmRunner<float> r(MachineType::Float32());
......
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