Revert "[Torque] Generalize Torque literals to larger size"
This reverts commit 757830b02b
.
Reason for revert: Speculatively revert due to a number of
performance regressions
Original change's description:
> [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/+/3329792
> 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@{#78671}
Bug: v8:7793
Change-Id: I9896e28b3c69b8cf2488bf93e993ec320d8c5d2e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3401866
Reviewed-by: Nico Hartmann <nicohartmann@chromium.org>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78706}
This commit is contained in:
parent
bbe2ef4cfd
commit
362e265d4c
@ -922,9 +922,6 @@ filegroup(
|
||||
filegroup(
|
||||
name = "torque_base_files",
|
||||
srcs = [
|
||||
":v8_bigint",
|
||||
"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",
|
||||
@ -2800,8 +2797,6 @@ 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"],
|
||||
|
6
BUILD.gn
6
BUILD.gn
@ -2290,7 +2290,6 @@ v8_source_set("v8_initializers") {
|
||||
deps = [
|
||||
":torque_generated_initializers",
|
||||
":v8_base_without_compiler",
|
||||
":v8_bigint",
|
||||
":v8_shared_internal_headers",
|
||||
":v8_tracing",
|
||||
]
|
||||
@ -2366,8 +2365,6 @@ 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) {
|
||||
@ -4856,8 +4853,6 @@ 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",
|
||||
@ -4911,7 +4906,6 @@ v8_source_set("torque_base") {
|
||||
]
|
||||
|
||||
deps = [
|
||||
":v8_bigint",
|
||||
":v8_flags",
|
||||
":v8_shared_internal_headers",
|
||||
]
|
||||
|
@ -301,10 +301,6 @@ 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) {
|
||||
@ -422,13 +418,13 @@ class FromStringAccumulator {
|
||||
: max_digits_(std::max(max_digits, kStackParts)) {}
|
||||
|
||||
// Step 2: Call this method to read all characters.
|
||||
// {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);
|
||||
// {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);
|
||||
|
||||
// Step 3: Check if a result is available, and determine its required
|
||||
// allocation size (guaranteed to be <= max_digits passed to the constructor).
|
||||
@ -438,13 +434,14 @@ class FromStringAccumulator {
|
||||
}
|
||||
|
||||
// Step 4: Use BigIntProcessor::FromString() to retrieve the result into an
|
||||
// {RWDigits} struct allocated for the size returned by step 3.
|
||||
// {RWDigits} struct allocated for the size returned by step 2.
|
||||
|
||||
private:
|
||||
friend class ProcessorImpl;
|
||||
|
||||
template <class CharIt>
|
||||
ALWAYS_INLINE CharIt ParsePowerTwo(CharIt start, CharIt end, digit_t radix);
|
||||
template <class Char>
|
||||
ALWAYS_INLINE const Char* ParsePowerTwo(const Char* start, const Char* end,
|
||||
digit_t radix);
|
||||
|
||||
ALWAYS_INLINE bool AddPart(digit_t multiplier, digit_t part, bool is_last);
|
||||
ALWAYS_INLINE bool AddPart(digit_t part);
|
||||
@ -494,9 +491,10 @@ 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 CharIt>
|
||||
CharIt FromStringAccumulator::ParsePowerTwo(CharIt current, CharIt end,
|
||||
digit_t radix) {
|
||||
template <class Char>
|
||||
const Char* FromStringAccumulator::ParsePowerTwo(const Char* current,
|
||||
const Char* end,
|
||||
digit_t radix) {
|
||||
radix_ = static_cast<uint8_t>(radix);
|
||||
const int char_bits = kCharBits[radix >> 2];
|
||||
int bits_left;
|
||||
@ -530,10 +528,11 @@ CharIt FromStringAccumulator::ParsePowerTwo(CharIt current, CharIt end,
|
||||
return current;
|
||||
}
|
||||
|
||||
template <class CharIt>
|
||||
CharIt FromStringAccumulator::Parse(CharIt start, CharIt end, digit_t radix) {
|
||||
template <class Char>
|
||||
const Char* FromStringAccumulator::Parse(const Char* start, const Char* end,
|
||||
digit_t radix) {
|
||||
BIGINT_H_DCHECK(2 <= radix && radix <= 36);
|
||||
CharIt current = start;
|
||||
const Char* current = start;
|
||||
#if !HAVE_BUILTIN_MUL_OVERFLOW
|
||||
const digit_t kMaxMultiplier = (~digit_t{0}) / radix;
|
||||
#endif
|
||||
|
@ -127,7 +127,6 @@ 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) {
|
||||
stack.objects[0] = TheHole;
|
||||
StoreFixedArrayElement(stack, 0, TheHole, SKIP_WRITE_BARRIER);
|
||||
} else
|
||||
deferred {
|
||||
JoinStackPop(stack, receiver);
|
||||
|
@ -26,8 +26,6 @@
|
||||
type void;
|
||||
type never;
|
||||
|
||||
type IntegerLiteral constexpr 'IntegerLiteral';
|
||||
|
||||
type Tagged generates 'TNode<MaybeObject>' constexpr 'MaybeObject';
|
||||
type StrongTagged extends Tagged
|
||||
generates 'TNode<Object>' constexpr 'Object';
|
||||
@ -614,7 +612,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) return SmiConstant(0);
|
||||
if (value == 0.0) return SmiConstant(0);
|
||||
const result = ChangeFloat64ToTagged(value);
|
||||
dcheck(IsNumberNormalized(result));
|
||||
return result;
|
||||
@ -986,38 +984,6 @@ 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;
|
||||
@ -1207,29 +1173,19 @@ 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,59 +4,6 @@
|
||||
|
||||
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);
|
||||
}
|
||||
@ -378,10 +325,6 @@ 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 ? Convert<int32>(1) : Convert<int32>(0);
|
||||
let length: int32 = isNegative ? 1 : 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.0) goto Int32(asInt32);
|
||||
if (absInput < kMaxAbsValue && absInput >= 1) 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.0);
|
||||
return AllocateHeapNumberWithValue(Convert<float64>(h) * -1);
|
||||
} 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) goto InvalidCount;
|
||||
if (n == V8_INFINITY || n < 0.0) goto InvalidCount;
|
||||
|
||||
// 6. If n is 0, return the empty String.
|
||||
if (s.length_uint32 == 0) goto EmptyString;
|
||||
|
@ -105,10 +105,6 @@ 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,7 +17,6 @@
|
||||
#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"
|
||||
@ -14755,19 +14754,6 @@ 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,7 +13,6 @@
|
||||
#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"
|
||||
@ -3744,45 +3743,6 @@ 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; }
|
||||
|
@ -1,78 +0,0 @@
|
||||
// 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_
|
@ -1,142 +0,0 @@
|
||||
// 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,11 +5,12 @@
|
||||
#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,12 +5,13 @@
|
||||
#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"
|
||||
|
@ -81,7 +81,7 @@ class TurbofanOtherNumberConstantType extends TurbofanType {
|
||||
}
|
||||
|
||||
macro IsMinusZero(x: float64): bool {
|
||||
return x == 0 && 1.0 / x < 0;
|
||||
return x == 0 && 1 / x < 0;
|
||||
}
|
||||
|
||||
macro TestTurbofanBitsetType(
|
||||
@ -95,17 +95,17 @@ macro TestTurbofanBitsetType(
|
||||
if (IsInteger(value)) {
|
||||
if (IsMinusZero(valueF)) {
|
||||
return bitsetLow.minus_zero;
|
||||
} else if (valueF < 0 - Convert<float64>(0x80000000)) {
|
||||
} else if (valueF < Convert<float64>(-0x80000000)) {
|
||||
return bitsetLow.other_number;
|
||||
} else if (valueF < 0 - Convert<float64>(0x40000000)) {
|
||||
} else if (valueF < -0x40000000) {
|
||||
return bitsetLow.other_signed32;
|
||||
} else if (valueF < 0) {
|
||||
return bitsetLow.negative31;
|
||||
} else if (valueF < Convert<float64>(0x40000000)) {
|
||||
return bitsetLow.unsigned30;
|
||||
} else if (valueF < Convert<float64>(0x80000000)) {
|
||||
} else if (valueF < 0x80000000) {
|
||||
return bitsetLow.other_unsigned31;
|
||||
} else if (valueF <= Convert<float64>(0xffffffff)) {
|
||||
} else if (valueF <= 0xffffffff) {
|
||||
return bitsetLow.other_unsigned32;
|
||||
} else {
|
||||
return bitsetLow.other_number;
|
||||
|
@ -14,7 +14,6 @@
|
||||
#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"
|
||||
@ -34,8 +33,7 @@ namespace torque {
|
||||
V(ConditionalExpression) \
|
||||
V(IdentifierExpression) \
|
||||
V(StringLiteralExpression) \
|
||||
V(IntegerLiteralExpression) \
|
||||
V(FloatingPointLiteralExpression) \
|
||||
V(NumberLiteralExpression) \
|
||||
V(FieldAccessExpression) \
|
||||
V(ElementAccessExpression) \
|
||||
V(DereferenceExpression) \
|
||||
@ -461,28 +459,16 @@ struct StringLiteralExpression : Expression {
|
||||
std::string literal;
|
||||
};
|
||||
|
||||
struct IntegerLiteralExpression : Expression {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(IntegerLiteralExpression)
|
||||
IntegerLiteralExpression(SourcePosition pos, IntegerLiteral value)
|
||||
: Expression(kKind, pos), value(std::move(value)) {}
|
||||
struct NumberLiteralExpression : Expression {
|
||||
DEFINE_AST_NODE_LEAF_BOILERPLATE(NumberLiteralExpression)
|
||||
NumberLiteralExpression(SourcePosition pos, double number)
|
||||
: Expression(kKind, pos), number(number) {}
|
||||
|
||||
void VisitAllSubExpressions(VisitCallback callback) override {
|
||||
callback(this);
|
||||
}
|
||||
|
||||
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;
|
||||
double number;
|
||||
};
|
||||
|
||||
struct ElementAccessExpression : LocationExpression {
|
||||
|
@ -67,8 +67,6 @@ 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,7 +127,6 @@ 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,8 +44,6 @@ enum class ParseResultHolderBase::TypeId {
|
||||
kStdString,
|
||||
kBool,
|
||||
kInt32,
|
||||
kDouble,
|
||||
kIntegerLiteral,
|
||||
kStdVectorOfString,
|
||||
kExpressionPtr,
|
||||
kIdentifierPtr,
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
#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"
|
||||
@ -183,7 +182,6 @@ 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"
|
||||
@ -945,18 +943,22 @@ VisitResult ImplementationVisitor::Visit(AssignmentExpression* expr) {
|
||||
return scope.Yield(assignment_value);
|
||||
}
|
||||
|
||||
VisitResult ImplementationVisitor::Visit(FloatingPointLiteralExpression* expr) {
|
||||
VisitResult ImplementationVisitor::Visit(NumberLiteralExpression* 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->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 << ")";
|
||||
<< expr->number;
|
||||
return VisitResult{result_type, str.str()};
|
||||
}
|
||||
|
||||
@ -2846,9 +2848,7 @@ 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 ||
|
||||
output_type_ == OutputType::kCCDebug) &&
|
||||
!inline_macro) {
|
||||
if (output_type_ == OutputType::kCC && !inline_macro) {
|
||||
if (auto* torque_macro = TorqueMacro::DynamicCast(macro)) {
|
||||
auto* streams = CurrentFileStreams::Get();
|
||||
SourceId file = streams ? streams->file : SourceId::Invalid();
|
||||
@ -2862,32 +2862,14 @@ VisitResult ImplementationVisitor::GenerateCall(
|
||||
std::stringstream result;
|
||||
result << "(";
|
||||
bool first = true;
|
||||
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;
|
||||
}
|
||||
if (auto* extern_macro = ExternMacro::DynamicCast(macro)) {
|
||||
result << extern_macro->external_assembler_name() << "(state_)."
|
||||
<< extern_macro->ExternalName() << "(";
|
||||
} else {
|
||||
result << macro->ExternalName() << "(state_";
|
||||
first = false;
|
||||
}
|
||||
for (VisitResult arg : converted_arguments) {
|
||||
for (VisitResult arg : arguments.parameters) {
|
||||
DCHECK(!arg.IsOnStack());
|
||||
if (!first) {
|
||||
result << ", ";
|
||||
|
@ -555,8 +555,7 @@ class ImplementationVisitor {
|
||||
VisitResult Visit(IncrementDecrementExpression* expr);
|
||||
VisitResult Visit(AssignmentExpression* expr);
|
||||
VisitResult Visit(StringLiteralExpression* expr);
|
||||
VisitResult Visit(FloatingPointLiteralExpression* expr);
|
||||
VisitResult Visit(IntegerLiteralExpression* expr);
|
||||
VisitResult Visit(NumberLiteralExpression* expr);
|
||||
VisitResult Visit(AssumeTypeImpossibleExpression* expr);
|
||||
VisitResult Visit(TryLabelExpression* expr);
|
||||
VisitResult Visit(StatementExpression* expr);
|
||||
|
@ -10,8 +10,6 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "src/numbers/integer-literal.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -36,15 +34,6 @@ 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
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "src/bigint/bigint.h"
|
||||
#include "src/flags/flags.h"
|
||||
#include "src/torque/ast.h"
|
||||
#include "src/torque/constants.h"
|
||||
@ -93,12 +92,6 @@ 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;
|
||||
@ -854,8 +847,8 @@ class AnnotationSet {
|
||||
std::map<std::string, std::pair<AnnotationParameter, SourcePosition>> map_;
|
||||
};
|
||||
|
||||
base::Optional<ParseResult> YieldInt32(ParseResultIterator* child_results) {
|
||||
std::string value = child_results->matched_input().ToString();
|
||||
base::Optional<ParseResult> MakeInt32(ParseResultIterator* child_results) {
|
||||
std::string value = child_results->NextAs<std::string>();
|
||||
size_t num_chars_converted = 0;
|
||||
int result = 0;
|
||||
try {
|
||||
@ -872,58 +865,6 @@ base::Optional<ParseResult> YieldInt32(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) {
|
||||
// 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(
|
||||
ParseResultIterator* child_results) {
|
||||
std::string value = child_results->NextAs<std::string>();
|
||||
@ -1944,17 +1885,29 @@ base::Optional<ParseResult> MakeAssignmentExpression(
|
||||
return ParseResult{result};
|
||||
}
|
||||
|
||||
base::Optional<ParseResult> MakeFloatingPointLiteralExpression(
|
||||
base::Optional<ParseResult> MakeNumberLiteralExpression(
|
||||
ParseResultIterator* child_results) {
|
||||
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));
|
||||
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);
|
||||
return ParseResult{result};
|
||||
}
|
||||
|
||||
@ -2114,19 +2067,8 @@ 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,
|
||||
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, MakeNode<NumberLiteralExpression>(1),
|
||||
MakeNode<NumberLiteralExpression>(0));
|
||||
}
|
||||
index_info = ClassFieldIndexInfo{*index, optional};
|
||||
}
|
||||
@ -2245,24 +2187,12 @@ struct TorqueGrammar : Grammar {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool MatchIntegerLiteral(InputPosition* pos) {
|
||||
static bool MatchDecimalLiteral(InputPosition* pos) {
|
||||
InputPosition current = *pos;
|
||||
bool found_digit = false;
|
||||
MatchString("-", ¤t);
|
||||
while (MatchChar(std::isdigit, ¤t)) 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("-", ¤t);
|
||||
while (MatchChar(std::isdigit, ¤t)) found_digit = true;
|
||||
if (!MatchString(".", ¤t)) return false;
|
||||
MatchString(".", ¤t);
|
||||
while (MatchChar(std::isdigit, ¤t)) found_digit = true;
|
||||
if (!found_digit) return false;
|
||||
*pos = current;
|
||||
@ -2347,18 +2277,13 @@ struct TorqueGrammar : Grammar {
|
||||
// Result: std::string
|
||||
Symbol externalString = {Rule({&stringLiteral}, StringLiteralUnquoteAction)};
|
||||
|
||||
// Result: IntegerLiteral
|
||||
Symbol integerLiteral = {
|
||||
Rule({Pattern(MatchIntegerLiteral)}, YieldIntegerLiteral),
|
||||
Rule({Pattern(MatchHexLiteral)}, YieldIntegerLiteral)};
|
||||
|
||||
// Result: double
|
||||
Symbol floatingPointLiteral = {
|
||||
Rule({Pattern(MatchFloatingPointLiteral)}, YieldDouble)};
|
||||
// Result: std::string
|
||||
Symbol decimalLiteral = {
|
||||
Rule({Pattern(MatchDecimalLiteral)}, YieldMatchedInput),
|
||||
Rule({Pattern(MatchHexLiteral)}, YieldMatchedInput)};
|
||||
|
||||
// Result: int32_t
|
||||
Symbol int32Literal = {Rule({Pattern(MatchIntegerLiteral)}, YieldInt32),
|
||||
Rule({Pattern(MatchHexLiteral)}, YieldInt32)};
|
||||
Symbol int32Literal = {Rule({&decimalLiteral}, MakeInt32)};
|
||||
|
||||
// Result: AnnotationParameter
|
||||
Symbol annotationParameter = {
|
||||
@ -2577,8 +2502,7 @@ struct TorqueGrammar : Grammar {
|
||||
MakeReferenceFieldAccessExpression),
|
||||
Rule({&primaryExpression, Token("["), expression, Token("]")},
|
||||
MakeElementAccessExpression),
|
||||
Rule({&integerLiteral}, MakeIntegerLiteralExpression),
|
||||
Rule({&floatingPointLiteral}, MakeFloatingPointLiteralExpression),
|
||||
Rule({&decimalLiteral}, MakeNumberLiteralExpression),
|
||||
Rule({&stringLiteral}, MakeStringLiteralExpression),
|
||||
Rule({&simpleType, &initializerList}, MakeStructExpression),
|
||||
Rule({&newExpression}),
|
||||
|
@ -315,10 +315,6 @@ 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 =
|
||||
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);
|
||||
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);
|
||||
}
|
||||
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<IntegerLiteralExpression>(IntegerLiteral(*field.offset));
|
||||
MakeNode<NumberLiteralExpression>(static_cast<double>(*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<IntegerLiteralExpression>(
|
||||
IntegerLiteral(previous_element_size));
|
||||
MakeNode<NumberLiteralExpression>(
|
||||
static_cast<double>(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) ? FromConstexpr<int31>(0) : 1;
|
||||
let _var2: int31 = FromConstexpr<bool>(42 == 0) ? FromConstexpr<int31>(1) : 0;
|
||||
let _var1: int31 = FromConstexpr<bool>(42 == 0) ? 0 : 1;
|
||||
let _var2: int31 = FromConstexpr<bool>(42 == 0) ? 1 : 0;
|
||||
return True;
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,6 @@ constexpr const char* kTestTorquePrelude = R"(
|
||||
type void;
|
||||
type never;
|
||||
|
||||
type IntegerLiteral constexpr 'int64_t';
|
||||
|
||||
namespace torque_internal {
|
||||
struct Reference<T: type> {
|
||||
const object: HeapObject;
|
||||
@ -114,8 +112,6 @@ 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 {
|
||||
@ -137,15 +133,6 @@ 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,7 +8,6 @@
|
||||
#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"
|
||||
|
||||
@ -78,9 +77,6 @@ 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,19 +97,6 @@ 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
|
||||
|
Loading…
Reference in New Issue
Block a user