Chromium Code Reviews| Index: src/compiler/wasm-compiler.cc |
| diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
| index cee3d3ab18c41bbaf7528e50a8555bcbd047305e..933886cd9d225af8fb3cecb31d832a7f61a4f9ff 100644 |
| --- a/src/compiler/wasm-compiler.cc |
| +++ b/src/compiler/wasm-compiler.cc |
| @@ -80,62 +80,68 @@ class WasmTrapHelper : public ZoneObject { |
| explicit WasmTrapHelper(WasmGraphBuilder* builder) |
| : builder_(builder), |
| jsgraph_(builder->jsgraph()), |
| - graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) { |
| - for (int i = 0; i < wasm::kTrapCount; i++) traps_[i] = nullptr; |
| - } |
| + graph_(builder->jsgraph() ? builder->jsgraph()->graph() : nullptr) {} |
| // Make the current control path trap to unreachable. |
| - void Unreachable() { ConnectTrap(wasm::kTrapUnreachable); } |
| + void Unreachable(int position) { |
| + ConnectTrap(wasm::kTrapUnreachable, position); |
| + } |
| // Always trap with the given reason. |
| - void TrapAlways(wasm::TrapReason reason) { ConnectTrap(reason); } |
| + void TrapAlways(wasm::TrapReason reason, int position) { |
| + ConnectTrap(reason, position); |
| + } |
| // Add a check that traps if {node} is equal to {val}. |
| - Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val) { |
| + Node* TrapIfEq32(wasm::TrapReason reason, Node* node, int32_t val, |
| + int position) { |
| Int32Matcher m(node); |
| if (m.HasValue() && !m.Is(val)) return graph()->start(); |
| if (val == 0) { |
| - AddTrapIfFalse(reason, node); |
| + AddTrapIfFalse(reason, node, position); |
| } else { |
| AddTrapIfTrue(reason, |
| graph()->NewNode(jsgraph()->machine()->Word32Equal(), node, |
| - jsgraph()->Int32Constant(val))); |
| + jsgraph()->Int32Constant(val)), |
| + position); |
| } |
| return builder_->Control(); |
| } |
| // Add a check that traps if {node} is zero. |
| - Node* ZeroCheck32(wasm::TrapReason reason, Node* node) { |
| - return TrapIfEq32(reason, node, 0); |
| + Node* ZeroCheck32(wasm::TrapReason reason, Node* node, int position) { |
| + return TrapIfEq32(reason, node, 0, position); |
| } |
| // Add a check that traps if {node} is equal to {val}. |
| - Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val) { |
| + Node* TrapIfEq64(wasm::TrapReason reason, Node* node, int64_t val, |
| + int position) { |
| Int64Matcher m(node); |
| if (m.HasValue() && !m.Is(val)) return graph()->start(); |
| - AddTrapIfTrue(reason, |
| - graph()->NewNode(jsgraph()->machine()->Word64Equal(), node, |
| - jsgraph()->Int64Constant(val))); |
| + AddTrapIfTrue(reason, graph()->NewNode(jsgraph()->machine()->Word64Equal(), |
| + node, jsgraph()->Int64Constant(val)), |
| + position); |
| return builder_->Control(); |
| } |
| // Add a check that traps if {node} is zero. |
| - Node* ZeroCheck64(wasm::TrapReason reason, Node* node) { |
| - return TrapIfEq64(reason, node, 0); |
| + Node* ZeroCheck64(wasm::TrapReason reason, Node* node, int position) { |
| + return TrapIfEq64(reason, node, 0, position); |
| } |
| // Add a trap if {cond} is true. |
| - void AddTrapIfTrue(wasm::TrapReason reason, Node* cond) { |
| - AddTrapIf(reason, cond, true); |
| + void AddTrapIfTrue(wasm::TrapReason reason, Node* cond, int position) { |
| + AddTrapIf(reason, cond, true, position); |
| } |
| // Add a trap if {cond} is false. |
| - void AddTrapIfFalse(wasm::TrapReason reason, Node* cond) { |
| - AddTrapIf(reason, cond, false); |
| + void AddTrapIfFalse(wasm::TrapReason reason, Node* cond, int position) { |
| + AddTrapIf(reason, cond, false, position); |
| } |
| // Add a trap if {cond} is true or false according to {iftrue}. |
| - void AddTrapIf(wasm::TrapReason reason, Node* cond, bool iftrue) { |
| + void AddTrapIf(wasm::TrapReason reason, Node* cond, bool iftrue, |
| + int position) { |
| Node** effect_ptr = builder_->effect_; |
| Node** control_ptr = builder_->control_; |
| Node* before = *effect_ptr; |
| @@ -145,7 +151,7 @@ class WasmTrapHelper : public ZoneObject { |
| Node* if_false = graph()->NewNode(common()->IfFalse(), branch); |
| *control_ptr = iftrue ? if_true : if_false; |
| - ConnectTrap(reason); |
| + ConnectTrap(reason, position); |
| *control_ptr = iftrue ? if_false : if_true; |
| *effect_ptr = before; |
| } |
| @@ -176,35 +182,50 @@ class WasmTrapHelper : public ZoneObject { |
| WasmGraphBuilder* builder_; |
| JSGraph* jsgraph_; |
| Graph* graph_; |
| - Node* traps_[wasm::kTrapCount]; |
| - Node* effects_[wasm::kTrapCount]; |
| + Node* trap_merge_ = nullptr; |
| + Node* trap_effect_; |
| + Node* trap_reason_; |
| + Node* trap_position_; |
| JSGraph* jsgraph() { return jsgraph_; } |
| Graph* graph() { return jsgraph_->graph(); } |
| CommonOperatorBuilder* common() { return jsgraph()->common(); } |
| - void ConnectTrap(wasm::TrapReason reason) { |
| - if (traps_[reason] == nullptr) { |
| + void ConnectTrap(wasm::TrapReason reason, int position) { |
| + DCHECK(position >= 0); |
| + Node* reason_node = builder_->Int32Constant( |
| + wasm::WasmOpcodes::TrapReasonToMessageId(reason)); |
| + Node* position_node = builder_->Int32Constant(position); |
| + if (trap_merge_ == nullptr) { |
| // Create trap code for the first time this trap is used. |
|
titzer
2016/04/28 11:27:00
Update comment: s/this trap is used//
Clemens Hammacher
2016/04/28 12:43:28
Done.
|
| - return BuildTrapCode(reason); |
| + return BuildTrapCode(reason_node, position_node); |
| } |
| // Connect the current control and effect to the existing trap code. |
| - builder_->AppendToMerge(traps_[reason], builder_->Control()); |
| - builder_->AppendToPhi(traps_[reason], effects_[reason], builder_->Effect()); |
| + builder_->AppendToMerge(trap_merge_, builder_->Control()); |
| + builder_->AppendToPhi(trap_effect_, builder_->Effect()); |
| + builder_->AppendToPhi(trap_reason_, reason_node); |
| + builder_->AppendToPhi(trap_position_, position_node); |
| } |
| - void BuildTrapCode(wasm::TrapReason reason) { |
| - Node* message_id = builder_->NumberConstant( |
| - wasm::WasmOpcodes::TrapReasonToMessageId(reason)); |
| + void BuildTrapCode(Node* reason_node, Node* position_node) { |
| Node* end; |
| Node** control_ptr = builder_->control_; |
| Node** effect_ptr = builder_->effect_; |
| wasm::ModuleEnv* module = builder_->module_; |
| - DCHECK(traps_[reason] == NULL); |
| - *control_ptr = traps_[reason] = |
| + DCHECK(trap_merge_ == NULL); |
| + *control_ptr = trap_merge_ = |
| graph()->NewNode(common()->Merge(1), *control_ptr); |
| - *effect_ptr = effects_[reason] = |
| + *effect_ptr = trap_effect_ = |
| graph()->NewNode(common()->EffectPhi(1), *effect_ptr, *control_ptr); |
| + trap_reason_ = |
| + graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1), |
| + reason_node, *control_ptr); |
| + trap_position_ = |
| + graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 1), |
| + position_node, *control_ptr); |
| + |
| + Node* trap_reason_smi = builder_->BuildChangeInt32ToSmi(trap_reason_); |
| + Node* trap_position_smi = builder_->BuildChangeInt32ToSmi(trap_position_); |
| if (module && !module->instance->context.is_null()) { |
| // Use the module context to call the runtime to throw an exception. |
| @@ -215,7 +236,8 @@ class WasmTrapHelper : public ZoneObject { |
| CallDescriptor::kNoFlags); |
| Node* inputs[] = { |
| jsgraph()->CEntryStubConstant(fun->result_size), // C entry |
| - message_id, // message id |
| + trap_reason_smi, // message id |
| + trap_position_smi, // byte position |
| jsgraph()->ExternalConstant( |
| ExternalReference(f, jsgraph()->isolate())), // ref |
| jsgraph()->Int32Constant(fun->nargs), // arity |
| @@ -313,10 +335,8 @@ void WasmGraphBuilder::AppendToMerge(Node* merge, Node* from) { |
| merge, jsgraph()->common()->ResizeMergeOrPhi(merge->op(), new_size)); |
| } |
| - |
| -void WasmGraphBuilder::AppendToPhi(Node* merge, Node* phi, Node* from) { |
| +void WasmGraphBuilder::AppendToPhi(Node* phi, Node* from) { |
| DCHECK(IrOpcode::IsPhiOpcode(phi->opcode())); |
| - DCHECK(IrOpcode::IsMergeOpcode(merge->opcode())); |
| int new_size = phi->InputCount(); |
| phi->InsertInput(jsgraph()->zone(), phi->InputCount() - 1, from); |
| NodeProperties::ChangeOp( |
| @@ -361,9 +381,8 @@ Node* WasmGraphBuilder::Int64Constant(int64_t value) { |
| return jsgraph()->Int64Constant(value); |
| } |
| - |
| -Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, |
| - Node* right) { |
| +Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, Node* right, |
| + int position) { |
| const Operator* op; |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| switch (opcode) { |
| @@ -377,13 +396,13 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, |
| op = m->Int32Mul(); |
| break; |
| case wasm::kExprI32DivS: |
| - return BuildI32DivS(left, right); |
| + return BuildI32DivS(left, right, position); |
| case wasm::kExprI32DivU: |
| - return BuildI32DivU(left, right); |
| + return BuildI32DivU(left, right, position); |
| case wasm::kExprI32RemS: |
| - return BuildI32RemS(left, right); |
| + return BuildI32RemS(left, right, position); |
| case wasm::kExprI32RemU: |
| - return BuildI32RemU(left, right); |
| + return BuildI32RemU(left, right, position); |
| case wasm::kExprI32And: |
| op = m->Word32And(); |
| break; |
| @@ -464,16 +483,16 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, |
| break; |
| // kExprI64DivS: |
| case wasm::kExprI64DivS: |
| - return BuildI64DivS(left, right); |
| + return BuildI64DivS(left, right, position); |
| // kExprI64DivU: |
| case wasm::kExprI64DivU: |
| - return BuildI64DivU(left, right); |
| + return BuildI64DivU(left, right, position); |
| // kExprI64RemS: |
| case wasm::kExprI64RemS: |
| - return BuildI64RemS(left, right); |
| + return BuildI64RemS(left, right, position); |
| // kExprI64RemU: |
| case wasm::kExprI64RemU: |
| - return BuildI64RemU(left, right); |
| + return BuildI64RemU(left, right, position); |
| case wasm::kExprI64Ior: |
| op = m->Word64Or(); |
| break; |
| @@ -627,8 +646,8 @@ Node* WasmGraphBuilder::Binop(wasm::WasmOpcode opcode, Node* left, |
| return graph()->NewNode(op, left, right); |
| } |
| - |
| -Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { |
| +Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input, |
| + int position) { |
| const Operator* op; |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| switch (opcode) { |
| @@ -652,9 +671,9 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { |
| op = m->Float64Sqrt(); |
| break; |
| case wasm::kExprI32SConvertF64: |
| - return BuildI32SConvertF64(input); |
| + return BuildI32SConvertF64(input, position); |
| case wasm::kExprI32UConvertF64: |
| - return BuildI32UConvertF64(input); |
| + return BuildI32UConvertF64(input, position); |
| case wasm::kExprF32ConvertF64: |
| op = m->TruncateFloat64ToFloat32(); |
| break; |
| @@ -671,9 +690,9 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { |
| op = m->RoundUint32ToFloat32(); |
| break; |
| case wasm::kExprI32SConvertF32: |
| - return BuildI32SConvertF32(input); |
| + return BuildI32SConvertF32(input, position); |
| case wasm::kExprI32UConvertF32: |
| - return BuildI32UConvertF32(input); |
| + return BuildI32UConvertF32(input, position); |
| case wasm::kExprF64ConvertF32: |
| op = m->ChangeFloat32ToFloat64(); |
| break; |
| @@ -856,19 +875,19 @@ Node* WasmGraphBuilder::Unop(wasm::WasmOpcode opcode, Node* input) { |
| break; |
| // kExprI64SConvertF32: |
| case wasm::kExprI64SConvertF32: { |
| - return BuildI64SConvertF32(input); |
| + return BuildI64SConvertF32(input, position); |
| } |
| // kExprI64SConvertF64: |
| case wasm::kExprI64SConvertF64: { |
| - return BuildI64SConvertF64(input); |
| + return BuildI64SConvertF64(input, position); |
| } |
| // kExprI64UConvertF32: |
| case wasm::kExprI64UConvertF32: { |
| - return BuildI64UConvertF32(input); |
| + return BuildI64UConvertF32(input, position); |
| } |
| // kExprI64UConvertF64: |
| case wasm::kExprI64UConvertF64: { |
| - return BuildI64UConvertF64(input); |
| + return BuildI64UConvertF64(input, position); |
| } |
| default: |
| op = UnsupportedOpcode(opcode); |
| @@ -943,9 +962,8 @@ Node* WasmGraphBuilder::Return(unsigned count, Node** vals) { |
| Node* WasmGraphBuilder::ReturnVoid() { return Return(0, Buffer(0)); } |
| - |
| -Node* WasmGraphBuilder::Unreachable() { |
| - trap_->Unreachable(); |
| +Node* WasmGraphBuilder::Unreachable(int position) { |
| + trap_->Unreachable(position); |
| return nullptr; |
| } |
| @@ -1136,8 +1154,7 @@ Node* WasmGraphBuilder::BuildF64Max(Node* left, Node* right) { |
| Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); |
| } |
| - |
| -Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) { |
| +Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js must use the wacky JS semantics. |
| @@ -1153,13 +1170,12 @@ Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input) { |
| // truncated input value, then there has been an overflow and we trap. |
| Node* check = Unop(wasm::kExprF32SConvertI32, result); |
| Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); |
| - trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| - |
| -Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { |
| +Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js must use the wacky JS semantics. |
| @@ -1173,13 +1189,12 @@ Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input) { |
| // truncated input value, then there has been an overflow and we trap. |
| Node* check = Unop(wasm::kExprF64SConvertI32, result); |
| Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); |
| - trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| - |
| -Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { |
| +Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js must use the wacky JS semantics. |
| @@ -1195,13 +1210,12 @@ Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input) { |
| // truncated input value, then there has been an overflow and we trap. |
| Node* check = Unop(wasm::kExprF32UConvertI32, result); |
| Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); |
| - trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| - |
| -Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { |
| +Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js must use the wacky JS semantics. |
| @@ -1215,7 +1229,7 @@ Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input) { |
| // truncated input value, then there has been an overflow and we trap. |
| Node* check = Unop(wasm::kExprF64UConvertI32, result); |
| Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); |
| - trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| @@ -1506,66 +1520,66 @@ Node* WasmGraphBuilder::BuildIntToFloatConversionInstruction( |
| return load; |
| } |
| -Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input) { |
| +Node* WasmGraphBuilder::BuildI64SConvertF32(Node* input, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildFloatToIntConversionInstruction( |
| input, ExternalReference::wasm_float32_to_int64(jsgraph()->isolate()), |
| - MachineRepresentation::kFloat32, MachineType::Int64()); |
| + MachineRepresentation::kFloat32, MachineType::Int64(), position); |
| } else { |
| Node* trunc = graph()->NewNode( |
| jsgraph()->machine()->TryTruncateFloat32ToInt64(), input); |
| Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| Node* overflow = |
| graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| - trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| } |
| -Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input) { |
| +Node* WasmGraphBuilder::BuildI64UConvertF32(Node* input, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildFloatToIntConversionInstruction( |
| input, ExternalReference::wasm_float32_to_uint64(jsgraph()->isolate()), |
| - MachineRepresentation::kFloat32, MachineType::Int64()); |
| + MachineRepresentation::kFloat32, MachineType::Int64(), position); |
| } else { |
| Node* trunc = graph()->NewNode( |
| jsgraph()->machine()->TryTruncateFloat32ToUint64(), input); |
| Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| Node* overflow = |
| graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| - trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| } |
| -Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input) { |
| +Node* WasmGraphBuilder::BuildI64SConvertF64(Node* input, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildFloatToIntConversionInstruction( |
| input, ExternalReference::wasm_float64_to_int64(jsgraph()->isolate()), |
| - MachineRepresentation::kFloat64, MachineType::Int64()); |
| + MachineRepresentation::kFloat64, MachineType::Int64(), position); |
| } else { |
| Node* trunc = graph()->NewNode( |
| jsgraph()->machine()->TryTruncateFloat64ToInt64(), input); |
| Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| Node* overflow = |
| graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| - trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| } |
| -Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input) { |
| +Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildFloatToIntConversionInstruction( |
| input, ExternalReference::wasm_float64_to_uint64(jsgraph()->isolate()), |
| - MachineRepresentation::kFloat64, MachineType::Int64()); |
| + MachineRepresentation::kFloat64, MachineType::Int64(), position); |
| } else { |
| Node* trunc = graph()->NewNode( |
| jsgraph()->machine()->TryTruncateFloat64ToUint64(), input); |
| Node* result = graph()->NewNode(jsgraph()->common()->Projection(0), trunc); |
| Node* overflow = |
| graph()->NewNode(jsgraph()->common()->Projection(1), trunc); |
| - trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow); |
| + trap_->ZeroCheck64(wasm::kTrapFloatUnrepresentable, overflow, position); |
| return result; |
| } |
| } |
| @@ -1573,7 +1587,7 @@ Node* WasmGraphBuilder::BuildI64UConvertF64(Node* input) { |
| Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( |
| Node* input, ExternalReference ref, |
| MachineRepresentation parameter_representation, |
| - const MachineType result_type) { |
| + const MachineType result_type, int position) { |
| Node* stack_slot_param = graph()->NewNode( |
| jsgraph()->machine()->StackSlot(parameter_representation)); |
| Node* stack_slot_result = graph()->NewNode( |
| @@ -1590,7 +1604,7 @@ Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( |
| Node* function = graph()->NewNode(jsgraph()->common()->ExternalConstant(ref)); |
| Node* args[] = {function, stack_slot_param, stack_slot_result}; |
| trap_->ZeroCheck32(wasm::kTrapFloatUnrepresentable, |
| - BuildCCall(sig_builder.Build(), args)); |
| + BuildCCall(sig_builder.Build(), args), position); |
| const Operator* load_op = jsgraph()->machine()->Load(result_type); |
| Node* load = |
| graph()->NewNode(load_op, stack_slot_result, jsgraph()->Int32Constant(0), |
| @@ -1599,7 +1613,7 @@ Node* WasmGraphBuilder::BuildFloatToIntConversionInstruction( |
| return load; |
| } |
| -Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js semantics return 0 on divide or mod by zero. |
| @@ -1629,7 +1643,7 @@ Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right) { |
| jsgraph()->Int32Constant(0), div)); |
| } |
| - trap_->ZeroCheck32(wasm::kTrapDivByZero, right); |
| + trap_->ZeroCheck32(wasm::kTrapDivByZero, right, position); |
| Node* before = *control_; |
| Node* denom_is_m1; |
| Node* denom_is_not_m1; |
| @@ -1637,7 +1651,7 @@ Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right) { |
| graph()->NewNode(m->Word32Equal(), right, jsgraph()->Int32Constant(-1)), |
| &denom_is_m1, &denom_is_not_m1); |
| *control_ = denom_is_m1; |
| - trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, left, kMinInt); |
| + trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, left, kMinInt, position); |
| if (*control_ != denom_is_m1) { |
| *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1, |
| *control_); |
| @@ -1647,7 +1661,7 @@ Node* WasmGraphBuilder::BuildI32DivS(Node* left, Node* right) { |
| return graph()->NewNode(m->Int32Div(), left, right, *control_); |
| } |
| -Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js semantics return 0 on divide or mod by zero. |
| @@ -1670,7 +1684,7 @@ Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right) { |
| graph()->NewNode(m->Int32Mod(), left, right, d.if_false))); |
| } |
| - trap_->ZeroCheck32(wasm::kTrapRemByZero, right); |
| + trap_->ZeroCheck32(wasm::kTrapRemByZero, right, position); |
| Diamond d( |
| graph(), jsgraph()->common(), |
| @@ -1682,7 +1696,7 @@ Node* WasmGraphBuilder::BuildI32RemS(Node* left, Node* right) { |
| graph()->NewNode(m->Int32Mod(), left, right, d.if_false)); |
| } |
| -Node* WasmGraphBuilder::BuildI32DivU(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI32DivU(Node* left, Node* right, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js semantics return 0 on divide or mod by zero. |
| @@ -1701,11 +1715,12 @@ Node* WasmGraphBuilder::BuildI32DivU(Node* left, Node* right) { |
| graph()->NewNode(jsgraph()->machine()->Uint32Div(), left, |
| right, z.if_false)); |
| } |
| - return graph()->NewNode(m->Uint32Div(), left, right, |
| - trap_->ZeroCheck32(wasm::kTrapDivByZero, right)); |
| + return graph()->NewNode( |
| + m->Uint32Div(), left, right, |
| + trap_->ZeroCheck32(wasm::kTrapDivByZero, right, position)); |
| } |
| -Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right, int position) { |
| MachineOperatorBuilder* m = jsgraph()->machine(); |
| if (module_ && module_->asm_js()) { |
| // asm.js semantics return 0 on divide or mod by zero. |
| @@ -1721,17 +1736,18 @@ Node* WasmGraphBuilder::BuildI32RemU(Node* left, Node* right) { |
| rem); |
| } |
| - return graph()->NewNode(m->Uint32Mod(), left, right, |
| - trap_->ZeroCheck32(wasm::kTrapRemByZero, right)); |
| + return graph()->NewNode( |
| + m->Uint32Mod(), left, right, |
| + trap_->ZeroCheck32(wasm::kTrapRemByZero, right, position)); |
| } |
| -Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildDiv64Call( |
| left, right, ExternalReference::wasm_int64_div(jsgraph()->isolate()), |
| - MachineType::Int64(), wasm::kTrapDivByZero); |
| + MachineType::Int64(), wasm::kTrapDivByZero, position); |
| } |
| - trap_->ZeroCheck64(wasm::kTrapDivByZero, right); |
| + trap_->ZeroCheck64(wasm::kTrapDivByZero, right, position); |
| Node* before = *control_; |
| Node* denom_is_m1; |
| Node* denom_is_not_m1; |
| @@ -1740,7 +1756,7 @@ Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) { |
| &denom_is_m1, &denom_is_not_m1); |
| *control_ = denom_is_m1; |
| trap_->TrapIfEq64(wasm::kTrapDivUnrepresentable, left, |
| - std::numeric_limits<int64_t>::min()); |
| + std::numeric_limits<int64_t>::min(), position); |
| if (*control_ != denom_is_m1) { |
| *control_ = graph()->NewNode(jsgraph()->common()->Merge(2), denom_is_not_m1, |
| *control_); |
| @@ -1751,13 +1767,13 @@ Node* WasmGraphBuilder::BuildI64DivS(Node* left, Node* right) { |
| *control_); |
| } |
| -Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildDiv64Call( |
| left, right, ExternalReference::wasm_int64_mod(jsgraph()->isolate()), |
| - MachineType::Int64(), wasm::kTrapRemByZero); |
| + MachineType::Int64(), wasm::kTrapRemByZero, position); |
| } |
| - trap_->ZeroCheck64(wasm::kTrapRemByZero, right); |
| + trap_->ZeroCheck64(wasm::kTrapRemByZero, right, position); |
| Diamond d(jsgraph()->graph(), jsgraph()->common(), |
| graph()->NewNode(jsgraph()->machine()->Word64Equal(), right, |
| jsgraph()->Int64Constant(-1))); |
| @@ -1769,28 +1785,31 @@ Node* WasmGraphBuilder::BuildI64RemS(Node* left, Node* right) { |
| rem); |
| } |
| -Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI64DivU(Node* left, Node* right, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildDiv64Call( |
| left, right, ExternalReference::wasm_uint64_div(jsgraph()->isolate()), |
| - MachineType::Int64(), wasm::kTrapDivByZero); |
| + MachineType::Int64(), wasm::kTrapDivByZero, position); |
| } |
| - return graph()->NewNode(jsgraph()->machine()->Uint64Div(), left, right, |
| - trap_->ZeroCheck64(wasm::kTrapDivByZero, right)); |
| + return graph()->NewNode( |
| + jsgraph()->machine()->Uint64Div(), left, right, |
| + trap_->ZeroCheck64(wasm::kTrapDivByZero, right, position)); |
| } |
| -Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right) { |
| +Node* WasmGraphBuilder::BuildI64RemU(Node* left, Node* right, int position) { |
| if (jsgraph()->machine()->Is32()) { |
| return BuildDiv64Call( |
| left, right, ExternalReference::wasm_uint64_mod(jsgraph()->isolate()), |
| - MachineType::Int64(), wasm::kTrapRemByZero); |
| + MachineType::Int64(), wasm::kTrapRemByZero, position); |
| } |
| - return graph()->NewNode(jsgraph()->machine()->Uint64Mod(), left, right, |
| - trap_->ZeroCheck64(wasm::kTrapRemByZero, right)); |
| + return graph()->NewNode( |
| + jsgraph()->machine()->Uint64Mod(), left, right, |
| + trap_->ZeroCheck64(wasm::kTrapRemByZero, right, position)); |
| } |
| Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right, |
| ExternalReference ref, |
| - MachineType result_type, int trap_zero) { |
| + MachineType result_type, int trap_zero, |
| + int position) { |
| Node* stack_slot_dst = graph()->NewNode( |
| jsgraph()->machine()->StackSlot(MachineRepresentation::kWord64)); |
| Node* stack_slot_src = graph()->NewNode( |
| @@ -1817,8 +1836,8 @@ Node* WasmGraphBuilder::BuildDiv64Call(Node* left, Node* right, |
| // TODO(wasm): This can get simpler if we have a specialized runtime call to |
| // throw WASM exceptions by trap code instead of by string. |
| - trap_->ZeroCheck32(static_cast<wasm::TrapReason>(trap_zero), call); |
| - trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, call, -1); |
| + trap_->ZeroCheck32(static_cast<wasm::TrapReason>(trap_zero), call, position); |
| + trap_->TrapIfEq32(wasm::kTrapDivUnrepresentable, call, -1, position); |
| const Operator* load_op = jsgraph()->machine()->Load(result_type); |
| Node* load = |
| graph()->NewNode(load_op, stack_slot_dst, jsgraph()->Int32Constant(0), |
| @@ -1889,7 +1908,8 @@ Node* WasmGraphBuilder::CallImport(uint32_t index, Node** args) { |
| return BuildWasmCall(sig, args); |
| } |
| -Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) { |
| +Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args, |
| + int position) { |
| DCHECK_NOT_NULL(args[0]); |
| DCHECK(module_ && module_->instance); |
| @@ -1904,10 +1924,10 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) { |
| // 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(wasm::kTrapFuncInvalid, in_bounds); |
| + trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position); |
| } else { |
| // No function table. Generate a trap and return a constant. |
| - trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0)); |
| + trap_->AddTrapIfFalse(wasm::kTrapFuncInvalid, Int32Constant(0), position); |
| return trap_->GetTrapValue(module_->GetSignature(index)); |
| } |
| Node* table = FunctionTable(); |
| @@ -1927,7 +1947,7 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t index, Node** args) { |
| *effect_, *control_); |
| Node* sig_match = graph()->NewNode(machine->WordEqual(), load_sig, |
| jsgraph()->SmiConstant(index)); |
| - trap_->AddTrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match); |
| + trap_->AddTrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position); |
| } |
| // Load code object from the table. |
| @@ -2561,9 +2581,8 @@ Node* WasmGraphBuilder::StoreGlobal(uint32_t index, Node* val) { |
| return node; |
| } |
| - |
| void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index, |
| - uint32_t offset) { |
| + uint32_t offset, int position) { |
| // TODO(turbofan): fold bounds checks for constant indexes. |
| DCHECK(module_ && module_->instance); |
| size_t size = module_->instance->mem_size; |
| @@ -2581,12 +2600,11 @@ void WasmGraphBuilder::BoundsCheckMem(MachineType memtype, Node* index, |
| jsgraph()->Int32Constant(static_cast<uint32_t>(limit))); |
| } |
| - trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond); |
| + trap_->AddTrapIfFalse(wasm::kTrapMemOutOfBounds, cond, position); |
| } |
| - |
| Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, |
| - Node* index, uint32_t offset) { |
| + Node* index, uint32_t offset, int position) { |
| Node* load; |
| if (module_ && module_->asm_js()) { |
| @@ -2597,7 +2615,7 @@ Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, |
| *control_); |
| } else { |
| // WASM semantics throw on OOB. Introduce explicit bounds check. |
| - BoundsCheckMem(memtype, index, offset); |
| + BoundsCheckMem(memtype, index, offset, position); |
| load = graph()->NewNode(jsgraph()->machine()->Load(memtype), |
| MemBuffer(offset), index, *effect_, *control_); |
| } |
| @@ -2620,9 +2638,8 @@ Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype, |
| return load; |
| } |
| - |
| Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, |
| - uint32_t offset, Node* val) { |
| + uint32_t offset, Node* val, int position) { |
| Node* store; |
| if (module_ && module_->asm_js()) { |
| // asm.js semantics use CheckedStore (i.e. ignore OOB writes). |
| @@ -2633,7 +2650,7 @@ Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, |
| *control_); |
| } else { |
| // WASM semantics throw on OOB. Introduce explicit bounds check. |
| - BoundsCheckMem(memtype, index, offset); |
| + BoundsCheckMem(memtype, index, offset, position); |
| StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
| store = |
| graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), |