Skip to content

Commit

Permalink
deps: V8: cherry-pick c875e86df1d7
Browse files Browse the repository at this point in the history
Original commit message:

    [bigint] Convert BigInt property names to decimal

    Hexadecimal/octal/binary BigInt property names should be converted
    to decimal, i.e. the following object literals should all be equivalent:
    var o = {0xF: 1}, p = {0xFn: 1}, q = {15: 1}, r = {15n: 1}.

    Test case by yangwenming@bytedance.com, uploaded at
    https://chromium-review.googlesource.com/c/v8/v8/+/3634937

    Fixed: v8:10600
    Change-Id: Ie1d8a16e95697cd31cbc0784843779c921ce91fa
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3642302
    Reviewed-by: Toon Verwaest <verwaest@chromium.org>
    Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#80490}

Refs: v8/v8@c875e86
PR-URL: #46501
Refs: v8/v8@c875e86
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
  • Loading branch information
sepehrst authored and juanarbol committed Mar 5, 2023
1 parent b266adb commit 3ea53c5
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 2 deletions.
2 changes: 1 addition & 1 deletion common.gypi
Expand Up @@ -36,7 +36,7 @@

# Reset this number to 0 on major V8 upgrades.
# Increment by one for each non-official patch applied to deps/v8.
'v8_embedder_string': '-node.22',
'v8_embedder_string': '-node.23',

##### V8 defaults for Node.js #####

Expand Down
25 changes: 25 additions & 0 deletions deps/v8/src/numbers/conversions.cc
Expand Up @@ -12,6 +12,7 @@
#include "src/base/numbers/dtoa.h"
#include "src/base/numbers/strtod.h"
#include "src/base/platform/wrappers.h"
#include "src/base/small-vector.h"
#include "src/bigint/bigint.h"
#include "src/common/assert-scope.h"
#include "src/handles/handles.h"
Expand Down Expand Up @@ -970,6 +971,23 @@ class StringToBigIntHelper : public StringToIntHelper<IsolateT> {
UNREACHABLE();
}

// Used for converting BigInt literals. The scanner has already checked
// that the literal is valid and not too big, so this always succeeds.
std::unique_ptr<char[]> DecimalString(bigint::Processor* processor) {
DCHECK_EQ(behavior_, Behavior::kLiteral);
this->ParseInt();
DCHECK_EQ(this->state(), State::kDone);
int num_digits = accumulator_.ResultLength();
base::SmallVector<bigint::digit_t, 8> digit_storage(num_digits);
bigint::RWDigits digits(digit_storage.data(), num_digits);
processor->FromString(digits, &accumulator_);
int num_chars = bigint::ToStringResultLength(digits, 10, false);
std::unique_ptr<char[]> out(new char[num_chars + 1]);
processor->ToString(out.get(), &num_chars, digits, 10, false);
out[num_chars] = '\0';
return out;
}

private:
template <class Char>
void ParseInternal(Char start) {
Expand Down Expand Up @@ -1018,6 +1036,13 @@ template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE)
MaybeHandle<BigInt> BigIntLiteral(LocalIsolate* isolate,
const char* string);

std::unique_ptr<char[]> BigIntLiteralToDecimal(
LocalIsolate* isolate, base::Vector<const uint8_t> literal) {
StringToBigIntHelper<LocalIsolate> helper(nullptr, literal.begin(),
literal.length());
return helper.DecimalString(isolate->bigint_processor());
}

