Commit 757830b0 authored by Nico Hartmann's avatar Nico Hartmann Committed by V8 LUCI CQ

[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.

Bug: v8:7793
Change-Id: I46c231aab92bc2f0c26955d1876079f306b358c6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3329792Reviewed-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@{#78671}
parent f4ce0839
...@@ -922,6 +922,9 @@ filegroup( ...@@ -922,6 +922,9 @@ filegroup(
filegroup( filegroup(
name = "torque_base_files", name = "torque_base_files",
srcs = [ srcs = [
":v8_bigint",
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
"src/torque/ast.h", "src/torque/ast.h",
"src/torque/cc-generator.cc", "src/torque/cc-generator.cc",
"src/torque/cc-generator.h", "src/torque/cc-generator.h",
...@@ -2797,6 +2800,8 @@ filegroup( ...@@ -2797,6 +2800,8 @@ filegroup(
"src/interpreter/interpreter-generator.h", "src/interpreter/interpreter-generator.h",
"src/interpreter/interpreter-intrinsics-generator.cc", "src/interpreter/interpreter-intrinsics-generator.cc",
"src/interpreter/interpreter-intrinsics-generator.h", "src/interpreter/interpreter-intrinsics-generator.h",
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
] + select({ ] + select({
"@v8//bazel/config:v8_target_ia32": ["src/builtins/ia32/builtins-ia32.cc"], "@v8//bazel/config:v8_target_ia32": ["src/builtins/ia32/builtins-ia32.cc"],
"@v8//bazel/config:v8_target_x64": ["src/builtins/x64/builtins-x64.cc"], "@v8//bazel/config:v8_target_x64": ["src/builtins/x64/builtins-x64.cc"],
......
...@@ -2290,6 +2290,7 @@ v8_source_set("v8_initializers") { ...@@ -2290,6 +2290,7 @@ v8_source_set("v8_initializers") {
deps = [ deps = [
":torque_generated_initializers", ":torque_generated_initializers",
":v8_base_without_compiler", ":v8_base_without_compiler",
":v8_bigint",
":v8_shared_internal_headers", ":v8_shared_internal_headers",
":v8_tracing", ":v8_tracing",
] ]
...@@ -2365,6 +2366,8 @@ v8_source_set("v8_initializers") { ...@@ -2365,6 +2366,8 @@ v8_source_set("v8_initializers") {
"src/interpreter/interpreter-generator.h", "src/interpreter/interpreter-generator.h",
"src/interpreter/interpreter-intrinsics-generator.cc", "src/interpreter/interpreter-intrinsics-generator.cc",
"src/interpreter/interpreter-intrinsics-generator.h", "src/interpreter/interpreter-intrinsics-generator.h",
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
] ]
if (v8_enable_webassembly) { if (v8_enable_webassembly) {
...@@ -4853,6 +4856,8 @@ v8_source_set("torque_base") { ...@@ -4853,6 +4856,8 @@ v8_source_set("torque_base") {
visibility = [ ":*" ] # Only targets in this file can depend on this. visibility = [ ":*" ] # Only targets in this file can depend on this.
sources = [ sources = [
"src/numbers/integer-literal-inl.h",
"src/numbers/integer-literal.h",
"src/torque/ast.h", "src/torque/ast.h",
"src/torque/cc-generator.cc", "src/torque/cc-generator.cc",
"src/torque/cc-generator.h", "src/torque/cc-generator.h",
...@@ -4906,6 +4911,7 @@ v8_source_set("torque_base") { ...@@ -4906,6 +4911,7 @@ v8_source_set("torque_base") {
] ]
deps = [ deps = [
":v8_bigint",
":v8_flags", ":v8_flags",
":v8_shared_internal_headers", ":v8_shared_internal_headers",
] ]
......
...@@ -301,6 +301,10 @@ class Processor { ...@@ -301,6 +301,10 @@ class Processor {
// Z := the contents of {accumulator}. // Z := the contents of {accumulator}.
// Assume that this leaves {accumulator} in unusable state. // Assume that this leaves {accumulator} in unusable state.
Status FromString(RWDigits Z, FromStringAccumulator* accumulator); 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) { inline int AddResultLength(int x_length, int y_length) {
...@@ -418,13 +422,13 @@ class FromStringAccumulator { ...@@ -418,13 +422,13 @@ class FromStringAccumulator {
: max_digits_(std::max(max_digits, kStackParts)) {} : max_digits_(std::max(max_digits, kStackParts)) {}
// Step 2: Call this method to read all characters. // Step 2: Call this method to read all characters.
// {Char} should be a character type, such as uint8_t or uint16_t. // {CharIt} should be a forward iterator and
// {end} should be one past the last character (i.e. {start == end} would // std::iterator_traits<CharIt>::value_type shall be a character type, such as
// indicate an empty string). // uint8_t or uint16_t. {end} should be one past the last character (i.e.
// Returns the current position when an invalid character is encountered. // {start == end} would indicate an empty string). Returns the current
template <class Char> // position when an invalid character is encountered.
ALWAYS_INLINE const Char* Parse(const Char* start, const Char* end, template <class CharIt>
digit_t radix); ALWAYS_INLINE CharIt Parse(CharIt start, CharIt end, digit_t radix);
// Step 3: Check if a result is available, and determine its required // Step 3: Check if a result is available, and determine its required
// allocation size (guaranteed to be <= max_digits passed to the constructor). // allocation size (guaranteed to be <= max_digits passed to the constructor).
...@@ -434,14 +438,13 @@ class FromStringAccumulator { ...@@ -434,14 +438,13 @@ class FromStringAccumulator {
} }
// Step 4: Use BigIntProcessor::FromString() to retrieve the result into an // 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: private:
friend class ProcessorImpl; friend class ProcessorImpl;
template <class Char> template <class CharIt>
ALWAYS_INLINE const Char* ParsePowerTwo(const Char* start, const Char* end, ALWAYS_INLINE CharIt ParsePowerTwo(CharIt start, CharIt end, digit_t radix);
digit_t radix);
ALWAYS_INLINE bool AddPart(digit_t multiplier, digit_t part, bool is_last); ALWAYS_INLINE bool AddPart(digit_t multiplier, digit_t part, bool is_last);
ALWAYS_INLINE bool AddPart(digit_t part); ALWAYS_INLINE bool AddPart(digit_t part);
...@@ -491,9 +494,8 @@ static constexpr uint8_t kCharValue[] = { ...@@ -491,9 +494,8 @@ static constexpr uint8_t kCharValue[] = {
// A space- and time-efficient way to map {2,4,8,16,32} to {1,2,3,4,5}. // 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}; static constexpr uint8_t kCharBits[] = {1, 2, 3, 0, 4, 0, 0, 0, 5};
template <class Char> template <class CharIt>
const Char* FromStringAccumulator::ParsePowerTwo(const Char* current, CharIt FromStringAccumulator::ParsePowerTwo(CharIt current, CharIt end,
const Char* end,
digit_t radix) { digit_t radix) {
radix_ = static_cast<uint8_t>(radix); radix_ = static_cast<uint8_t>(radix);
const int char_bits = kCharBits[radix >> 2]; const int char_bits = kCharBits[radix >> 2];
...@@ -528,11 +530,10 @@ const Char* FromStringAccumulator::ParsePowerTwo(const Char* current, ...@@ -528,11 +530,10 @@ const Char* FromStringAccumulator::ParsePowerTwo(const Char* current,
return current; return current;
} }
template <class Char> template <class CharIt>
const Char* FromStringAccumulator::Parse(const Char* start, const Char* end, CharIt FromStringAccumulator::Parse(CharIt start, CharIt end, digit_t radix) {
digit_t radix) {
BIGINT_H_DCHECK(2 <= radix && radix <= 36); BIGINT_H_DCHECK(2 <= radix && radix <= 36);
const Char* current = start; CharIt current = start;
#if !HAVE_BUILTIN_MUL_OVERFLOW #if !HAVE_BUILTIN_MUL_OVERFLOW
const digit_t kMaxMultiplier = (~digit_t{0}) / radix; const digit_t kMaxMultiplier = (~digit_t{0}) / radix;
#endif #endif
......
...@@ -127,6 +127,7 @@ class ToStringFormatter { ...@@ -127,6 +127,7 @@ class ToStringFormatter {
out_end_(out + chars_available), out_end_(out + chars_available),
out_(out_end_), out_(out_end_),
processor_(processor) { processor_(processor) {
digits_.Normalize();
DCHECK(chars_available >= ToStringResultLength(digits_, radix_, sign_)); DCHECK(chars_available >= ToStringResultLength(digits_, radix_, sign_));
} }
......
...@@ -548,7 +548,7 @@ macro JoinStackPopInline(implicit context: Context)(receiver: JSReceiver): ...@@ -548,7 +548,7 @@ macro JoinStackPopInline(implicit context: Context)(receiver: JSReceiver):
// Builtin call was not nested (receiver is the first entry) and // Builtin call was not nested (receiver is the first entry) and
// did not contain other nested arrays that expanded the stack. // did not contain other nested arrays that expanded the stack.
if (stack.objects[0] == receiver && len == kMinJoinStackSize) { if (stack.objects[0] == receiver && len == kMinJoinStackSize) {
StoreFixedArrayElement(stack, 0, TheHole, SKIP_WRITE_BARRIER); stack.objects[0] = TheHole;
} else } else
deferred { deferred {
JoinStackPop(stack, receiver); JoinStackPop(stack, receiver);
......
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
type void; type void;
type never; type never;
type IntegerLiteral constexpr 'IntegerLiteral';
type Tagged generates 'TNode<MaybeObject>' constexpr 'MaybeObject'; type Tagged generates 'TNode<MaybeObject>' constexpr 'MaybeObject';
type StrongTagged extends Tagged type StrongTagged extends Tagged
generates 'TNode<Object>' constexpr 'Object'; generates 'TNode<Object>' constexpr 'Object';
...@@ -612,7 +614,7 @@ transitioning macro ToIntegerImpl(implicit context: Context)(input: JSAny): ...@@ -612,7 +614,7 @@ transitioning macro ToIntegerImpl(implicit context: Context)(input: JSAny):
if (Float64IsNaN(value)) return SmiConstant(0); if (Float64IsNaN(value)) return SmiConstant(0);
value = math::Float64Trunc(value); value = math::Float64Trunc(value);
// ToInteger normalizes -0 to +0. // ToInteger normalizes -0 to +0.
if (value == 0.0) return SmiConstant(0); if (value == 0) return SmiConstant(0);
const result = ChangeFloat64ToTagged(value); const result = ChangeFloat64ToTagged(value);
dcheck(IsNumberNormalized(result)); dcheck(IsNumberNormalized(result));
return result; return result;
...@@ -984,6 +986,38 @@ extern operator '==' macro ConstexprInt32Equal( ...@@ -984,6 +986,38 @@ extern operator '==' macro ConstexprInt32Equal(
extern operator '!=' macro ConstexprInt32NotEqual( extern operator '!=' macro ConstexprInt32NotEqual(
constexpr int32, constexpr int32): constexpr bool; 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(int32, int32): bool;
extern operator '==' macro Word32Equal(uint32, uint32): bool; extern operator '==' macro Word32Equal(uint32, uint32): bool;
extern operator '!=' macro Word32NotEqual(int32, int32): bool; extern operator '!=' macro Word32NotEqual(int32, int32): bool;
...@@ -1173,19 +1207,29 @@ extern macro IntPtrConstant(constexpr int32): intptr; ...@@ -1173,19 +1207,29 @@ extern macro IntPtrConstant(constexpr int32): intptr;
extern macro Uint16Constant(constexpr uint16): uint16; extern macro Uint16Constant(constexpr uint16): uint16;
extern macro Int32Constant(constexpr int31): int31; extern macro Int32Constant(constexpr int31): int31;
extern macro Int32Constant(constexpr int32): int32; extern macro Int32Constant(constexpr int32): int32;
macro Int32Constant(i: constexpr IntegerLiteral): int32 {
return Int32Constant(ConstexprIntegerLiteralToInt32(i));
}
extern macro Int64Constant(constexpr int64): int64; extern macro Int64Constant(constexpr int64): int64;
extern macro Uint64Constant(constexpr uint64): uint64; extern macro Uint64Constant(constexpr uint64): uint64;
extern macro Float64Constant(constexpr int32): float64; extern macro Float64Constant(constexpr int32): float64;
extern macro Float64Constant(constexpr float64): float64; extern macro Float64Constant(constexpr float64): float64;
extern macro Float64Constant(constexpr IntegerLiteral): float64;
extern macro SmiConstant(constexpr int31): Smi; extern macro SmiConstant(constexpr int31): Smi;
extern macro SmiConstant(constexpr Smi): Smi; extern macro SmiConstant(constexpr Smi): Smi;
extern macro SmiConstant(constexpr MessageTemplate): Smi; extern macro SmiConstant(constexpr MessageTemplate): Smi;
extern macro SmiConstant(constexpr bool): Smi; extern macro SmiConstant(constexpr bool): Smi;
extern macro SmiConstant(constexpr uint32): 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 BoolConstant(constexpr bool): bool;
extern macro StringConstant(constexpr string): String; extern macro StringConstant(constexpr string): String;
extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot; extern macro IntPtrConstant(constexpr ContextSlot): ContextSlot;
extern macro IntPtrConstant(constexpr intptr): intptr; extern macro IntPtrConstant(constexpr intptr): intptr;
macro IntPtrConstant(il: constexpr IntegerLiteral): intptr {
return IntPtrConstant(ConstexprIntegerLiteralToIntptr(il));
}
extern macro PointerConstant(constexpr RawPtr): RawPtr; extern macro PointerConstant(constexpr RawPtr): RawPtr;
extern macro SingleCharacterStringConstant(constexpr string): String; extern macro SingleCharacterStringConstant(constexpr string): String;
extern macro Float64SilenceNaN(float64): float64; extern macro Float64SilenceNaN(float64): float64;
......
...@@ -4,6 +4,59 @@ ...@@ -4,6 +4,59 @@
intrinsic %FromConstexpr<To: type, From: type>(b: From): To; intrinsic %FromConstexpr<To: type, From: type>(b: From): To;
macro FromConstexpr<To: type, From: type>(o: 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 { FromConstexpr<int31, constexpr int31>(i: constexpr int31): int31 {
return %FromConstexpr<int31>(i); return %FromConstexpr<int31>(i);
} }
...@@ -325,6 +378,10 @@ Convert<intptr, Number>(n: Number): intptr { ...@@ -325,6 +378,10 @@ Convert<intptr, Number>(n: Number): intptr {
Convert<bint, int32>(v: int32): bint { Convert<bint, int32>(v: int32): bint {
return IntPtrToBInt(Convert<intptr>(v)); return IntPtrToBInt(Convert<intptr>(v));
} }
FromConstexpr<float64, constexpr IntegerLiteral>(v: constexpr IntegerLiteral):
float64 {
return ConstexprIntegerLiteralToFloat64(v);
}
extern macro IntPtrToBInt(intptr): bint; extern macro IntPtrToBInt(intptr): bint;
Convert<bint, intptr>(v: intptr): bint { Convert<bint, intptr>(v: intptr): bint {
return IntPtrToBInt(v); return IntPtrToBInt(v);
......
...@@ -90,7 +90,7 @@ macro NumberToStringSmi(x: int32, radix: int32): String labels Slow { ...@@ -90,7 +90,7 @@ macro NumberToStringSmi(x: int32, radix: int32): String labels Slow {
// Calculate length and pre-allocate the result string. // Calculate length and pre-allocate the result string.
let temp: int32 = n; let temp: int32 = n;
let length: int32 = isNegative ? 1 : 0; let length: int32 = isNegative ? Convert<int32>(1) : Convert<int32>(0);
while (temp > 0) { while (temp > 0) {
temp = temp / radix; temp = temp / radix;
length = length + 1; length = length + 1;
...@@ -277,7 +277,7 @@ transitioning builtin ParseInt(implicit context: Context)( ...@@ -277,7 +277,7 @@ transitioning builtin ParseInt(implicit context: Context)(
// the runtime for the range [0,1[ because the result could be -0. // the runtime for the range [0,1[ because the result could be -0.
const kMaxAbsValue: float64 = 2147483648.0; const kMaxAbsValue: float64 = 2147483648.0;
const absInput: float64 = math::Float64Abs(asFloat64); 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; goto CallRuntime;
} }
case (s: String): { case (s: String): {
...@@ -690,7 +690,7 @@ builtin Negate(implicit context: Context)(value: JSAny): Numeric { ...@@ -690,7 +690,7 @@ builtin Negate(implicit context: Context)(value: JSAny): Numeric {
} label Smi(s: Smi) { } label Smi(s: Smi) {
return SmiMul(s, -1); return SmiMul(s, -1);
} label HeapNumber(h: HeapNumber) { } label HeapNumber(h: HeapNumber) {
return AllocateHeapNumberWithValue(Convert<float64>(h) * -1); return AllocateHeapNumberWithValue(Convert<float64>(h) * -1.0);
} label BigInt(b: BigInt) { } label BigInt(b: BigInt) {
tail runtime::BigIntUnaryOp( tail runtime::BigIntUnaryOp(
context, b, SmiTag<Operation>(Operation::kNegate)); context, b, SmiTag<Operation>(Operation::kNegate));
......
...@@ -55,7 +55,7 @@ transitioning javascript builtin StringPrototypeRepeat( ...@@ -55,7 +55,7 @@ transitioning javascript builtin StringPrototypeRepeat(
// 4. If n < 0, throw a RangeError exception. // 4. If n < 0, throw a RangeError exception.
// 5. If n is +∞, 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. // 6. If n is 0, return the empty String.
if (s.length_uint32 == 0) goto EmptyString; if (s.length_uint32 == 0) goto EmptyString;
......
...@@ -105,6 +105,10 @@ struct Slice<T: type, Reference: type> { ...@@ -105,6 +105,10 @@ struct Slice<T: type, Reference: type> {
return this.TryAtIndex(Convert<intptr>(index)) otherwise unreachable; 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 { macro AtIndex(index: constexpr int31): Reference {
const i: intptr = Convert<intptr>(index); const i: intptr = Convert<intptr>(index);
return this.TryAtIndex(i) otherwise unreachable; return this.TryAtIndex(i) otherwise unreachable;
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "src/heap/heap-inl.h" // For MemoryChunk. TODO(jkummerow): Drop. #include "src/heap/heap-inl.h" // For MemoryChunk. TODO(jkummerow): Drop.
#include "src/heap/memory-chunk.h" #include "src/heap/memory-chunk.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/numbers/integer-literal-inl.h"
#include "src/objects/api-callbacks.h" #include "src/objects/api-callbacks.h"
#include "src/objects/cell.h" #include "src/objects/cell.h"
#include "src/objects/descriptor-array.h" #include "src/objects/descriptor-array.h"
...@@ -14754,6 +14755,19 @@ void CodeStubAssembler::Print(const char* prefix, ...@@ -14754,6 +14755,19 @@ void CodeStubAssembler::Print(const char* prefix,
CallRuntime(Runtime::kDebugPrint, NoContextConstant(), arg); 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) { void CodeStubAssembler::PerformStackCheck(TNode<Context> context) {
Label ok(this), stack_check_interrupt(this, Label::kDeferred); Label ok(this), stack_check_interrupt(this, Label::kDeferred);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/common/message-template.h" #include "src/common/message-template.h"
#include "src/compiler/code-assembler.h" #include "src/compiler/code-assembler.h"
#include "src/numbers/integer-literal.h"
#include "src/objects/arguments.h" #include "src/objects/arguments.h"
#include "src/objects/bigint.h" #include "src/objects/bigint.h"
#include "src/objects/cell.h" #include "src/objects/cell.h"
...@@ -3743,6 +3744,45 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3743,6 +3744,45 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
} }
bool ConstexprBoolNot(bool value) { return !value; } 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 ConstexprInt31Equal(int31_t a, int31_t b) { return a == b; }
bool ConstexprInt31NotEqual(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 {
// Special case 0 here.
if (IsZero()) return "0";
int len = bigint::ToStringResultLength(GetDigits(), 10, sign());
std::vector<char> buffer(len);
bigint::Processor* processor = bigint::Processor::New(new bigint::Platform());
processor->ToString(buffer.data(), &len, GetDigits(), 10, sign());
processor->Destroy();
return std::string(buffer.begin(), buffer.begin() + len);
}
inline IntegerLiteral operator<<(const IntegerLiteral& lhs,
const IntegerLiteral& rhs) {
if (lhs.IsZero() || rhs.IsZero()) return lhs;
CHECK_EQ(rhs.length(), 1);
// We don't support negative left shift here.
CHECK(!rhs.sign());
const int result_length = bigint::LeftShift_ResultLength(
lhs.length(), lhs.GetDigits().msd(), rhs.GetDigits()[0]);
DCHECK_LE(result_length, IntegerLiteral::kMaxLength);
auto result = IntegerLiteral::ForLength(result_length, lhs.sign());
bigint::LeftShift(result.GetRWDigits(), lhs.GetDigits(), rhs.GetDigits()[0]);
return result;
}
inline IntegerLiteral operator+(const IntegerLiteral& lhs,
const IntegerLiteral& rhs) {
const int result_length = bigint::AddSignedResultLength(
lhs.length(), rhs.length(), lhs.sign() == rhs.sign());
auto result = IntegerLiteral::ForLength(result_length);
bool result_sign = bigint::AddSigned(result.GetRWDigits(), lhs.GetDigits(),
lhs.sign(), rhs.GetDigits(), rhs.sign());
result.set_sign(result_sign);
result.Normalize();
return result;
}
inline IntegerLiteral operator|(const IntegerLiteral& lhs,
const IntegerLiteral& rhs) {
int result_length = bigint::BitwiseOrResultLength(lhs.length(), rhs.length());
auto result =
IntegerLiteral::ForLength(result_length, lhs.sign() || rhs.sign());
if (lhs.sign()) {
if (rhs.sign()) {
bigint::BitwiseOr_NegNeg(result.GetRWDigits(), lhs.GetDigits(),
rhs.GetDigits());
} else {
bigint::BitwiseOr_PosNeg(result.GetRWDigits(), rhs.GetDigits(),
lhs.GetDigits());
}
} else {
if (rhs.sign()) {
bigint::BitwiseOr_PosNeg(result.GetRWDigits(), lhs.GetDigits(),
rhs.GetDigits());
} else {
bigint::BitwiseOr_PosPos(result.GetRWDigits(), lhs.GetDigits(),
rhs.GetDigits());
}
}
return result;
}
} // 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/bigint/bigint.h"
#include "src/common/globals.h"
namespace v8 {
namespace internal {
class IntegerLiteral {
public:
using digit_t = bigint::digit_t;
static constexpr int kMaxLength =
(1 << 30) / (kSystemPointerSize * kBitsPerByte);
template <typename T>
explicit IntegerLiteral(T value) : IntegerLiteral(value, true) {}
static IntegerLiteral ForLength(int length, bool sign = false) {
return IntegerLiteral(sign, std::vector<digit_t>(length));
}
bool sign() const { return sign_; }
void set_sign(bool sign) { sign_ = sign; }
int length() const { return static_cast<int>(digits_.size()); }
bigint::RWDigits GetRWDigits() {
return bigint::RWDigits(digits_.data(), static_cast<int>(digits_.size()));
}
bigint::Digits GetDigits() const {
return bigint::Digits(const_cast<digit_t*>(digits_.data()),
static_cast<int>(digits_.size()));
}
template <typename T>
bool IsRepresentableAs() const {
static_assert(std::is_integral<T>::value, "Integral type required");
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");
base::Optional<T> result_opt = TryTo<T>();
DCHECK(result_opt.has_value());
return *result_opt;
}
template <typename T>
base::Optional<T> TryTo() const {
static_assert(std::is_integral<T>::value, "Integral type required");
if (!IsRepresentableAs<T>()) return base::nullopt;
using unsigned_t = std::make_unsigned_t<T>;
unsigned_t value = 0;
if (digits_.empty()) return static_cast<T>(value);
for (size_t i = 0; i < digits_.size(); ++i) {
value = value | (static_cast<unsigned_t>(digits_[i])
<< (sizeof(digit_t) * kBitsPerByte * i));
}
if (sign_) {
value = (~value + 1);
}
return static_cast<T>(value);
}
bool IsZero() const {
return std::all_of(digits_.begin(), digits_.end(),
[](digit_t d) { return d == 0; });
}
void Normalize() {
while (digits_.size() > 0 && digits_[0] == 0) digits_.pop_back();
if (digits_.empty()) sign_ = false;
}
int Compare(const IntegerLiteral& other) const {
int diff = bigint::Compare(GetDigits(), other.GetDigits());
if (diff == 0) {
if (IsZero() || sign() == other.sign()) return 0;
return sign() ? -1 : 1;
} else if (diff < 0) {
return other.sign() ? 1 : -1;
} else {
return sign() ? -1 : 1;
}
}
std::string ToString() const;
private:
IntegerLiteral(bool sign, std::vector<digit_t> digits)
: sign_(sign), digits_(std::move(digits)) {}
template <typename T>
explicit IntegerLiteral(T value, bool perform_dcheck) : sign_(false) {
static_assert(std::is_integral<T>::value, "Integral type required");
if (value == T(0)) return;
auto absolute = static_cast<typename std::make_unsigned<T>::type>(value);
if (value < T(0)) {
sign_ = true;
absolute = (~absolute) + 1;
}
if (sizeof(absolute) <= sizeof(digit_t)) {
digits_.push_back(absolute);
} else {
do {
digits_.push_back(static_cast<digit_t>(absolute));
absolute >>= sizeof(digit_t) * kBitsPerByte;
} while (absolute != 0);
}
if (perform_dcheck) DCHECK_EQ(To<T>(), value);
}
bool sign_;
std::vector<digit_t> digits_;
};
inline bool operator==(const IntegerLiteral& lhs, const IntegerLiteral& rhs) {
return lhs.Compare(rhs) == 0;
}
inline bool operator!=(const IntegerLiteral& lhs, const IntegerLiteral& rhs) {
return lhs.Compare(rhs) != 0;
}
inline std::ostream& operator<<(std::ostream& stream,
const IntegerLiteral& literal) {
return stream << literal.ToString();
}
IntegerLiteral operator<<(const IntegerLiteral& lhs, const IntegerLiteral& rhs);
IntegerLiteral operator+(const IntegerLiteral& lhs, const IntegerLiteral& rhs);
IntegerLiteral operator|(const IntegerLiteral& lhs, const IntegerLiteral& rhs);
} // namespace internal
} // namespace v8
#endif // V8_NUMBERS_INTEGER_LITERAL_H_
...@@ -5,12 +5,11 @@ ...@@ -5,12 +5,11 @@
#ifndef V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_ #ifndef V8_OBJECTS_DESCRIPTOR_ARRAY_INL_H_
#define 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/execution/isolate.h"
#include "src/handles/maybe-handles-inl.h" #include "src/handles/maybe-handles-inl.h"
#include "src/heap/heap-write-barrier.h" #include "src/heap/heap-write-barrier.h"
#include "src/heap/heap.h" #include "src/heap/heap.h"
#include "src/objects/descriptor-array.h"
#include "src/objects/field-type.h" #include "src/objects/field-type.h"
#include "src/objects/heap-object-inl.h" #include "src/objects/heap-object-inl.h"
#include "src/objects/lookup-cache-inl.h" #include "src/objects/lookup-cache-inl.h"
......
...@@ -5,13 +5,12 @@ ...@@ -5,13 +5,12 @@
#ifndef V8_OBJECTS_FIXED_ARRAY_INL_H_ #ifndef V8_OBJECTS_FIXED_ARRAY_INL_H_
#define 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/handles/handles-inl.h"
#include "src/heap/heap-write-barrier-inl.h" #include "src/heap/heap-write-barrier-inl.h"
#include "src/numbers/conversions.h" #include "src/numbers/conversions.h"
#include "src/objects/bigint.h" #include "src/objects/bigint.h"
#include "src/objects/compressed-slots.h" #include "src/objects/compressed-slots.h"
#include "src/objects/fixed-array.h"
#include "src/objects/map.h" #include "src/objects/map.h"
#include "src/objects/maybe-object-inl.h" #include "src/objects/maybe-object-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
......
...@@ -81,7 +81,7 @@ class TurbofanOtherNumberConstantType extends TurbofanType { ...@@ -81,7 +81,7 @@ class TurbofanOtherNumberConstantType extends TurbofanType {
} }
macro IsMinusZero(x: float64): bool { macro IsMinusZero(x: float64): bool {
return x == 0 && 1 / x < 0; return x == 0 && 1.0 / x < 0;
} }
macro TestTurbofanBitsetType( macro TestTurbofanBitsetType(
...@@ -95,17 +95,17 @@ macro TestTurbofanBitsetType( ...@@ -95,17 +95,17 @@ macro TestTurbofanBitsetType(
if (IsInteger(value)) { if (IsInteger(value)) {
if (IsMinusZero(valueF)) { if (IsMinusZero(valueF)) {
return bitsetLow.minus_zero; return bitsetLow.minus_zero;
} else if (valueF < Convert<float64>(-0x80000000)) { } else if (valueF < 0 - Convert<float64>(0x80000000)) {
return bitsetLow.other_number; return bitsetLow.other_number;
} else if (valueF < -0x40000000) { } else if (valueF < 0 - Convert<float64>(0x40000000)) {
return bitsetLow.other_signed32; return bitsetLow.other_signed32;
} else if (valueF < 0) { } else if (valueF < 0) {
return bitsetLow.negative31; return bitsetLow.negative31;
} else if (valueF < Convert<float64>(0x40000000)) { } else if (valueF < Convert<float64>(0x40000000)) {
return bitsetLow.unsigned30; return bitsetLow.unsigned30;
} else if (valueF < 0x80000000) { } else if (valueF < Convert<float64>(0x80000000)) {
return bitsetLow.other_unsigned31; return bitsetLow.other_unsigned31;
} else if (valueF <= 0xffffffff) { } else if (valueF <= Convert<float64>(0xffffffff)) {
return bitsetLow.other_unsigned32; return bitsetLow.other_unsigned32;
} else { } else {
return bitsetLow.other_number; return bitsetLow.other_number;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <vector> #include <vector>
#include "src/base/optional.h" #include "src/base/optional.h"
#include "src/numbers/integer-literal.h"
#include "src/torque/constants.h" #include "src/torque/constants.h"
#include "src/torque/source-positions.h" #include "src/torque/source-positions.h"
#include "src/torque/utils.h" #include "src/torque/utils.h"
...@@ -33,7 +34,8 @@ namespace torque { ...@@ -33,7 +34,8 @@ namespace torque {
V(ConditionalExpression) \ V(ConditionalExpression) \
V(IdentifierExpression) \ V(IdentifierExpression) \
V(StringLiteralExpression) \ V(StringLiteralExpression) \
V(NumberLiteralExpression) \ V(IntegerLiteralExpression) \
V(FloatingPointLiteralExpression) \
V(FieldAccessExpression) \ V(FieldAccessExpression) \
V(ElementAccessExpression) \ V(ElementAccessExpression) \
V(DereferenceExpression) \ V(DereferenceExpression) \
...@@ -459,16 +461,28 @@ struct StringLiteralExpression : Expression { ...@@ -459,16 +461,28 @@ struct StringLiteralExpression : Expression {
std::string literal; std::string literal;
}; };
struct NumberLiteralExpression : Expression { struct IntegerLiteralExpression : Expression {
DEFINE_AST_NODE_LEAF_BOILERPLATE(NumberLiteralExpression) DEFINE_AST_NODE_LEAF_BOILERPLATE(IntegerLiteralExpression)
NumberLiteralExpression(SourcePosition pos, double number) IntegerLiteralExpression(SourcePosition pos, IntegerLiteral value)
: Expression(kKind, pos), number(number) {} : Expression(kKind, pos), value(std::move(value)) {}
void VisitAllSubExpressions(VisitCallback callback) override { void VisitAllSubExpressions(VisitCallback callback) override {
callback(this); 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 { struct ElementAccessExpression : LocationExpression {
......
...@@ -67,6 +67,8 @@ static const char* const FLOAT64_OR_HOLE_TYPE_STRING = "float64_or_hole"; ...@@ -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_INT31_TYPE_STRING = "constexpr int31";
static const char* const CONST_INT32_TYPE_STRING = "constexpr int32"; static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64"; 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 TORQUE_INTERNAL_NAMESPACE_STRING = "torque_internal";
static const char* const MUTABLE_REFERENCE_TYPE_STRING = "MutableReference"; static const char* const MUTABLE_REFERENCE_TYPE_STRING = "MutableReference";
static const char* const CONST_REFERENCE_TYPE_STRING = "ConstReference"; static const char* const CONST_REFERENCE_TYPE_STRING = "ConstReference";
......
...@@ -127,6 +127,7 @@ LexerResult Lexer::RunLexer(const std::string& input) { ...@@ -127,6 +127,7 @@ LexerResult Lexer::RunLexer(const std::string& input) {
while (pos != end) { while (pos != end) {
token_start = pos; token_start = pos;
Symbol* symbol = MatchToken(&pos, end); Symbol* symbol = MatchToken(&pos, end);
DCHECK_IMPLIES(symbol != nullptr, pos != token_start);
InputPosition token_end = pos; InputPosition token_end = pos;
line_column_tracker.Advance(token_start, token_end); line_column_tracker.Advance(token_start, token_end);
if (!symbol) { if (!symbol) {
......
...@@ -44,6 +44,8 @@ enum class ParseResultHolderBase::TypeId { ...@@ -44,6 +44,8 @@ enum class ParseResultHolderBase::TypeId {
kStdString, kStdString,
kBool, kBool,
kInt32, kInt32,
kDouble,
kIntegerLiteral,
kStdVectorOfString, kStdVectorOfString,
kExpressionPtr, kExpressionPtr,
kIdentifierPtr, kIdentifierPtr,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "src/base/optional.h" #include "src/base/optional.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/numbers/integer-literal-inl.h"
#include "src/torque/cc-generator.h" #include "src/torque/cc-generator.h"
#include "src/torque/cfg.h" #include "src/torque/cfg.h"
#include "src/torque/constants.h" #include "src/torque/constants.h"
...@@ -182,6 +183,7 @@ void ImplementationVisitor::BeginDebugMacrosFile() { ...@@ -182,6 +183,7 @@ void ImplementationVisitor::BeginDebugMacrosFile() {
header << "#ifndef " << kHeaderDefine << "\n"; header << "#ifndef " << kHeaderDefine << "\n";
header << "#define " << kHeaderDefine << "\n\n"; header << "#define " << kHeaderDefine << "\n\n";
header << "#include \"tools/debug_helper/debug-helper-internal.h\"\n"; header << "#include \"tools/debug_helper/debug-helper-internal.h\"\n";
header << "#include \"src/numbers/integer-literal.h\"\n";
header << "\n"; header << "\n";
header << "namespace v8 {\n" header << "namespace v8 {\n"
...@@ -943,22 +945,18 @@ VisitResult ImplementationVisitor::Visit(AssignmentExpression* expr) { ...@@ -943,22 +945,18 @@ VisitResult ImplementationVisitor::Visit(AssignmentExpression* expr) {
return scope.Yield(assignment_value); return scope.Yield(assignment_value);
} }
VisitResult ImplementationVisitor::Visit(NumberLiteralExpression* expr) { VisitResult ImplementationVisitor::Visit(FloatingPointLiteralExpression* expr) {
const Type* result_type = TypeOracle::GetConstFloat64Type(); 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; std::stringstream str;
str << std::setprecision(std::numeric_limits<double>::digits10 + 1) 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 << ")";
return VisitResult{result_type, str.str()}; return VisitResult{result_type, str.str()};
} }
...@@ -2848,7 +2846,9 @@ VisitResult ImplementationVisitor::GenerateCall( ...@@ -2848,7 +2846,9 @@ VisitResult ImplementationVisitor::GenerateCall(
// If we're currently generating a C++ macro and it's calling another macro, // 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 // then we need to make sure that we also generate C++ code for the called
// macro within the same -inl.inc file. // 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)) { if (auto* torque_macro = TorqueMacro::DynamicCast(macro)) {
auto* streams = CurrentFileStreams::Get(); auto* streams = CurrentFileStreams::Get();
SourceId file = streams ? streams->file : SourceId::Invalid(); SourceId file = streams ? streams->file : SourceId::Invalid();
...@@ -2862,6 +2862,8 @@ VisitResult ImplementationVisitor::GenerateCall( ...@@ -2862,6 +2862,8 @@ VisitResult ImplementationVisitor::GenerateCall(
std::stringstream result; std::stringstream result;
result << "("; result << "(";
bool first = true; bool first = true;
switch (output_type_) {
case OutputType::kCSA: {
if (auto* extern_macro = ExternMacro::DynamicCast(macro)) { if (auto* extern_macro = ExternMacro::DynamicCast(macro)) {
result << extern_macro->external_assembler_name() << "(state_)." result << extern_macro->external_assembler_name() << "(state_)."
<< extern_macro->ExternalName() << "("; << extern_macro->ExternalName() << "(";
...@@ -2869,7 +2871,23 @@ VisitResult ImplementationVisitor::GenerateCall( ...@@ -2869,7 +2871,23 @@ VisitResult ImplementationVisitor::GenerateCall(
result << macro->ExternalName() << "(state_"; result << macro->ExternalName() << "(state_";
first = false; first = false;
} }
for (VisitResult arg : arguments.parameters) { 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 : converted_arguments) {
DCHECK(!arg.IsOnStack()); DCHECK(!arg.IsOnStack());
if (!first) { if (!first) {
result << ", "; result << ", ";
......
...@@ -555,7 +555,8 @@ class ImplementationVisitor { ...@@ -555,7 +555,8 @@ class ImplementationVisitor {
VisitResult Visit(IncrementDecrementExpression* expr); VisitResult Visit(IncrementDecrementExpression* expr);
VisitResult Visit(AssignmentExpression* expr); VisitResult Visit(AssignmentExpression* expr);
VisitResult Visit(StringLiteralExpression* expr); VisitResult Visit(StringLiteralExpression* expr);
VisitResult Visit(NumberLiteralExpression* expr); VisitResult Visit(FloatingPointLiteralExpression* expr);
VisitResult Visit(IntegerLiteralExpression* expr);
VisitResult Visit(AssumeTypeImpossibleExpression* expr); VisitResult Visit(AssumeTypeImpossibleExpression* expr);
VisitResult Visit(TryLabelExpression* expr); VisitResult Visit(TryLabelExpression* expr);
VisitResult Visit(StatementExpression* expr); VisitResult Visit(StatementExpression* expr);
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include <cstdint> #include <cstdint>
#include "src/numbers/integer-literal.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -34,6 +36,15 @@ inline uintptr_t Unsigned(intptr_t s) { return static_cast<uintptr_t>(s); } ...@@ -34,6 +36,15 @@ inline uintptr_t Unsigned(intptr_t s) { return static_cast<uintptr_t>(s); }
#endif #endif
inline bool Word32Equal(uint32_t a, uint32_t b) { return a == b; } 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 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 CodeStubAssembler
} // namespace TorqueRuntimeMacroShims } // namespace TorqueRuntimeMacroShims
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <stdexcept> #include <stdexcept>
#include <unordered_map> #include <unordered_map>
#include "src/bigint/bigint.h"
#include "src/flags/flags.h" #include "src/flags/flags.h"
#include "src/torque/ast.h" #include "src/torque/ast.h"
#include "src/torque/constants.h" #include "src/torque/constants.h"
...@@ -92,6 +93,12 @@ template <> ...@@ -92,6 +93,12 @@ template <>
V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<int32_t>::id = V8_EXPORT_PRIVATE const ParseResultTypeId ParseResultHolder<int32_t>::id =
ParseResultTypeId::kInt32; ParseResultTypeId::kInt32;
template <> 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 V8_EXPORT_PRIVATE const ParseResultTypeId
ParseResultHolder<std::vector<std::string>>::id = ParseResultHolder<std::vector<std::string>>::id =
ParseResultTypeId::kStdVectorOfString; ParseResultTypeId::kStdVectorOfString;
...@@ -847,8 +854,8 @@ class AnnotationSet { ...@@ -847,8 +854,8 @@ class AnnotationSet {
std::map<std::string, std::pair<AnnotationParameter, SourcePosition>> map_; std::map<std::string, std::pair<AnnotationParameter, SourcePosition>> map_;
}; };
base::Optional<ParseResult> MakeInt32(ParseResultIterator* child_results) { base::Optional<ParseResult> YieldInt32(ParseResultIterator* child_results) {
std::string value = child_results->NextAs<std::string>(); std::string value = child_results->matched_input().ToString();
size_t num_chars_converted = 0; size_t num_chars_converted = 0;
int result = 0; int result = 0;
try { try {
...@@ -865,6 +872,58 @@ base::Optional<ParseResult> MakeInt32(ParseResultIterator* child_results) { ...@@ -865,6 +872,58 @@ base::Optional<ParseResult> MakeInt32(ParseResultIterator* child_results) {
return ParseResult{result}; 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) {
// Note that kMaxDigits is rather arbitrary and we just need something that
// is large enough on all platforms to hold all (signed and unsigned) 64 bit
// integer values. We will insert range checks for the actual types later
// anyway, so we allow arbitrarily large literals here.
constexpr int kMaxDigits = 10;
std::string value = child_results->matched_input().ToString();
auto pos = value.begin();
auto end = value.end();
// Consume a leading minus.
bool sign = false;
if (*pos == '-') {
sign = true;
++pos;
}
DCHECK_NE(pos, end);
bigint::FromStringAccumulator accumulator(kMaxDigits);
if (StringStartsWith({pos, end}, "0x")) {
// Parse hexadecimal literal.
pos += 2;
pos = accumulator.Parse(pos, end, 16);
} else {
// Parse decimal literal.
pos = accumulator.Parse(pos, end, 10);
}
// Should have processed all characters in the input.
DCHECK_EQ(pos, end);
auto literal = IntegerLiteral::ForLength(accumulator.ResultLength(), sign);
auto processor = bigint::Processor::New(new bigint::Platform());
processor->FromString(literal.GetRWDigits(), &accumulator);
processor->Destroy();
return ParseResult(std::move(literal));
}
base::Optional<ParseResult> MakeStringAnnotationParameter( base::Optional<ParseResult> MakeStringAnnotationParameter(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
std::string value = child_results->NextAs<std::string>(); std::string value = child_results->NextAs<std::string>();
...@@ -1885,29 +1944,17 @@ base::Optional<ParseResult> MakeAssignmentExpression( ...@@ -1885,29 +1944,17 @@ base::Optional<ParseResult> MakeAssignmentExpression(
return ParseResult{result}; return ParseResult{result};
} }
base::Optional<ParseResult> MakeNumberLiteralExpression( base::Optional<ParseResult> MakeFloatingPointLiteralExpression(
ParseResultIterator* child_results) { ParseResultIterator* child_results) {
auto number = child_results->NextAs<std::string>(); auto value = child_results->NextAs<double>();
// TODO(turbofan): Support 64bit literals. Expression* result = MakeNode<FloatingPointLiteralExpression>(value);
// Meanwhile, we type it as constexpr float64 when out of int32 range. return ParseResult{result};
double value = 0; }
try {
#if defined(V8_OS_SOLARIS) base::Optional<ParseResult> MakeIntegerLiteralExpression(
// stod() on Solaris does not currently support hex strings. Use strtol() ParseResultIterator* child_results) {
// specifically for hex literals until stod() support is available. auto value = child_results->NextAs<IntegerLiteral>();
if (number.find("0x") == std::string::npos && Expression* result = MakeNode<IntegerLiteralExpression>(std::move(value));
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);
return ParseResult{result}; return ParseResult{result};
} }
...@@ -2067,8 +2114,19 @@ base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) { ...@@ -2067,8 +2114,19 @@ base::Optional<ParseResult> MakeClassField(ParseResultIterator* child_results) {
// Internally, an optional field is just an indexed field where the count // Internally, an optional field is just an indexed field where the count
// is zero or one. // is zero or one.
index = MakeNode<ConditionalExpression>( index = MakeNode<ConditionalExpression>(
*index, MakeNode<NumberLiteralExpression>(1), *index,
MakeNode<NumberLiteralExpression>(0)); 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}; index_info = ClassFieldIndexInfo{*index, optional};
} }
...@@ -2187,12 +2245,24 @@ struct TorqueGrammar : Grammar { ...@@ -2187,12 +2245,24 @@ struct TorqueGrammar : Grammar {
return false; 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; InputPosition current = *pos;
bool found_digit = false; bool found_digit = false;
MatchString("-", &current); MatchString("-", &current);
while (MatchChar(std::isdigit, &current)) found_digit = true; while (MatchChar(std::isdigit, &current)) found_digit = true;
MatchString(".", &current); if (!MatchString(".", &current)) return false;
while (MatchChar(std::isdigit, &current)) found_digit = true; while (MatchChar(std::isdigit, &current)) found_digit = true;
if (!found_digit) return false; if (!found_digit) return false;
*pos = current; *pos = current;
...@@ -2277,13 +2347,18 @@ struct TorqueGrammar : Grammar { ...@@ -2277,13 +2347,18 @@ struct TorqueGrammar : Grammar {
// Result: std::string // Result: std::string
Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)}; Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)};
// Result: std::string // Result: IntegerLiteral
Symbol decimalLiteral = { Symbol integerLiteral = {
Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput), Rule({Pattern(MatchIntegerLiteral)}, YieldIntegerLiteral),
Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)}; Rule({Pattern(MatchHexLiteral)}, YieldIntegerLiteral)};
// Result: double
Symbol floatingPointLiteral = {
Rule({Pattern(MatchFloatingPointLiteral)}, YieldDouble)};
// Result: int32_t // Result: int32_t
Symbol int32Literal = {Rule({&decimalLiteral}, MakeInt32)}; Symbol int32Literal = {Rule({Pattern(MatchIntegerLiteral)}, YieldInt32),
Rule({Pattern(MatchHexLiteral)}, YieldInt32)};
// Result: AnnotationParameter // Result: AnnotationParameter
Symbol annotationParameter = { Symbol annotationParameter = {
...@@ -2502,7 +2577,8 @@ struct TorqueGrammar : Grammar { ...@@ -2502,7 +2577,8 @@ struct TorqueGrammar : Grammar {
MakeReferenceFieldAccessExpression), MakeReferenceFieldAccessExpression),
Rule({&primaryExpression, Token("["), expression, Token("]")}, Rule({&primaryExpression, Token("["), expression, Token("]")},
MakeElementAccessExpression), MakeElementAccessExpression),
Rule({&decimalLiteral}, MakeNumberLiteralExpression), Rule({&integerLiteral}, MakeIntegerLiteralExpression),
Rule({&floatingPointLiteral}, MakeFloatingPointLiteralExpression),
Rule({&stringLiteral}, MakeStringLiteralExpression), Rule({&stringLiteral}, MakeStringLiteralExpression),
Rule({&simpleType, &initializerList}, MakeStructExpression), Rule({&simpleType, &initializerList}, MakeStructExpression),
Rule({&newExpression}), Rule({&newExpression}),
......
...@@ -315,6 +315,10 @@ class TypeOracle : public ContextualClass<TypeOracle> { ...@@ -315,6 +315,10 @@ class TypeOracle : public ContextualClass<TypeOracle> {
return Get().GetBuiltinType(CONST_FLOAT64_TYPE_STRING); return Get().GetBuiltinType(CONST_FLOAT64_TYPE_STRING);
} }
static const Type* GetIntegerLiteralType() {
return Get().GetBuiltinType(INTEGER_LITERAL_TYPE_STRING);
}
static const Type* GetNeverType() { static const Type* GetNeverType() {
return Get().GetBuiltinType(NEVER_TYPE_STRING); return Get().GetBuiltinType(NEVER_TYPE_STRING);
} }
......
...@@ -459,12 +459,12 @@ void TypeVisitor::VisitClassFieldsAndMethods( ...@@ -459,12 +459,12 @@ void TypeVisitor::VisitClassFieldsAndMethods(
field_size * ResidueClass::Unknown()); field_size * ResidueClass::Unknown());
if (auto literal = if (auto literal =
NumberLiteralExpression::DynamicCast(field.index->expr)) { IntegerLiteralExpression::DynamicCast(field.index->expr)) {
size_t value = static_cast<size_t>(literal->number); if (auto value = literal->value.TryTo<size_t>()) {
if (value != literal->number) { field_size *= *value;
Error("non-integral array length").Position(field.pos); } else {
Error("Not a valid field index").Position(field.pos);
} }
field_size *= value;
} else { } else {
field_size *= ResidueClass::Unknown(); field_size *= ResidueClass::Unknown();
} }
......
...@@ -850,7 +850,7 @@ void ClassType::GenerateSliceAccessor(size_t field_index) { ...@@ -850,7 +850,7 @@ void ClassType::GenerateSliceAccessor(size_t field_index) {
if (field.offset.has_value()) { if (field.offset.has_value()) {
offset_expression = offset_expression =
MakeNode<NumberLiteralExpression>(static_cast<double>(*field.offset)); MakeNode<IntegerLiteralExpression>(IntegerLiteral(*field.offset));
} else { } else {
const Field* previous = GetFieldPreceding(field_index); const Field* previous = GetFieldPreceding(field_index);
DCHECK_NOT_NULL(previous); DCHECK_NOT_NULL(previous);
...@@ -879,8 +879,8 @@ void ClassType::GenerateSliceAccessor(size_t field_index) { ...@@ -879,8 +879,8 @@ void ClassType::GenerateSliceAccessor(size_t field_index) {
std::tie(previous_element_size, std::ignore) = std::tie(previous_element_size, std::ignore) =
*SizeOf(previous->name_and_type.type); *SizeOf(previous->name_and_type.type);
Expression* previous_element_size_expression = Expression* previous_element_size_expression =
MakeNode<NumberLiteralExpression>( MakeNode<IntegerLiteralExpression>(
static_cast<double>(previous_element_size)); IntegerLiteral(previous_element_size));
// previous.length // previous.length
Expression* previous_length_expression = MakeFieldAccessExpression( Expression* previous_length_expression = MakeFieldAccessExpression(
......
...@@ -196,8 +196,8 @@ macro TestFunctionPointers(implicit context: Context)(): Boolean { ...@@ -196,8 +196,8 @@ macro TestFunctionPointers(implicit context: Context)(): Boolean {
@export @export
macro TestVariableRedeclaration(implicit context: Context)(): Boolean { macro TestVariableRedeclaration(implicit context: Context)(): Boolean {
let _var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1; let _var1: int31 = FromConstexpr<bool>(42 == 0) ? FromConstexpr<int31>(0) : 1;
let _var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0; let _var2: int31 = FromConstexpr<bool>(42 == 0) ? FromConstexpr<int31>(1) : 0;
return True; return True;
} }
......
...@@ -20,6 +20,8 @@ constexpr const char* kTestTorquePrelude = R"( ...@@ -20,6 +20,8 @@ constexpr const char* kTestTorquePrelude = R"(
type void; type void;
type never; type never;
type IntegerLiteral constexpr 'int64_t';
namespace torque_internal { namespace torque_internal {
struct Reference<T: type> { struct Reference<T: type> {
const object: HeapObject; const object: HeapObject;
...@@ -112,6 +114,8 @@ extern macro TaggedToHeapObject(Object): HeapObject ...@@ -112,6 +114,8 @@ extern macro TaggedToHeapObject(Object): HeapObject
extern macro Float64SilenceNaN(float64): float64; extern macro Float64SilenceNaN(float64): float64;
extern macro IntPtrConstant(constexpr int31): intptr; 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; macro FromConstexpr<To: type, From: type>(o: From): To;
FromConstexpr<Smi, constexpr Smi>(s: constexpr Smi): Smi { FromConstexpr<Smi, constexpr Smi>(s: constexpr Smi): Smi {
...@@ -133,6 +137,15 @@ FromConstexpr<bool, constexpr bool>(b: constexpr bool): bool { ...@@ -133,6 +137,15 @@ FromConstexpr<bool, constexpr bool>(b: constexpr bool): bool {
FromConstexpr<int32, constexpr int31>(i: constexpr int31): int32 { FromConstexpr<int32, constexpr int31>(i: constexpr int31): int32 {
return %FromConstexpr<int32>(i); 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 macro Cast<A : type extends Object>(implicit context: Context)(o: Object): A
labels CastError { labels CastError {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#ifndef V8_TORQUE_DEBUG_MACRO_SHIMS_H_ #ifndef V8_TORQUE_DEBUG_MACRO_SHIMS_H_
#define 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 "src/objects/smi.h"
#include "tools/debug_helper/debug-helper-internal.h" #include "tools/debug_helper/debug-helper-internal.h"
...@@ -77,6 +78,9 @@ inline Value<int32_t> SmiUntag(d::MemoryAccessor accessor, uintptr_t s_t) { ...@@ -77,6 +78,9 @@ inline Value<int32_t> SmiUntag(d::MemoryAccessor accessor, uintptr_t s_t) {
Smi s(s_t); Smi s(s_t);
return {d::MemoryAccessResult::kOk, s.value()}; 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, inline Value<bool> UintPtrLessThan(d::MemoryAccessor accessor, uintptr_t a,
uintptr_t b) { uintptr_t b) {
return {d::MemoryAccessResult::kOk, a < b}; return {d::MemoryAccessResult::kOk, a < b};
...@@ -97,6 +101,19 @@ inline Value<bool> Word32NotEqual(d::MemoryAccessor accessor, uint32_t a, ...@@ -97,6 +101,19 @@ inline Value<bool> Word32NotEqual(d::MemoryAccessor accessor, uint32_t a,
uint32_t b) { uint32_t b) {
return {d::MemoryAccessResult::kOk, a != 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 CodeStubAssembler
} // namespace TorqueDebugMacroShims } // 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