| Index: src/compiler/wasm-compiler.cc
|
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
|
| index 6c50183beeadd533a25f44d1196b153b8cfe5534..f8960d1c0b23be602ecc7759fed43f8eb7cf8c65 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]);
|
| -
|
| - // Add code object as constant.
|
| - args[0] = HeapConstant(module_->GetCodeOrPlaceholder(index));
|
| - wasm::FunctionSig* sig = module_->GetFunctionSignature(index);
|
| + size_t ret_count = sig->return_count();
|
| + if (ret_count == 0) return nullptr; // No return value.
|
|
|
| - 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);
|
| }
|
|
|
|
|