diff --git a/common.gypi b/common.gypi index ecb5dd907f2b75..851816e084565d 100644 --- a/common.gypi +++ b/common.gypi @@ -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.8', + 'v8_embedder_string': '-node.9', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/numbers/conversions.cc b/deps/v8/src/numbers/conversions.cc index 0683402794dbe7..7f1f11e4dcd105 100644 --- a/deps/v8/src/numbers/conversions.cc +++ b/deps/v8/src/numbers/conversions.cc @@ -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" @@ -970,6 +971,23 @@ class StringToBigIntHelper : public StringToIntHelper { 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 DecimalString(bigint::Processor* processor) { + DCHECK_EQ(behavior_, Behavior::kLiteral); + this->ParseInt(); + DCHECK_EQ(this->state(), State::kDone); + int num_digits = accumulator_.ResultLength(); + base::SmallVector 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 out(new char[num_chars + 1]); + processor->ToString(out.get(), &num_chars, digits, 10, false); + out[num_chars] = '\0'; + return out; + } + private: template void ParseInternal(Char start) { @@ -1018,6 +1036,13 @@ template EXPORT_TEMPLATE_DEFINE(V8_EXPORT_PRIVATE) MaybeHandle BigIntLiteral(LocalIsolate* isolate, const char* string); +std::unique_ptr BigIntLiteralToDecimal( + LocalIsolate* isolate, base::Vector literal) { + StringToBigIntHelper helper(nullptr, literal.begin(), + literal.length()); + return helper.DecimalString(isolate->bigint_processor()); +} + const char* DoubleToCString(double v, base::Vector buffer) { switch (FPCLASSIFY_NAMESPACE::fpclassify(v)) { case FP_NAN: diff --git a/deps/v8/src/numbers/conversions.h b/deps/v8/src/numbers/conversions.h index 9232de93cafe90..fce0d726544527 100644 --- a/deps/v8/src/numbers/conversions.h +++ b/deps/v8/src/numbers/conversions.h @@ -119,6 +119,8 @@ const int kDoubleToCStringMinBufferSize = 100; V8_EXPORT_PRIVATE const char* DoubleToCString(double value, base::Vector buffer); +V8_EXPORT_PRIVATE std::unique_ptr BigIntLiteralToDecimal( + LocalIsolate* isolate, base::Vector 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 buffer); diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index df829ff8cac43c..cfa91e446f82e9 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -2288,7 +2288,7 @@ typename ParserBase::ExpressionT ParserBase::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; } diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc index 6ee70886a99f8d..9789909456ee5e 100644 --- a/deps/v8/src/parsing/parser.cc +++ b/deps/v8/src/parsing/parser.cc @@ -247,6 +247,16 @@ bool Parser::CollapseNaryExpression(Expression** x, Expression* y, return true; } +const AstRawString* Parser::GetBigIntAsSymbol() { + base::Vector literal = scanner()->BigIntLiteral(); + if (literal[0] != '0' || literal.length() == 1) { + return ast_value_factory()->GetOneByteString(literal); + } + std::unique_ptr 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); diff --git a/deps/v8/src/parsing/parser.h b/deps/v8/src/parsing/parser.h index 1d8fa2515df380..d3245d7da952b9 100644 --- a/deps/v8/src/parsing/parser.h +++ b/deps/v8/src/parsing/parser.h @@ -790,6 +790,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase) { return ast_value_factory()->GetOneByteString(string); } + const AstRawString* GetBigIntAsSymbol(); + class ThisExpression* ThisExpression() { UseThis(); return factory()->ThisExpression(); diff --git a/deps/v8/src/parsing/preparser.h b/deps/v8/src/parsing/preparser.h index ff64f9a5f55bba..7ad65961e593c5 100644 --- a/deps/v8/src/parsing/preparser.h +++ b/deps/v8/src/parsing/preparser.h @@ -1522,6 +1522,10 @@ class PreParser : public ParserBase { return PreParserIdentifier::Default(); } + V8_INLINE PreParserIdentifier GetBigIntAsSymbol() const { + return PreParserIdentifier::Default(); + } + V8_INLINE PreParserExpression ThisExpression() { UseThis(); return PreParserExpression::This(); diff --git a/deps/v8/src/parsing/scanner.h b/deps/v8/src/parsing/scanner.h index 0fe907632de4bf..3a38ed243bb1dd 100644 --- a/deps/v8/src/parsing/scanner.h +++ b/deps/v8/src/parsing/scanner.h @@ -336,6 +336,9 @@ class V8_EXPORT_PRIVATE Scanner { AstValueFactory* ast_value_factory) const; double DoubleValue(); + base::Vector BigIntLiteral() const { + return literal_one_byte_string(); + } const char* CurrentLiteralAsCString(Zone* zone) const; diff --git a/deps/v8/test/mjsunit/harmony/bigint/property-names.js b/deps/v8/test/mjsunit/harmony/bigint/property-names.js index ac65e1041d50fa..400b51f51c67a3 100644 --- a/deps/v8/test/mjsunit/harmony/bigint/property-names.js +++ b/deps/v8/test/mjsunit/harmony/bigint/property-names.js @@ -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"]);