From 5083bb08d4d7f9f9227104910c32dc7499e26de6 Mon Sep 17 00:00:00 2001 From: Lars T Hansen Date: Mon, 5 Feb 2018 20:29:27 +0100 Subject: [PATCH] Bug 1435756 - Clarify fallthrough in generated code for wasm truncate. r=bbouvier --HG-- extra : source : ce16751adf656bb414257c3ab0450fcfb7f21ea9 extra : amend_source : 707316189f2e91d688117064e913ef18dc6d5ace --- .../x86-shared/MacroAssembler-x86-shared.cpp | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp index 84c535480f22..11dd66682223 100644 --- a/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp +++ b/js/src/jit/x86-shared/MacroAssembler-x86-shared.cpp @@ -683,7 +683,7 @@ struct MOZ_RAII AutoHandleWasmTruncateToIntErrors { MacroAssembler& masm; Label inputIsNaN; - Label fail; + Label intOverflow; wasm::BytecodeOffset off; explicit AutoHandleWasmTruncateToIntErrors(MacroAssembler& masm, wasm::BytecodeOffset off) @@ -691,8 +691,9 @@ struct MOZ_RAII AutoHandleWasmTruncateToIntErrors { } ~AutoHandleWasmTruncateToIntErrors() { - // Handle errors. - masm.bind(&fail); + // Handle errors. These cases are not in arbitrary order: code will + // fall through to intOverflow. + masm.bind(&intOverflow); masm.jump(wasm::OldTrapDesc(off, wasm::Trap::IntegerOverflow, masm.framePushed())); masm.bind(&inputIsNaN); @@ -725,17 +726,19 @@ MacroAssembler::oolWasmTruncateCheckF64ToI32(FloatRegister input, bool isUnsigne // Eagerly take care of NaNs. branchDouble(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN); - // Handle special values (not needed for unsigned values). + // For unsigned, fall through to intOverflow failure case. if (isUnsigned) return; + // Handle special values. + // We've used vcvttsd2si. The only valid double values that can // truncate to INT32_MIN are in ]INT32_MIN - 1; INT32_MIN]. loadConstantDouble(double(INT32_MIN) - 1.0, ScratchDoubleReg); - branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.fail); + branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.intOverflow); loadConstantDouble(double(INT32_MIN), ScratchDoubleReg); - branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.fail); + branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.intOverflow); jump(rejoin); } @@ -748,15 +751,17 @@ MacroAssembler::oolWasmTruncateCheckF32ToI32(FloatRegister input, bool isUnsigne // Eagerly take care of NaNs. branchFloat(Assembler::DoubleUnordered, input, input, &traps.inputIsNaN); - // Handle special values (not needed for unsigned values). + // For unsigned, fall through to intOverflow failure case. if (isUnsigned) return; + // Handle special values. + // We've used vcvttss2si. Check that the input wasn't // float(INT32_MIN), which is the only legimitate input that // would truncate to INT32_MIN. loadConstantFloat32(float(INT32_MIN), ScratchFloat32Reg); - branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.fail); + branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.intOverflow); jump(rejoin); } @@ -772,9 +777,9 @@ MacroAssembler::oolWasmTruncateCheckF64ToI64(FloatRegister input, bool isUnsigne // Handle special values. if (isUnsigned) { loadConstantDouble(-0.0, ScratchDoubleReg); - branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.fail); + branchDouble(Assembler::DoubleGreaterThan, input, ScratchDoubleReg, &traps.intOverflow); loadConstantDouble(-1.0, ScratchDoubleReg); - branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.fail); + branchDouble(Assembler::DoubleLessThanOrEqual, input, ScratchDoubleReg, &traps.intOverflow); jump(rejoin); return; } @@ -783,7 +788,7 @@ MacroAssembler::oolWasmTruncateCheckF64ToI64(FloatRegister input, bool isUnsigne // truncation is INT64_MIN is double(INT64_MIN): exponent is so // high that the highest resolution around is much more than 1. loadConstantDouble(double(int64_t(INT64_MIN)), ScratchDoubleReg); - branchDouble(Assembler::DoubleNotEqual, input, ScratchDoubleReg, &traps.fail); + branchDouble(Assembler::DoubleNotEqual, input, ScratchDoubleReg, &traps.intOverflow); jump(rejoin); } @@ -799,16 +804,16 @@ MacroAssembler::oolWasmTruncateCheckF32ToI64(FloatRegister input, bool isUnsigne // Handle special values. if (isUnsigned) { loadConstantFloat32(-0.0f, ScratchFloat32Reg); - branchFloat(Assembler::DoubleGreaterThan, input, ScratchFloat32Reg, &traps.fail); + branchFloat(Assembler::DoubleGreaterThan, input, ScratchFloat32Reg, &traps.intOverflow); loadConstantFloat32(-1.0f, ScratchFloat32Reg); - branchFloat(Assembler::DoubleLessThanOrEqual, input, ScratchFloat32Reg, &traps.fail); + branchFloat(Assembler::DoubleLessThanOrEqual, input, ScratchFloat32Reg, &traps.intOverflow); jump(rejoin); return; } // We've used vcvtss2sq. See comment in outOfLineWasmTruncateDoubleToInt64. loadConstantFloat32(float(int64_t(INT64_MIN)), ScratchFloat32Reg); - branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.fail); + branchFloat(Assembler::DoubleNotEqual, input, ScratchFloat32Reg, &traps.intOverflow); jump(rejoin); }