const char* DoubleToCString(double v, base::Vector<char> buffer) {
switch (FPCLASSIFY_NAMESPACE::fpclassify(v)) {
case FP_NAN:
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/numbers/conversions.h
Expand Up @@ -119,6 +119,8 @@ const int kDoubleToCStringMinBufferSize = 100;
V8_EXPORT_PRIVATE const char* DoubleToCString(double value,
base::Vector<char> buffer);

V8_EXPORT_PRIVATE std::unique_ptr<char[]> BigIntLiteralToDecimal(
LocalIsolate* isolate, base::Vector<const uint8_t> literal);
// Convert an int to a null-terminated string. The returned string is
// located inside the buffer, but not necessarily at the start.
V8_EXPORT_PRIVATE const char* IntToCString(int n, base::Vector<char> buffer);
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/parsing/parser-base.h
Expand Up @@ -2288,7 +2288,7 @@ typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseProperty(

case Token::BIGINT: {
Consume(Token::BIGINT);
prop_info->name = impl()->GetSymbol();
prop_info->name = impl()->GetBigIntAsSymbol();
is_array_index = impl()->IsArrayIndex(prop_info->name, &index);
break;
}
Expand Down
10 changes: 10 additions & 0 deletions deps/v8/src/parsing/parser.cc
Expand Up @@ -247,6 +247,16 @@ bool Parser::CollapseNaryExpression(Expression** x, Expression* y,
return true;
}

const AstRawString* Parser::GetBigIntAsSymbol() {
base::Vector<const uint8_t> literal = scanner()->BigIntLiteral();
if (literal[0] != '0' || literal.length() == 1) {
return ast_value_factory()->GetOneByteString(literal);
}
std::unique_ptr<char[]> decimal =
BigIntLiteralToDecimal(local_isolate_, literal);
return ast_value_factory()->GetOneByteString(decimal.get());
}

Expression* Parser::BuildUnaryExpression(Expression* expression,
Token::Value op, int pos) {
DCHECK_NOT_NULL(expression);
Expand Down
2 changes: 2 additions & 0 deletions deps/v8/src/parsing/parser.h
Expand Up @@ -790,6 +790,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
return ast_value_factory()->GetOneByteString(string);
}

const AstRawString* GetBigIntAsSymbol();

class ThisExpression* ThisExpression() {
UseThis();
return factory()->ThisExpression();
Expand Down
4 changes: 4 additions & 0 deletions deps/v8/src/parsing/preparser.h
Expand Up @@ -1522,6 +1522,10 @@ class PreParser : public ParserBase<PreParser> {
return PreParserIdentifier::Default();
}

V8_INLINE PreParserIdentifier GetBigIntAsSymbol() const {
return PreParserIdentifier::Default();
}

V8_INLINE PreParserExpression ThisExpression() {
UseThis();
return PreParserExpression::This();
Expand Down
3 changes: 3 additions & 0 deletions deps/v8/src/parsing/scanner.h
Expand Up @@ -336,6 +336,9 @@ class V8_EXPORT_PRIVATE Scanner {
AstValueFactory* ast_value_factory) const;

double DoubleValue();
base::Vector<const uint8_t> BigIntLiteral() const {
return literal_one_byte_string();
}

const char* CurrentLiteralAsCString(Zone* zone) const;

Expand Down
23 changes: 23 additions & 0 deletions deps/v8/test/mjsunit/harmony/bigint/property-names.js
Expand Up @@ -7,3 +7,26 @@ assertEquals(it, 1);

var { 999999999999999999n: it } = { 999999999999999999n: 1 }; // greater than max safe integer
assertEquals(it, 1);

var obj = { 0xfffffffffffffffffffffn: 1};
assertEquals(1, obj["19342813113834066795298815"]);

var obj2 = {0o777777777777777777777777777n: 1};
assertEquals(1, obj2["2417851639229258349412351"]);

var obj3 = { 0x4n: 'hi' };

assertEquals('hi', obj3[4]);
assertEquals(undefined, obj3["0x4"]);

let obj4 =
{12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890n: 1};
assertEquals(
1,
obj4["12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"]);

// 130 hex digits
let obj5 = {0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffn: 1};
assertEquals(
1,
obj5["3432398830065304857490950399540696608634717650071652704697231729592771591698828026061279820330727277488648155695740429018560993999858321906287014145557528575"]);

0 comments on commit 3ea53c5

Please sign in to comment.