Commit 362b30eb authored by Nico Hartmann's avatar Nico Hartmann Committed by V8 LUCI CQ

Reland "Reland "[Torque] Generalize Torque literals to larger size""

This is a reland of 517ed4ad

Original change's description:
> Reland "[Torque] Generalize Torque literals to larger size"
>
> Previously, literals in Torque were stored as double values, which
> made it impossible to precisely represent 64 bit integer values.
> This CL replaces the old literal expression with an integer and
> floating point literal expression that are unbounded in size. We
> allow implicit conversion of these literals to arbitary integer
> and floating point types respectively and insert a corresponding
> bounds check into generated CSA.
>
> Changes in the reland: Simplified IntegerLiteral to single digit.
>
> Bug: v8:7793, chromium:1289282
> Change-Id: I31c762c2f31165c7a1d0b07842b764e5851ce189
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3406750
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#78811}

Bug: v8:7793, chromium:1289282
Change-Id: I7aadc4d2c9494f03eae85e94949c8f4cab7a075c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3437047Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78939}
parent bc2a8f64
......@@ -923,6 +923,8 @@ filegroup(
filegroup(
name = "torque_base_files",
srcs = [
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
"src/torque/ast.h",
"src/torque/cc-generator.cc",
"src/torque/cc-generator.h",
......@@ -2802,6 +2804,8 @@ filegroup(
"src/interpreter/interpreter-generator.h",
"src/interpreter/interpreter-intrinsics-generator.cc",
"src/interpreter/interpreter-intrinsics-generator.h",
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
] + select({
"@v8//bazel/config:v8_target_ia32": ["src/builtins/ia32/builtins-ia32.cc"],
"@v8//bazel/config:v8_target_x64": ["src/builtins/x64/builtins-x64.cc"],
......
......@@ -2380,6 +2380,8 @@ v8_source_set("v8_initializers") {
"src/interpreter/interpreter-generator.h",
"src/interpreter/interpreter-intrinsics-generator.cc",
"src/interpreter/interpreter-intrinsics-generator.h",
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
]
if (v8_enable_webassembly) {
......@@ -4872,6 +4874,8 @@ v8_source_set("torque_base") {
visibility = [ ":*" ] # Only targets in this file can depend on this.
sources = [
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
"src/torque/ast.h",
"src/torque/cc-generator.cc",
"src/torque/cc-generator.h",
......
......@@ -301,6 +301,10 @@ class Processor {
// Z := the contents of {accumulator}.
// Assume that this leaves {accumulator} in unusable state.
Status FromString(RWDigits Z, FromStringAccumulator* accumulator);
protected:
// Use {Destroy} or {Destroyer} instead of the destructor directly.
~Processor() = default;
};
inline int AddResultLength(int x_length, int y_length) {
......@@ -418,13 +422,13 @@ class FromStringAccumulator {
: max_digits_(std::max(max_digits, kStackParts)) {}
// Step 2: Call this method to read all characters.
// {Char} should be a character type, such as uint8_t or uint16_t.
// {end} should be one past the last character (i.e. {start == end} would
// indicate an empty string).
// Returns the current position when an invalid character is encountered.
template <class Char>
ALWAYS_INLINE const Char* Parse(const Char* start, const Char* end,
digit_t radix);
// {CharIt} should be a forward iterator and
// std::iterator_traits<CharIt>::value_type shall be a character type, such as
// uint8_t or uint16_t. {end} should be one past the last character (i.e.
// {start == end} would indicate an empty string). Returns the current
// position when an invalid character is encountered.
template <class CharIt>
ALWAYS_INLINE CharIt Parse(CharIt start, CharIt end, digit_t radix);
// Step 3: Check if a result is available, and determine its required
// allocation size (guaranteed to be <= max_digits passed to the constructor).
......@@ -434,14 +438,13 @@ class FromStringAccumulator {
}
// Step 4: Use BigIntProcessor::FromString() to retrieve the result into an
// {RWDigits} struct allocated for the size returned by step 2.
// {RWDigits} struct allocated for the size returned by step 3.
private:
friend class ProcessorImpl;
template <class Char>
ALWAYS_INLINE const Char* ParsePowerTwo(const Char* start, const Char* end,
digit_t radix);
template <class CharIt>
ALWAYS_INLINE CharIt ParsePowerTwo(CharIt start, CharIt end, digit_t radix);
ALWAYS_INLINE bool AddPart(digit_t multiplier, digit_t part, bool is_last);
ALWAYS_INLINE bool AddPart(digit_t part);
......@@ -491,10 +494,9 @@ static constexpr uint8_t kCharValue[] = {
// A space- and time-efficient way to map {2,4,8,16,32} to {1,2,3,4,5}.
static constexpr uint8_t kCharBits[] = {1, 2, 3, 0, 4, 0, 0, 0, 5};
template <class Char>
const Char* FromStringAccumulator::ParsePowerTwo(const Char* current,
const Char* end,
digit_t radix) {
template <class CharIt>
CharIt FromStringAccumulator::ParsePowerTwo(CharIt current, CharIt end,
digit_t radix) {
radix_ = static_cast<uint8_t>(radix);
const int char_bits = kCharBits[radix >> 2];
int bits_left;
......@@ -528,11 +530,10 @@ const Char* FromStringAccumulator::ParsePowerTwo(const Char* current,
return current;
}
template <class Char>
const Char* FromStringAccumulator::Parse(const Char* start, const Char* end,
digit_t radix) {
template <class CharIt>
CharIt FromStringAccumulator::Parse(CharIt start, CharIt end, digit_t radix) {
BIGINT_H_DCHECK(2 <= radix && radix <= 36);
const Char* current = start;
CharIt current = start;
#if !HAVE_BUILTIN_MUL_OVERFLOW
const digit_t kMaxMultiplier = (~digit_t{0}) / radix;
#endif
......
......@@ -127,6 +127,7 @@ class ToStringFormatter {
out_end_(out + chars_available),
out_(out_end_),
processor_(processor) {
digits_.Normalize();
DCHECK(chars_available >= ToStringResultLength(digits_, radix_, sign_));
}
......
......@@ -548,7 +548,7 @@ macro JoinStackPopInline(implicit context: Context)(receiver: JSReceiver):
// Builtin call was not nested (receiver is the first entry) and
// did not contain other nested arrays that expanded the stack.
if (stack.objects[0] == receiver && len == kMinJoinStackSize) {
StoreFixedArrayElement(stack, 0, TheHole, SKIP_WRITE_BARRIER);
stack.objects[0] = TheHole;
} else
deferred {
JoinStackPop(stack, receiver);
......
......@@ -27,6 +27,8 @@
type void;
type never;
type IntegerLiteral constexpr 'IntegerLiteral';
type Tagged generates 'TNode<MaybeObject>' constexpr 'MaybeObject';
type StrongTagged extends Tagged
generates 'TNode<Object>' constexpr 'Object';
......@@ -613,7 +615,7 @@ transitioning macro ToIntegerImpl(implicit context: Context)(input: JSAny):
if (Float64IsNaN(value)) return SmiConstant(0);
value = math::Float64Trunc(value);
// ToInteger normalizes -0 to +0.
if (value == 0.0) return SmiConstant(0);
if (value == 0) return SmiConstant(0);
const result = ChangeFloat64ToTagged(value);
dcheck(IsNumberNormalized(result));
return result;
......@@ -989,6 +991,38 @@ extern operator '==' macro ConstexprInt32Equal(
extern operator '!=' macro ConstexprInt32NotEqual(
constexpr int32, constexpr int32): constexpr bool;
// IntegerLiteral overloads
extern macro ConstexprIntegerLiteralToInt31(constexpr IntegerLiteral):
constexpr int31;
extern macro ConstexprIntegerLiteralToInt32(constexpr IntegerLiteral):
constexpr int32;
extern macro ConstexprIntegerLiteralToUint32(constexpr IntegerLiteral):
constexpr uint32;
extern macro ConstexprIntegerLiteralToUint64(constexpr IntegerLiteral):
constexpr uint64;
extern macro ConstexprIntegerLiteralToIntptr(constexpr IntegerLiteral):
constexpr intptr;
extern macro ConstexprIntegerLiteralToUintptr(constexpr IntegerLiteral):
constexpr uintptr;
extern macro ConstexprIntegerLiteralToInt8(constexpr IntegerLiteral):
constexpr int8;
extern macro ConstexprIntegerLiteralToUint8(constexpr IntegerLiteral):
constexpr uint8;
extern macro ConstexprIntegerLiteralToFloat64(constexpr IntegerLiteral):
constexpr float64;
extern operator '==' macro ConstexprIntegerLiteralEqual(
constexpr IntegerLiteral, constexpr IntegerLiteral): constexpr bool;
extern operator '+' macro ConstexprIntegerLiteralAdd(
constexpr IntegerLiteral,
constexpr IntegerLiteral): constexpr IntegerLiteral;
extern operator '<<' macro ConstexprIntegerLiteralLeftShift(
constexpr IntegerLiteral,
constexpr IntegerLiteral): constexpr IntegerLiteral;
extern operator '|' macro ConstexprIntegerLiteralBitwiseOr(
constexpr IntegerLiteral,
constexpr IntegerLiteral): constexpr IntegerLiteral;
extern operator '==' macro Word32Equal(int32, int32): bool;
extern operator '==' macro Word32Equal(uint32, uint32): bool;
extern operator '!=' macro Word32NotEqual(int32, int32): bool;
......@@ -1178,19 +1212,29 @@ extern macro IntPtrConstant(constexpr int32): intptr;
extern macro Uint16Constant(constexpr uint16): uint16;
extern macro Int32Constant(constexpr int31): int31;
extern macro Int32Constant(constexpr int32): int32;
macro Int32Constant(i: constexpr IntegerLiteral): int32 {
return Int32Constant(ConstexprIntegerLiteralToInt32(i));
}
extern macro Int64Constant(constexpr int64): int64;
extern macro Uint64Constant(constexpr uint64): uint64;
extern macro Float64Constant(constexpr int32): float64;
extern macro Float64Constant(constexpr float64): float64;
extern macro Float64Constant(constexpr IntegerLiteral): float64;
extern macro SmiConstant(constexpr int31): Smi;
extern macro SmiConstant(constexpr Smi): Smi;
extern macro SmiConstant(constexpr MessageTemplate): Smi;
extern macro SmiConstant(constexpr bool): Smi;
extern macro SmiConstant(constexpr uint32): Smi;
macro SmiConstant(il: constexpr IntegerLiteral): Smi {
return SmiConstant(ConstexprIntegerLiteralToInt31(il));
}
extern macro BoolConstant(constexpr bool): bool;
extern macro StringConstant(constexpr string): String;
extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot;
extern macro IntPtrConstant(constexpr intptr): intptr;
macro IntPtrConstant(il: constexpr IntegerLiteral): intptr {
return IntPtrConstant(ConstexprIntegerLiteralToIntptr(il));
}
extern macro PointerConstant(constexpr RawPtr): RawPtr;
extern macro SingleCharacterStringConstant(constexpr string): String;
extern macro Float64SilenceNaN(float64): float64;
......
......@@ -4,6 +4,59 @@
intrinsic %FromConstexpr<To: type, From: type>(b: From): To;
macro FromConstexpr<To: type, From: type>(o: From): To;
// Conversions for IntegerLiteral
FromConstexpr<intptr, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
intptr {
return ConstexprIntegerLiteralToIntptr(i);
}
FromConstexpr<uintptr, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
uintptr {
return ConstexprIntegerLiteralToUintptr(i);
}
FromConstexpr<int32, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
int32 {
return ConstexprIntegerLiteralToInt32(i);
}
FromConstexpr<uint32, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
uint32 {
return ConstexprIntegerLiteralToUint32(i);
}
FromConstexpr<int31, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
int31 {
return ConstexprIntegerLiteralToInt31(i);
}
FromConstexpr<int8, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
int8 {
return ConstexprIntegerLiteralToInt8(i);
}
FromConstexpr<uint8, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
uint8 {
return ConstexprIntegerLiteralToUint8(i);
}
FromConstexpr<uint64, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
uint64 {
return ConstexprIntegerLiteralToUint64(i);
}
FromConstexpr<constexpr int31, constexpr IntegerLiteral>(
i: constexpr IntegerLiteral): constexpr int31 {
return ConstexprIntegerLiteralToInt31(i);
}
FromConstexpr<constexpr int32, constexpr IntegerLiteral>(
i: constexpr IntegerLiteral): constexpr int32 {
return ConstexprIntegerLiteralToInt32(i);
}
FromConstexpr<Number, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
Number {
return NumberConstant(ConstexprIntegerLiteralToFloat64(i));
}
FromConstexpr<Smi, constexpr IntegerLiteral>(i: constexpr IntegerLiteral): Smi {
return Convert<Smi>(ConstexprIntegerLiteralToInt31(i));
}
FromConstexpr<char8, constexpr IntegerLiteral>(i: constexpr IntegerLiteral):
char8 {
return %RawDownCast<char8>(FromConstexpr<uint8>(i));
}
FromConstexpr<int31, constexpr int31>(i: constexpr int31): int31 {
return %FromConstexpr<int31>(i);
}
......@@ -325,6 +378,10 @@ Convert<intptr, Number>(n: Number): intptr {
Convert<bint, int32>(v: int32): bint {
return IntPtrToBInt(Convert<intptr>(v));
}
FromConstexpr<float64, constexpr IntegerLiteral>(v: constexpr IntegerLiteral):
float64 {
return ConstexprIntegerLiteralToFloat64(v);
}
extern macro IntPtrToBInt(intptr): bint;
Convert<bint, intptr>(v: intptr): bint {
return IntPtrToBInt(v);
......
......@@ -90,7 +90,7 @@ macro NumberToStringSmi(x: int32, radix: int32): String labels Slow {
// Calculate length and pre-allocate the result string.
let temp: int32 = n;
let length: int32 = isNegative ? 1 : 0;
let length: int32 = isNegative ? Convert<int32>(1) : Convert<int32>(0);
while (temp > 0) {
temp = temp / radix;
length = length + 1;
......@@ -277,7 +277,7 @@ transitioning builtin ParseInt(implicit context: Context)(
// the runtime for the range [0,1[ because the result could be -0.
const kMaxAbsValue: float64 = 2147483648.0;
const absInput: float64 = math::Float64Abs(asFloat64);
if (absInput < kMaxAbsValue && absInput >= 1) goto Int32(asInt32);
if (absInput < kMaxAbsValue && absInput >= 1.0) goto Int32(asInt32);
goto CallRuntime;
}
case (s: String): {
......@@ -690,7 +690,7 @@ builtin Negate(implicit context: Context)(value: JSAny): Numeric {
} label Smi(s: Smi) {
return SmiMul(s, -1);
} label HeapNumber(h: HeapNumber) {
return AllocateHeapNumberWithValue(Convert<float64>(h) * -1);
return AllocateHeapNumberWithValue(Convert<float64>(h) * -1.0);
} label BigInt(b: BigInt) {
tail runtime::BigIntUnaryOp(
context, b, SmiTag<Operation>(Operation::kNegate));
......
......@@ -55,7 +55,7 @@ transitioning javascript builtin StringPrototypeRepeat(
// 4. If n < 0, throw a RangeError exception.
// 5. If n is +∞, throw a RangeError exception.
if (n == V8_INFINITY || n < 0.0) goto InvalidCount;
if (n == V8_INFINITY || n < 0) goto InvalidCount;
// 6. If n is 0, return the empty String.
if (s.length_uint32 == 0) goto EmptyString;
......
......@@ -105,6 +105,10 @@ struct Slice<T: type, Reference: type> {
return this.TryAtIndex(Convert<intptr>(index)) otherwise unreachable;
}
macro AtIndex(index: constexpr IntegerLiteral): Reference {
return this.AtIndex(FromConstexpr<uintptr>(index));
}
macro AtIndex(index: constexpr int31): Reference {
const i: intptr = Convert<intptr>(index);
return this.TryAtIndex(i) otherwise unreachable;
......
......@@ -17,6 +17,7 @@
#include "src/heap/heap-inl.h" // For MemoryChunk. TODO(jkummerow): Drop.
#include "src/heap/memory-chunk.h"
#include "src/logging/counters.h"
#include "src/numbers/integer-literal-inl.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/cell.h"
#include "src/objects/descriptor-array.h"
......@@ -14892,6 +14893,19 @@ void CodeStubAssembler::Print(const char* prefix,
CallRuntime(Runtime::kDebugPrint, NoContextConstant(), arg);
}
IntegerLiteral CodeStubAssembler::ConstexprIntegerLiteralAdd(
const IntegerLiteral& lhs, const IntegerLiteral& rhs) {
return lhs + rhs;
}
IntegerLiteral CodeStubAssembler::ConstexprIntegerLiteralLeftShift(
const IntegerLiteral& lhs, const IntegerLiteral& rhs) {
return lhs << rhs;
}
IntegerLiteral CodeStubAssembler::ConstexprIntegerLiteralBitwiseOr(
const IntegerLiteral& lhs, const IntegerLiteral& rhs) {
return lhs | rhs;
}
void CodeStubAssembler::PerformStackCheck(TNode<Context> context) {
Label ok(this), stack_check_interrupt(this, Label::kDeferred);
......
......@@ -13,6 +13,7 @@
#include "src/common/globals.h"
#include "src/common/message-template.h"
#include "src/compiler/code-assembler.h"
#include "src/numbers/integer-literal.h"
#include "src/objects/arguments.h"
#include "src/objects/bigint.h"
#include "src/objects/cell.h"
......@@ -3776,6 +3777,45 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
}
bool ConstexprBoolNot(bool value) { return !value; }
int31_t ConstexprIntegerLiteralToInt31(const IntegerLiteral& i) {
return int31_t(i.To<int32_t>());
}
int32_t ConstexprIntegerLiteralToInt32(const IntegerLiteral& i) {
return i.To<int32_t>();
}
uint32_t ConstexprIntegerLiteralToUint32(const IntegerLiteral& i) {
return i.To<uint32_t>();
}
int8_t ConstexprIntegerLiteralToInt8(const IntegerLiteral& i) {
return i.To<int8_t>();
}
uint8_t ConstexprIntegerLiteralToUint8(const IntegerLiteral& i) {
return i.To<uint8_t>();
}
uint64_t ConstexprIntegerLiteralToUint64(const IntegerLiteral& i) {
return i.To<uint64_t>();
}
intptr_t ConstexprIntegerLiteralToIntptr(const IntegerLiteral& i) {
return i.To<intptr_t>();
}
uintptr_t ConstexprIntegerLiteralToUintptr(const IntegerLiteral& i) {
return i.To<uintptr_t>();
}
double ConstexprIntegerLiteralToFloat64(const IntegerLiteral& i) {
int64_t i_value = i.To<int64_t>();
double d_value = static_cast<double>(i_value);
CHECK_EQ(i_value, static_cast<int64_t>(d_value));
return d_value;
}
bool ConstexprIntegerLiteralEqual(IntegerLiteral lhs, IntegerLiteral rhs) {
return lhs == rhs;
}
IntegerLiteral ConstexprIntegerLiteralAdd(const IntegerLiteral& lhs,
const IntegerLiteral& rhs);
IntegerLiteral ConstexprIntegerLiteralLeftShift(const IntegerLiteral& lhs,
const IntegerLiteral& rhs);
IntegerLiteral ConstexprIntegerLiteralBitwiseOr(const IntegerLiteral& lhs,
const IntegerLiteral& rhs);
bool ConstexprInt31Equal(int31_t a, int31_t b) { return a == b; }
bool ConstexprInt31NotEqual(int31_t a, int31_t b) { return a != b; }
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_NUMBERS_INTEGER_LITERAL_INL_H_
#define V8_NUMBERS_INTEGER_LITERAL_INL_H_
#include "src/numbers/integer-literal.h"
namespace v8 {
namespace internal {
inline std::string IntegerLiteral::ToString() const {
if (negative_) return std::string("-") + std::to_string(absolute_value_);
return std::to_string(absolute_value_);
}
inline IntegerLiteral operator<<(const IntegerLiteral& x,
const IntegerLiteral& y) {
DCHECK(!y.is_negative());
DCHECK_LT(y.absolute_value(), sizeof(uint64_t) * kBitsPerByte);
return IntegerLiteral(x.is_negative(), x.absolute_value()
<< y.absolute_value());
}
inline IntegerLiteral operator+(const IntegerLiteral& x,
const IntegerLiteral& y) {
if (x.is_negative() == y.is_negative()) {
DCHECK_GE(x.absolute_value() + y.absolute_value(), x.absolute_value());
return IntegerLiteral(x.is_negative(),
x.absolute_value() + y.absolute_value());
}
if (x.absolute_value() >= y.absolute_value()) {
return IntegerLiteral(x.is_negative(),
x.absolute_value() - y.absolute_value());
}
return IntegerLiteral(!x.is_negative(),
y.absolute_value() - x.absolute_value());
}
} // namespace internal
} // namespace v8
#endif // V8_NUMBERS_INTEGER_LITERAL_INL_H_
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_NUMBERS_INTEGER_LITERAL_H_
#define V8_NUMBERS_INTEGER_LITERAL_H_
#include "src/base/optional.h"
#include "src/common/globals.h"
namespace v8 {
namespace internal {
class IntegerLiteral {
public:
IntegerLiteral(bool negative, uint64_t absolute_value)
: negative_(negative), absolute_value_(absolute_value) {
if (absolute_value == 0) negative_ = false;
}
template <typename T>
explicit IntegerLiteral(T value) : IntegerLiteral(value, true) {}
bool is_negative() const { return negative_; }
uint64_t absolute_value() const { return absolute_value_; }
template <typename T>
bool IsRepresentableAs() const {
static_assert(std::is_integral<T>::value, "Integral type required");
static_assert(sizeof(T) <= sizeof(uint64_t),
"Types with more than 64 bits are not supported");
return Compare(IntegerLiteral(std::numeric_limits<T>::min(), false)) >= 0 &&
Compare(IntegerLiteral(std::numeric_limits<T>::max(), false)) <= 0;
}
template <typename T>
T To() const {
static_assert(std::is_integral<T>::value, "Integral type required");
DCHECK(IsRepresentableAs<T>());
uint64_t v = absolute_value_;
if (negative_) v = ~v + 1;
return static_cast<T>(v);
}
template <typename T>
base::Optional<T> TryTo() const {
static_assert(std::is_integral<T>::value, "Integral type required");
if (!IsRepresentableAs<T>()) return base::nullopt;
return To<T>();
}
int Compare(const IntegerLiteral& other) const {
if (absolute_value_ == other.absolute_value_) {
if (absolute_value_ == 0 || negative_ == other.negative_) return 0;
return negative_ ? -1 : 1;
} else if (absolute_value_ < other.absolute_value_) {
return other.negative_ ? 1 : -1;
} else {
return negative_ ? -1 : 1;
}
}
std::string ToString() const;
private:
template <typename T>
explicit IntegerLiteral(T value, bool perform_dcheck) : negative_(false) {
static_assert(std::is_integral<T>::value, "Integral type required");
absolute_value_ = static_cast<uint64_t>(value);
if (value < T(0)) {
negative_ = true;
absolute_value_ = ~absolute_value_ + 1;
}
if (perform_dcheck) DCHECK_EQ(To<T>(), value);
}
bool negative_;
uint64_t absolute_value_;
};
inline bool operator==(const IntegerLiteral& x, const IntegerLiteral& y) {
return x.Compare(y) == 0;
}
inline bool operator!=(const IntegerLiteral& x, const IntegerLiteral& y) {
return x.Compare(y) != 0;
}
inline std::ostream& operator<<(std::ostream& stream,
const IntegerLiteral& literal) {
return stream << literal.ToString();
}
inline IntegerLiteral operator|(const IntegerLiteral& x,
const IntegerLiteral& y) {
DCHECK(!x.is_negative());
DCHECK(!y.is_negative());
return IntegerLiteral(false, x.absolute_value() | y.absolute_value());
}
IntegerLiteral operator<<(const IntegerLiteral& x, const IntegerLiteral& y);
IntegerLiteral operator+(const IntegerLiteral& x, const IntegerLiteral& y);
} // namespace internal
} // namespace v8
#endif // V8_NUMBERS_INTEGER_LITERAL_H_
......@@ -5,12 +5,11 @@
#ifndef V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_
#define V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_
#include "src/objects/descriptor-array.h"
#include "src/execution/isolate.h"
#include "src/handles/maybe-handles-inl.h"
#include "src/heap/heap-write-barrier.h"
#include "src/heap/heap.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/field-type.h"
#include "src/objects/heap-object-inl.h"
#include "src/objects/lookup-cache-inl.h"
......
......@@ -5,13 +5,12 @@
#ifndef V8_OBJECTS_FIXED_ARRAY_INL_H_
#define V8_OBJECTS_FIXED_ARRAY_INL_H_
#include "src/objects/fixed-array.h"
#include "src/handles/handles-inl.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/numbers/conversions.h"
#include "src/objects/bigint.h"
#include "src/objects/compressed-slots.h"
#include "src/objects/fixed-array.h"
#include "src/objects/map.h"
#include "src/objects/maybe-object-inl.h"
#include "src/objects/objects-inl.h"
......
......@@ -80,7 +80,7 @@ class TurbofanOtherNumberConstantType extends TurbofanType {
}
macro IsMinusZero(x: float64): bool {
return x == 0 && 1 / x < 0;
return x == 0 && 1.0 / x < 0;
}
macro TestTurbofanBitsetType(
......@@ -94,13 +94,13 @@ macro TestTurbofanBitsetType(
if (IsInteger(value)) {
if (IsMinusZero(valueF)) {
return bitsetLow.minus_zero;
} else if (valueF < Convert<float64>(-0x80000000)) {
} else if (valueF < -0x80000000) {
return bitsetLow.other_number;
} else if (valueF < -0x40000000) {
return bitsetLow.other_signed32;
} else if (valueF < 0) {
return bitsetLow.negative31;
} else if (valueF < Convert<float64>(0x40000000)) {
} else if (valueF < 0x40000000) {
return bitsetLow.unsigned30;
} else if (valueF < 0x80000000) {
return bitsetLow.other_unsigned31;
......
......@@ -14,6 +14,7 @@
#include <vector>
#include "src/base/optional.h"
#include "src/numbers/integer-literal.h"
#include "src/torque/constants.h"
#include "src/torque/source-positions.h"
#include "src/torque/utils.h"
......@@ -33,7 +34,8 @@ namespace torque {
V(ConditionalExpression) \
V(IdentifierExpression) \
V(StringLiteralExpression) \
V(NumberLiteralExpression) \
V(IntegerLiteralExpression) \
V(FloatingPointLiteralExpression) \
V(FieldAccessExpression) \
V(ElementAccessExpression) \
V(DereferenceExpression) \
......@@ -459,16 +461,28 @@ struct StringLiteralExpression : Expression {
std::string literal;
};
struct NumberLiteralExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(NumberLiteralExpression)
NumberLiteralExpression(SourcePosition pos, double number)
: Expression(kKind, pos), number(number) {}
struct IntegerLiteralExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(IntegerLiteralExpression)
IntegerLiteralExpression(SourcePosition pos, IntegerLiteral value)
: Expression(kKind, pos), value(std::move(value)) {}
void VisitAllSubExpressions(VisitCallback callback) override {
callback(this);
}
double number;
IntegerLiteral value;
};
struct FloatingPointLiteralExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(FloatingPointLiteralExpression)
FloatingPointLiteralExpression(SourcePosition pos, double value)
: Expression(kKind, pos), value(value) {}
void VisitAllSubExpressions(VisitCallback callback) override {
callback(this);
}
double value;
};
struct ElementAccessExpression : LocationExpression {
......
......@@ -67,6 +67,8 @@ static const char* const FLOAT64_OR_HOLE_TYPE_STRING = "float64_or_hole";
static const char* const CONST_INT31_TYPE_STRING = "constexpr int31";
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
static const char* const INTEGER_LITERAL_TYPE_STRING =
"constexpr IntegerLiteral";
static const char* const TORQUE_INTERNAL_NAMESPACE_STRING = "torque_internal";
static const char* const MUTABLE_REFERENCE_TYPE_STRING = "MutableReference";
static const char* const CONST_REFERENCE_TYPE_STRING = "ConstReference";
......
......@@ -127,6 +127,7 @@ LexerResult Lexer::RunLexer(const std::string& input) {
while (pos != end) {
token_start = pos;
Symbol* symbol = MatchToken(&pos, end);
DCHECK_IMPLIES(symbol != nullptr, pos != token_start);
InputPosition token_end = pos;
line_column_tracker.Advance(token_start, token_end);
if (!symbol) {
......
......@@ -44,6 +44,8 @@ enum class ParseResultHolderBase::TypeId {
kStdString,
kBool,
kInt32,
kDouble,
kIntegerLiteral,
kStdVectorOfString,
kExpressionPtr,
kIdentifierPtr,
......
......@@ -10,6 +10,7 @@
#include "src/base/optional.h"
#include "src/common/globals.h"
#include "src/numbers/integer-literal-inl.h"
#include "src/torque/cc-generator.h"
#include "src/torque/cfg.h"
#include "src/torque/constants.h"
......@@ -182,6 +183,7 @@ void ImplementationVisitor::BeginDebugMacrosFile() {
header << "#ifndef " << kHeaderDefine << "\n";
header << "#define " << kHeaderDefine << "\n\n";
header << "#include \"tools/debug_helper/debug-helper-internal.h\"\n";
header << "#include \"src/numbers/integer-literal.h\"\n";
header << "\n";
header << "namespace v8 {\n"
......@@ -943,22 +945,20 @@ VisitResult ImplementationVisitor::Visit(AssignmentExpression* expr) {
return scope.Yield(assignment_value);
}
VisitResult ImplementationVisitor::Visit(NumberLiteralExpression* expr) {
VisitResult ImplementationVisitor::Visit(FloatingPointLiteralExpression* expr) {
const Type* result_type = TypeOracle::GetConstFloat64Type();
if (expr->number >= std::numeric_limits<int32_t>::min() &&
expr->number <= std::numeric_limits<int32_t>::max()) {
int32_t i = static_cast<int32_t>(expr->number);
if (i == expr->number) {
if ((i >> 30) == (i >> 31)) {
result_type = TypeOracle::GetConstInt31Type();
} else {
result_type = TypeOracle::GetConstInt32Type();
}
}
}
std::stringstream str;
str << std::setprecision(std::numeric_limits<double>::digits10 + 1)
<< expr->number;
<< expr->value;
return VisitResult{result_type, str.str()};
}
VisitResult ImplementationVisitor::Visit(IntegerLiteralExpression* expr) {
const Type* result_type = TypeOracle::GetIntegerLiteralType();
std::stringstream str;
str << "IntegerLiteral("
<< (expr->value.is_negative() ? "true, 0x" : "false, 0x") << std::hex
<< expr->value.absolute_value() << std::dec << "ull)";
return VisitResult{result_type, str.str()};
}
......@@ -2848,7 +2848,9 @@ VisitResult ImplementationVisitor::GenerateCall(
// If we're currently generating a C++ macro and it's calling another macro,
// then we need to make sure that we also generate C++ code for the called
// macro within the same -inl.inc file.
if (output_type_ == OutputType::kCC && !inline_macro) {
if ((output_type_ == OutputType::kCC ||
output_type_ == OutputType::kCCDebug) &&
!inline_macro) {
if (auto* torque_macro = TorqueMacro::DynamicCast(macro)) {
auto* streams = CurrentFileStreams::Get();
SourceId file = streams ? streams->file : SourceId::Invalid();
......@@ -2862,14 +2864,32 @@ VisitResult ImplementationVisitor::GenerateCall(
std::stringstream result;
result << "(";
bool first = true;
if (auto* extern_macro = ExternMacro::DynamicCast(macro)) {
result << extern_macro->external_assembler_name() << "(state_)."
<< extern_macro->ExternalName() << "(";
} else {
result << macro->ExternalName() << "(state_";
first = false;
switch (output_type_) {
case OutputType::kCSA: {
if (auto* extern_macro = ExternMacro::DynamicCast(macro)) {
result << extern_macro->external_assembler_name() << "(state_)."
<< extern_macro->ExternalName() << "(";
} else {
result << macro->ExternalName() << "(state_";
first = false;
}
break;
}
case OutputType::kCC: {
auto* extern_macro = ExternMacro::DynamicCast(macro);
CHECK_NOT_NULL(extern_macro);
result << extern_macro->CCName() << "(";
break;
}
case OutputType::kCCDebug: {
auto* extern_macro = ExternMacro::DynamicCast(macro);
CHECK_NOT_NULL(extern_macro);
result << extern_macro->CCDebugName() << "(accessor";
first = false;
break;
}
}
for (VisitResult arg : arguments.parameters) {
for (VisitResult arg : converted_arguments) {
DCHECK(!arg.IsOnStack());
if (!first) {
result << ", ";
......
......@@ -555,7 +555,8 @@ class ImplementationVisitor {
VisitResult Visit(IncrementDecrementExpression* expr);
VisitResult Visit(AssignmentExpression* expr);
VisitResult Visit(StringLiteralExpression* expr);
VisitResult Visit(NumberLiteralExpression* expr);
VisitResult Visit(FloatingPointLiteralExpression* expr);
VisitResult Visit(IntegerLiteralExpression* expr);
VisitResult Visit(AssumeTypeImpossibleExpression* expr);
VisitResult Visit(TryLabelExpression* expr);
VisitResult Visit(StatementExpression* expr);
......
......@@ -10,6 +10,8 @@
#include <cstdint>
#include "src/numbers/integer-literal.h"
namespace v8 {
namespace internal {
......@@ -35,6 +37,15 @@ inline uintptr_t Unsigned(intptr_t s) { return static_cast<uintptr_t>(s); }
#endif
inline bool Word32Equal(uint32_t a, uint32_t b) { return a == b; }
inline bool Word32NotEqual(uint32_t a, uint32_t b) { return a != b; }
inline int32_t ConstexprIntegerLiteralToInt32(const IntegerLiteral& i) {
return i.To<int32_t>();
}
inline int31_t ConstexprIntegerLiteralToInt31(const IntegerLiteral& i) {
return int31_t(ConstexprIntegerLiteralToInt32(i));
}
inline intptr_t ConstexprIntegerLiteralToIntptr(const IntegerLiteral& i) {
return i.To<intptr_t>();
}
} // namespace CodeStubAssembler
} // namespace TorqueRuntimeMacroShims
......
......@@ -93,6 +93,12 @@ template <>
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<int32_t>::id =
ParseResultTypeId::kInt32;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<double>::id =
ParseResultTypeId::kDouble;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<IntegerLiteral>::id = ParseResultTypeId::kIntegerLiteral;
template <>
V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<std::vector<std::string>>::id =
ParseResultTypeId::kStdVectorOfString;
......@@ -866,8 +872,8 @@ bool ProcessIfAnnotation(ParseResultIterator* child_results) {
return true;
}
base::Optional<ParseResult> MakeInt32(ParseResultIterator* child_results) {
std::string value = child_results->NextAs<std::string>();
base::Optional<ParseResult> YieldInt32(ParseResultIterator* child_results) {
std::string value = child_results->matched_input().ToString();
size_t num_chars_converted = 0;
int result = 0;
try {
......@@ -884,6 +890,43 @@ base::Optional<ParseResult> MakeInt32(ParseResultIterator* child_results) {
return ParseResult{result};
}
base::Optional<ParseResult> YieldDouble(ParseResultIterator* child_results) {
std::string value = child_results->matched_input().ToString();
size_t num_chars_converted = 0;
double result = 0;
try {
result = std::stod(value, &num_chars_converted);
} catch (const std::out_of_range&) {
Error("double literal out-of-range");
return ParseResult{result};
}
// Tokenizer shouldn't have included extra trailing characters.
DCHECK_EQ(num_chars_converted, value.size());
return ParseResult{result};
}
base::Optional<ParseResult> YieldIntegerLiteral(
ParseResultIterator* child_results) {
std::string value = child_results->matched_input().ToString();
// Consume a leading minus.
bool negative = false;
if (value.size() > 0 && value[0] == '-') {
negative = true;
value = value.substr(1);
}
uint64_t absolute_value;
try {
size_t parsed = 0;
absolute_value = std::stoull(value, &parsed, 0);
DCHECK_EQ(parsed, value.size());
} catch (const std::invalid_argument&) {
Error("integer literal could not be parsed").Throw();
} catch (const std::out_of_range&) {
Error("integer literal value out of range").Throw();
}
return ParseResult(IntegerLiteral(negative, absolute_value));
}
base::Optional<ParseResult> MakeStringAnnotationParameter(
ParseResultIterator* child_results) {
std::string value = child_results->NextAs<std::string>();
......@@ -1904,29 +1947,17 @@ base::Optional<ParseResult> MakeAssignmentExpression(
return ParseResult{result};
}
base::Optional<ParseResult> MakeNumberLiteralExpression(
base::Optional<ParseResult> MakeFloatingPointLiteralExpression(
ParseResultIterator* child_results) {
auto number = child_results->NextAs<std::string>();
// TODO(turbofan): Support 64bit literals.
// Meanwhile, we type it as constexpr float64 when out of int32 range.
double value = 0;
try {
#if defined(V8_OS_SOLARIS)
// stod() on Solaris does not currently support hex strings. Use strtol()
// specifically for hex literals until stod() support is available.
if (number.find("0x") == std::string::npos &&
number.find("0X") == std::string::npos) {
value = std::stod(number);
} else {
value = static_cast<double>(strtol(number.c_str(), nullptr, 0));
}
#else
value = std::stod(number);
#endif // !defined(V8_OS_SOLARIS)
} catch (const std::out_of_range&) {
Error("double literal out-of-range").Throw();
}
Expression* result = MakeNode<NumberLiteralExpression>(value);
auto value = child_results->NextAs<double>();
Expression* result = MakeNode<FloatingPointLiteralExpression>(value);
return ParseResult{result};
}
base::Optional<ParseResult> MakeIntegerLiteralExpression(
ParseResultIterator* child_results) {
auto value = child_results->NextAs<IntegerLiteral>();
Expression* result = MakeNode<IntegerLiteralExpression>(std::move(value));
return ParseResult{result};
}
......@@ -2086,8 +2117,19 @@ base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
// Internally, an optional field is just an indexed field where the count
// is zero or one.
index = MakeNode<ConditionalExpression>(
*index, MakeNode<NumberLiteralExpression>(1),
MakeNode<NumberLiteralExpression>(0));
*index,
MakeCall(
MakeNode<Identifier>("FromConstexpr"),
{MakeNode<BasicTypeExpression>(std::vector<std::string>{},
MakeNode<Identifier>("intptr"),
std::vector<TypeExpression*>{})},
{MakeNode<IntegerLiteralExpression>(IntegerLiteral(1))}, {}),
MakeCall(
MakeNode<Identifier>("FromConstexpr"),
{MakeNode<BasicTypeExpression>(std::vector<std::string>{},
MakeNode<Identifier>("intptr"),
std::vector<TypeExpression*>{})},
{MakeNode<IntegerLiteralExpression>(IntegerLiteral(0))}, {}));
}
index_info = ClassFieldIndexInfo{*index, optional};
}
......@@ -2206,12 +2248,24 @@ struct TorqueGrammar : Grammar {
return false;
}
static bool MatchDecimalLiteral(InputPosition* pos) {
static bool MatchIntegerLiteral(InputPosition* pos) {
InputPosition current = *pos;
bool found_digit = false;
MatchString("-", &current);
while (MatchChar(std::isdigit, &current)) found_digit = true;
if (found_digit) {
*pos = current;
return true;
}
return false;
}
static bool MatchFloatingPointLiteral(InputPosition* pos) {
InputPosition current = *pos;
bool found_digit = false;
MatchString("-", &current);
while (MatchChar(std::isdigit, &current)) found_digit = true;
MatchString(".", &current);
if (!MatchString(".", &current)) return false;
while (MatchChar(std::isdigit, &current)) found_digit = true;
if (!found_digit) return false;
*pos = current;
......@@ -2285,13 +2339,18 @@ struct TorqueGrammar : Grammar {
// Result: std::string
Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)};
// Result: std::string
Symbol decimalLiteral = {
Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput),
Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)};
// Result: IntegerLiteral
Symbol integerLiteral = {
Rule({Pattern(MatchIntegerLiteral)}, YieldIntegerLiteral),
Rule({Pattern(MatchHexLiteral)}, YieldIntegerLiteral)};
// Result: double
Symbol floatingPointLiteral = {
Rule({Pattern(MatchFloatingPointLiteral)}, YieldDouble)};
// Result: int32_t
Symbol int32Literal = {Rule({&decimalLiteral}, MakeInt32)};
Symbol int32Literal = {Rule({Pattern(MatchIntegerLiteral)}, YieldInt32),
Rule({Pattern(MatchHexLiteral)}, YieldInt32)};
// Result: AnnotationParameter
Symbol annotationParameter = {
......@@ -2510,7 +2569,8 @@ struct TorqueGrammar : Grammar {
MakeReferenceFieldAccessExpression),
Rule({&primaryExpression, Token("["), expression, Token("]")},
MakeElementAccessExpression),
Rule({&decimalLiteral}, MakeNumberLiteralExpression),
Rule({&integerLiteral}, MakeIntegerLiteralExpression),
Rule({&floatingPointLiteral}, MakeFloatingPointLiteralExpression),
Rule({&stringLiteral}, MakeStringLiteralExpression),
Rule({&simpleType, &initializerList}, MakeStructExpression),
Rule({&newExpression}),
......
......@@ -315,6 +315,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return Get().GetBuiltinType(CONST_FLOAT64_TYPE_STRING);
}
static const Type* GetIntegerLiteralType() {
return Get().GetBuiltinType(INTEGER_LITERAL_TYPE_STRING);
}
static const Type* GetNeverType() {
return Get().GetBuiltinType(NEVER_TYPE_STRING);
}
......
......@@ -459,12 +459,12 @@ void TypeVisitor::VisitClassFieldsAndMethods(
field_size * ResidueClass::Unknown());
if (auto literal =
NumberLiteralExpression::DynamicCast(field.index->expr)) {
size_t value = static_cast<size_t>(literal->number);
if (value != literal->number) {
Error("non-integral array length").Position(field.pos);
IntegerLiteralExpression::DynamicCast(field.index->expr)) {
if (auto value = literal->value.TryTo<size_t>()) {
field_size *= *value;
} else {
Error("Not a valid field index").Position(field.pos);
}
field_size *= value;
} else {
field_size *= ResidueClass::Unknown();
}
......
......@@ -850,7 +850,7 @@ void ClassType::GenerateSliceAccessor(size_t field_index) {
if (field.offset.has_value()) {
offset_expression =
MakeNode<NumberLiteralExpression>(static_cast<double>(*field.offset));
MakeNode<IntegerLiteralExpression>(IntegerLiteral(*field.offset));
} else {
const Field* previous = GetFieldPreceding(field_index);
DCHECK_NOT_NULL(previous);
......@@ -879,8 +879,8 @@ void ClassType::GenerateSliceAccessor(size_t field_index) {
std::tie(previous_element_size, std::ignore) =
*SizeOf(previous->name_and_type.type);
Expression* previous_element_size_expression =
MakeNode<NumberLiteralExpression>(
static_cast<double>(previous_element_size));
MakeNode<IntegerLiteralExpression>(
IntegerLiteral(previous_element_size));
// previous.length
Expression* previous_length_expression = MakeFieldAccessExpression(
......
......@@ -196,8 +196,8 @@ macro TestFunctionPointers(implicit context: Context)(): Boolean {
@export
macro TestVariableRedeclaration(implicit context: Context)(): Boolean {
let _var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
let _var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
let _var1: int31 = FromConstexpr<bool>(42 == 0) ? FromConstexpr<int31>(0) : 1;
let _var2: int31 = FromConstexpr<bool>(42 == 0) ? FromConstexpr<int31>(1) : 0;
return True;
}
......
......@@ -20,6 +20,8 @@ constexpr const char* kTestTorquePrelude = R"(
type void;
type never;
type IntegerLiteral constexpr 'IntegerLiteral';
namespace torque_internal {
struct Reference<T: type> {
const object: HeapObject;
......@@ -112,6 +114,8 @@ extern macro TaggedToHeapObject(Object): HeapObject
extern macro Float64SilenceNaN(float64): float64;
extern macro IntPtrConstant(constexpr int31): intptr;
extern macro ConstexprIntegerLiteralToInt32(constexpr IntegerLiteral): constexpr int32;
extern macro SmiFromInt32(int32): Smi;
macro FromConstexpr<To: type, From: type>(o: From): To;
FromConstexpr<Smi, constexpr Smi>(s: constexpr Smi): Smi {
......@@ -133,6 +137,15 @@ FromConstexpr<bool, constexpr bool>(b: constexpr bool): bool {
FromConstexpr<int32, constexpr int31>(i: constexpr int31): int32 {
return %FromConstexpr<int32>(i);
}
FromConstexpr<int32, constexpr int32>(i: constexpr int32): int32 {
return %FromConstexpr<int32>(i);
}
FromConstexpr<int32, constexpr IntegerLiteral>(i: constexpr IntegerLiteral): int32 {
return FromConstexpr<int32>(ConstexprIntegerLiteralToInt32(i));
}
FromConstexpr<Smi, constexpr IntegerLiteral>(i: constexpr IntegerLiteral): Smi {
return SmiFromInt32(FromConstexpr<int32>(i));
}
macro Cast<A : type extends Object>(implicit context: Context)(o: Object): A
labels CastError {
......
......@@ -8,6 +8,7 @@
#ifndef V8_TORQUE_DEBUG_MACRO_SHIMS_H_
#define V8_TORQUE_DEBUG_MACRO_SHIMS_H_
#include "src/numbers/integer-literal.h"
#include "src/objects/smi.h"
#include "tools/debug_helper/debug-helper-internal.h"
......@@ -81,6 +82,9 @@ inline Value<int32_t> SmiUntag(d::MemoryAccessor accessor, uintptr_t s_t) {
Smi s(s_t);
return {d::MemoryAccessResult::kOk, s.value()};
}
inline Value<uintptr_t> SmiFromInt32(d::MemoryAccessor accessor, int32_t i) {
return {d::MemoryAccessResult::kOk, Smi::FromInt(i).ptr()};
}
inline Value<bool> UintPtrLessThan(d::MemoryAccessor accessor, uintptr_t a,
uintptr_t b) {
return {d::MemoryAccessResult::kOk, a < b};
......@@ -101,6 +105,19 @@ inline Value<bool> Word32NotEqual(d::MemoryAccessor accessor, uint32_t a,
uint32_t b) {
return {d::MemoryAccessResult::kOk, a != b};
}
// This is used in a nested call where we cannot pass Value<int32_t>.
inline int31_t ConstexprIntegerLiteralToInt31(d::MemoryAccessor accessor,
const IntegerLiteral& i) {
return i.To<int32_t>();
}
inline int32_t ConstexprIntegerLiteralToInt32(d::MemoryAccessor accessor,
const IntegerLiteral& i) {
return i.To<int32_t>();
}
inline intptr_t ConstexprIntegerLiteralToIntptr(d::MemoryAccessor accessor,
const IntegerLiteral& i) {
return i.To<intptr_t>();
}
} // namespace CodeStubAssembler
} // namespace TorqueDebugMacroShims
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment