Index: src/compiler/wasm-compiler.cc |
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
index 4e9c03a711ef34b0ba57394e9c3950ae30f2722b..b1eb3e6acdacb005304b2e374706e1a492536327 100644 |
--- a/src/compiler/wasm-compiler.cc |
+++ b/src/compiler/wasm-compiler.cc |
@@ -189,26 +189,29 @@ class WasmTrapHelper : public ZoneObject { |
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; |
- } |
+ return GetTrapValue(sig->GetReturn()); |
} else { |
return jsgraph()->Int32Constant(0xdeadbeef); |
} |
} |
+ Node* GetTrapValue(wasm::LocalType type) { |
+ switch (type) { |
+ 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; |
+ } |
+ } |
+ |
private: |
WasmGraphBuilder* builder_; |
JSGraph* jsgraph_; |
@@ -993,16 +996,11 @@ Node* WasmGraphBuilder::Return(unsigned count, Node** vals) { |
DCHECK_NOT_NULL(*control_); |
DCHECK_NOT_NULL(*effect_); |
- if (count == 0) { |
- // Handle a return of void. |
- vals[0] = jsgraph()->Int32Constant(0); |
- count = 1; |
- } |
- |
Node** buf = Realloc(vals, count, count + 2); |
buf[count] = *effect_; |
buf[count + 1] = *control_; |
- Node* ret = graph()->NewNode(jsgraph()->common()->Return(), count + 2, vals); |
+ Node* ret = |
+ graph()->NewNode(jsgraph()->common()->Return(count), count + 2, vals); |
MergeControlToEnd(jsgraph(), ret); |
return ret; |
@@ -1994,8 +1992,8 @@ Node* WasmGraphBuilder::BuildCCall(MachineSignature* sig, Node** args) { |
return call; |
} |
-Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args, |
- wasm::WasmCodePosition position) { |
+Node** WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args, |
+ wasm::WasmCodePosition position) { |
const size_t params = sig->parameter_count(); |
const size_t extra = 2; // effect and control inputs. |
const size_t count = 1 + params + extra; |
@@ -2014,33 +2012,38 @@ Node* WasmGraphBuilder::BuildWasmCall(wasm::FunctionSig* sig, Node** args, |
SetSourcePosition(call, position); |
*effect_ = call; |
- return call; |
-} |
- |
-Node* WasmGraphBuilder::CallDirect(uint32_t index, Node** args, |
- wasm::WasmCodePosition position) { |
- DCHECK_NULL(args[0]); |
+ size_t ret_count = sig->return_count(); |
+ if (ret_count == 0) return nullptr; // No return value. |
- // Add code object as constant. |
- args[0] = HeapConstant(module_->GetCodeOrPlaceholder(index)); |
- wasm::FunctionSig* sig = module_->GetFunctionSignature(index); |
- |
- return BuildWasmCall(sig, args, position); |
+ Node** rets = Buffer(ret_count); |
+ if (ret_count == 1) { |
+ // Only a single return value. |
+ rets[0] = call; |
+ } else { |
+ // Create projections for all return values. |
+ for (size_t i = 0; i < ret_count; i++) { |
+ rets[i] = graph()->NewNode(jsgraph()->common()->Projection(i), call, |
+ graph()->start()); |
+ } |
+ } |
+ return rets; |
} |
-Node* WasmGraphBuilder::CallImport(uint32_t index, Node** args, |
- wasm::WasmCodePosition position) { |
+Node** WasmGraphBuilder::CallDirect(uint32_t index, Node** args, |
+ wasm::WasmCodePosition position) { |
DCHECK_NULL(args[0]); |
// Add code object as constant. |
- args[0] = HeapConstant(module_->GetImportCode(index)); |
- wasm::FunctionSig* sig = module_->GetImportSignature(index); |
+ Handle<Code> code = module_->GetFunctionCode(index); |
+ DCHECK(!code.is_null()); |
+ args[0] = HeapConstant(code); |
+ wasm::FunctionSig* sig = module_->GetFunctionSignature(index); |
return BuildWasmCall(sig, args, position); |
} |
-Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, |
- wasm::WasmCodePosition position) { |
+Node** WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, |
+ wasm::WasmCodePosition position) { |
DCHECK_NOT_NULL(args[0]); |
DCHECK(module_ && module_->instance); |
@@ -2054,6 +2057,7 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, |
// Bounds check the index. |
uint32_t table_size = |
module_->IsValidTable(0) ? module_->GetTable(0)->max_size : 0; |
+ wasm::FunctionSig* sig = module_->GetSignature(index); |
if (table_size > 0) { |
// Bounds check against the table size. |
Node* size = Uint32Constant(table_size); |
@@ -2062,7 +2066,11 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, |
} else { |
// No function table. Generate a trap and return a constant. |
trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); |
- return trap_->GetTrapValue(module_->GetSignature(index)); |
+ Node** rets = Buffer(sig->return_count()); |
+ for (size_t i = 0; i < sig->return_count(); i++) { |
+ rets[i] = trap_->GetTrapValue(sig->GetReturn(i)); |
+ } |
+ return rets; |
} |
Node* table = FunctionTable(0); |
@@ -2096,7 +2104,6 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, |
*effect_, *control_); |
args[0] = load_code; |
- wasm::FunctionSig* sig = module_->GetSignature(index); |
return BuildWasmCall(sig, args, position); |
} |
@@ -2693,6 +2700,11 @@ Node* WasmGraphBuilder::MemBuffer(uint32_t offset) { |
} |
} |
+Node* WasmGraphBuilder::CurrentMemoryPages() { |
+ return graph()->NewNode(jsgraph()->machine()->Word32Shr(), MemSize(0), |
+ jsgraph()->Int32Constant(16)); |
+} |
+ |
Node* WasmGraphBuilder::MemSize(uint32_t offset) { |
DCHECK(module_ && module_->instance); |
uint32_t size = static_cast<uint32_t>(module_->instance->mem_size); |