mirror of
https://github.com/darlinghq/darling-JavaScriptCore.git
synced 2025-04-08 18:01:37 +00:00
174 lines
5.5 KiB
C++
174 lines
5.5 KiB
C++
/*
|
|
* Copyright (C) 2014 Apple Inc. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "MathCommon.h"
|
|
|
|
#if ENABLE(DFG_JIT)
|
|
|
|
namespace JSC {
|
|
|
|
class CallFrame;
|
|
class JSGlobalObject;
|
|
using EncodedJSValue = int64_t;
|
|
|
|
namespace DFG {
|
|
|
|
// Arith::Mode describes the mode of an arithmetic operation that speculates integer.
|
|
// Note that not all modes are valid for all operations.
|
|
namespace Arith {
|
|
enum Mode {
|
|
NotSet, // Arithmetic mode is either not relevant because we're using doubles anyway or we are at a phase in compilation where we don't know what we're doing, yet. Should never see this after FixupPhase except for nodes that take doubles as inputs already.
|
|
Unchecked, // Don't check anything and just do the direct hardware operation.
|
|
CheckOverflow, // Check for overflow but don't bother with negative zero.
|
|
CheckOverflowAndNegativeZero, // Check for both overflow and negative zero.
|
|
DoOverflow // Up-convert to the smallest type that soundly represents all possible results after input type speculation.
|
|
};
|
|
|
|
// Define the type of operation the rounding operation will perform.
|
|
enum class RoundingMode {
|
|
Int32, // The round operation produces a integer and -0 is considered as 0.
|
|
Int32WithNegativeZeroCheck, // The round operation produces a integer and checks for -0.
|
|
Double // The round operation produce a double. The result can be -0, NaN or (+/-)Infinity.
|
|
};
|
|
|
|
enum class UnaryType : uint32_t {
|
|
#define DFG_ARITH_UNARY_ENUM(capitalizedName, lowerName) capitalizedName,
|
|
FOR_EACH_ARITH_UNARY_OP(DFG_ARITH_UNARY_ENUM)
|
|
#undef DFG_ARITH_UNARY_ENUM
|
|
};
|
|
|
|
using UnaryFunction = double(JIT_OPERATION_ATTRIBUTES*)(double);
|
|
using UnaryOperation = double(JIT_OPERATION_ATTRIBUTES*)(JSGlobalObject*, EncodedJSValue);
|
|
|
|
} // namespace Arith
|
|
|
|
inline bool doesOverflow(Arith::Mode mode)
|
|
{
|
|
switch (mode) {
|
|
case Arith::NotSet:
|
|
ASSERT_NOT_REACHED();
|
|
#if !ASSERT_ENABLED
|
|
FALLTHROUGH;
|
|
#endif
|
|
case Arith::Unchecked:
|
|
case Arith::CheckOverflow:
|
|
case Arith::CheckOverflowAndNegativeZero:
|
|
return false;
|
|
case Arith::DoOverflow:
|
|
return true;
|
|
}
|
|
ASSERT_NOT_REACHED();
|
|
return true;
|
|
}
|
|
|
|
// It's only valid to call this once you've determined that you don't need to *do*
|
|
// overflow. For most nodes, that's implicit.
|
|
inline bool shouldCheckOverflow(Arith::Mode mode)
|
|
{
|
|
switch (mode) {
|
|
case Arith::NotSet:
|
|
case Arith::DoOverflow:
|
|
ASSERT_NOT_REACHED();
|
|
return true;
|
|
case Arith::Unchecked:
|
|
return false;
|
|
case Arith::CheckOverflow:
|
|
case Arith::CheckOverflowAndNegativeZero:
|
|
return true;
|
|
}
|
|
ASSERT_NOT_REACHED();
|
|
return true;
|
|
}
|
|
|
|
inline bool shouldCheckNegativeZero(Arith::Mode mode)
|
|
{
|
|
switch (mode) {
|
|
case Arith::NotSet:
|
|
case Arith::DoOverflow:
|
|
ASSERT_NOT_REACHED();
|
|
return true;
|
|
case Arith::Unchecked:
|
|
case Arith::CheckOverflow:
|
|
return false;
|
|
case Arith::CheckOverflowAndNegativeZero:
|
|
return true;
|
|
}
|
|
ASSERT_NOT_REACHED();
|
|
return true;
|
|
}
|
|
|
|
inline bool subsumes(Arith::Mode earlier, Arith::Mode later)
|
|
{
|
|
switch (earlier) {
|
|
case Arith::CheckOverflow:
|
|
switch (later) {
|
|
case Arith::Unchecked:
|
|
case Arith::CheckOverflow:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
case Arith::CheckOverflowAndNegativeZero:
|
|
switch (later) {
|
|
case Arith::Unchecked:
|
|
case Arith::CheckOverflow:
|
|
case Arith::CheckOverflowAndNegativeZero:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
default:
|
|
return earlier == later;
|
|
}
|
|
}
|
|
|
|
inline bool producesInteger(Arith::RoundingMode mode)
|
|
{
|
|
return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck || mode == Arith::RoundingMode::Int32;
|
|
}
|
|
|
|
inline bool shouldCheckNegativeZero(Arith::RoundingMode mode)
|
|
{
|
|
return mode == Arith::RoundingMode::Int32WithNegativeZeroCheck;
|
|
}
|
|
|
|
Arith::UnaryFunction arithUnaryFunction(Arith::UnaryType);
|
|
Arith::UnaryOperation arithUnaryOperation(Arith::UnaryType);
|
|
|
|
} } // namespace JSC::DFG
|
|
|
|
namespace WTF {
|
|
|
|
class PrintStream;
|
|
void printInternal(PrintStream&, JSC::DFG::Arith::Mode);
|
|
void printInternal(PrintStream&, JSC::DFG::Arith::RoundingMode);
|
|
void printInternal(PrintStream&, JSC::DFG::Arith::UnaryType);
|
|
|
|
} // namespace WTF
|
|
|
|
#endif // ENABLE(DFG_JIT)
|