Commit 9d3002fd authored by Mathias Bynens's avatar Mathias Bynens Committed by Commit Bot

[esnext] Make ECMAScript a syntactic superset of JSON

This patch makes ECMAScript a syntactic superset of JSON by allowing
U+2028 and U+2029 in string literals.

Proposal repo: https://github.com/tc39/proposal-json-superset

Bug: v8:7418
Change-Id: I7ef4ae6d85854ebc44a66e0eaf789814576832b7
Reviewed-on: https://chromium-review.googlesource.com/921228Reviewed-by: 's avatarSathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Mathias Bynens <mathias@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51313}
parent 9bd1e7d3
...@@ -4281,6 +4281,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_dynamic_import) ...@@ -4281,6 +4281,7 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_dynamic_import)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_import_meta) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_import_meta)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrict_constructor_return) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_restrict_constructor_return)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_optional_catch_binding) EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_optional_catch_binding)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_subsume_json)
void InstallPublicSymbol(Factory* factory, Handle<Context> native_context, void InstallPublicSymbol(Factory* factory, Handle<Context> native_context,
const char* name, Handle<Symbol> value) { const char* name, Handle<Symbol> value) {
......
...@@ -203,8 +203,11 @@ DEFINE_IMPLICATION(harmony_class_fields, harmony_public_fields) ...@@ -203,8 +203,11 @@ DEFINE_IMPLICATION(harmony_class_fields, harmony_public_fields)
DEFINE_IMPLICATION(harmony_class_fields, harmony_static_fields) DEFINE_IMPLICATION(harmony_class_fields, harmony_static_fields)
DEFINE_IMPLICATION(harmony_class_fields, harmony_private_fields) DEFINE_IMPLICATION(harmony_class_fields, harmony_private_fields)
// Update bootstrapper.cc whenever adding a new feature flag.
// Features that are still work in progress (behind individual flags). // Features that are still work in progress (behind individual flags).
#define HARMONY_INPROGRESS(V) \ #define HARMONY_INPROGRESS(V) \
V(harmony_subsume_json, "harmony subsume JSON") \
V(harmony_array_prototype_values, "harmony Array.prototype.values") \ V(harmony_array_prototype_values, "harmony Array.prototype.values") \
V(harmony_function_sent, "harmony function.sent") \ V(harmony_function_sent, "harmony function.sent") \
V(harmony_do_expressions, "harmony do-expressions") \ V(harmony_do_expressions, "harmony do-expressions") \
......
...@@ -1071,8 +1071,11 @@ Token::Value Scanner::ScanString() { ...@@ -1071,8 +1071,11 @@ Token::Value Scanner::ScanString() {
AddLiteralChar(c); AddLiteralChar(c);
} }
while (c0_ != quote && c0_ != kEndOfInput && bool (*line_terminator_func)(unsigned int) =
!unibrow::IsLineTerminator(c0_)) { FLAG_harmony_subsume_json ? unibrow::IsStringLiteralLineTerminator
: unibrow::IsLineTerminator;
while (c0_ != quote && c0_ != kEndOfInput && !line_terminator_func(c0_)) {
uc32 c = c0_; uc32 c = c0_;
Advance(); Advance();
if (c == '\\') { if (c == '\\') {
......
...@@ -204,6 +204,10 @@ V8_INLINE bool IsLineTerminator(uchar c) { ...@@ -204,6 +204,10 @@ V8_INLINE bool IsLineTerminator(uchar c) {
return c == 0x000A || c == 0x000D || c == 0x2028 || c == 0x2029; return c == 0x000A || c == 0x000D || c == 0x2028 || c == 0x2029;
} }
V8_INLINE bool IsStringLiteralLineTerminator(uchar c) {
return c == 0x000A || c == 0x000D;
}
#ifndef V8_INTL_SUPPORT #ifndef V8_INTL_SUPPORT
struct ToLowercase { struct ToLowercase {
static const int kMaxWidth = 3; static const int kMaxWidth = 3;
......
...@@ -273,7 +273,7 @@ TEST(UsingCachedData) { ...@@ -273,7 +273,7 @@ TEST(UsingCachedData) {
CcTest::i_isolate()->stack_guard()->SetStackLimit( CcTest::i_isolate()->stack_guard()->SetStackLimit(
i::GetCurrentStackPosition() - 128 * 1024); i::GetCurrentStackPosition() - 128 * 1024);
// Source containing functions that might be lazily compiled and all types // Source containing functions that might be lazily compiled and all types
// of symbols (string, propertyName, regexp). // of symbols (string, propertyName, regexp).
const char* source = const char* source =
"var x = 42;" "var x = 42;"
...@@ -1478,7 +1478,10 @@ void TestParserSync(const char* source, const ParserFlag* varying_flags, ...@@ -1478,7 +1478,10 @@ void TestParserSync(const char* source, const ParserFlag* varying_flags,
bool is_module = false, bool test_preparser = true, bool is_module = false, bool test_preparser = true,
bool ignore_error_msg = false) { bool ignore_error_msg = false) {
i::Handle<i::String> str = i::Handle<i::String> str =
CcTest::i_isolate()->factory()->NewStringFromAsciiChecked(source); CcTest::i_isolate()
->factory()
->NewStringFromUtf8(Vector<const char>(source, strlen(source)))
.ToHandleChecked();
for (int bits = 0; bits < (1 << varying_flags_length); bits++) { for (int bits = 0; bits < (1 << varying_flags_length); bits++) {
i::EnumSet<ParserFlag> flags; i::EnumSet<ParserFlag> flags;
for (size_t flag_index = 0; flag_index < varying_flags_length; for (size_t flag_index = 0; flag_index < varying_flags_length;
...@@ -3899,15 +3902,42 @@ TEST(BothModesUseCount) { ...@@ -3899,15 +3902,42 @@ TEST(BothModesUseCount) {
TEST(LineOrParagraphSeparatorAsLineTerminator) { TEST(LineOrParagraphSeparatorAsLineTerminator) {
// Tests that both preparsing and parsing accept U+2028 LINE SEPARATOR and // Tests that both preparsing and parsing accept U+2028 LINE SEPARATOR and
// U+2029 PARAGRAPH SEPARATOR as LineTerminator symbols. // U+2029 PARAGRAPH SEPARATOR as LineTerminator symbols outside of string
// literals.
const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}}; const char* context_data[][2] = {{"", ""}, {nullptr, nullptr}};
const char* statement_data[] = {"\x31\xE2\x80\xA8\x32", // "1<U+2028>2" const char* statement_data[] = {"\x31\xE2\x80\xA8\x32", // 1<U+2028>2
"\x31\xE2\x80\xA9\x32", // "1<U+2029>2" "\x31\xE2\x80\xA9\x32", // 1<U+2029>2
nullptr};
RunParserSyncTest(context_data, statement_data, kSuccess);
}
TEST(LineOrParagraphSeparatorInStringLiteral) {
// Tests that both preparsing and parsing treat U+2028 LINE SEPARATOR and
// U+2029 PARAGRAPH SEPARATOR as line terminators within string literals.
const char* context_data[][2] = {
{"\"", "\""}, {"'", "'"}, {nullptr, nullptr}};
const char* statement_data[] = {"\x31\xE2\x80\xA8\x32", // 1<U+2028>2
"\x31\xE2\x80\xA9\x32", // 1<U+2029>2
nullptr}; nullptr};
RunParserSyncTest(context_data, statement_data, kError); RunParserSyncTest(context_data, statement_data, kError);
} }
TEST(LineOrParagraphSeparatorInStringLiteralHarmony) {
// Tests that both preparsing and parsing don't treat U+2028 LINE SEPARATOR
// and U+2029 PARAGRAPH SEPARATOR as line terminators within string literals
// with the "subsume JSON" flag enabled.
v8::internal::FLAG_harmony_subsume_json = true;
const char* context_data[][2] = {
{"\"", "\""}, {"'", "'"}, {nullptr, nullptr}};
const char* statement_data[] = {"\x31\xE2\x80\xA8\x32", // 1<U+2028>2
"\x31\xE2\x80\xA9\x32", // 1<U+2029>2
nullptr};
RunParserSyncTest(context_data, statement_data, kSuccess);
}
TEST(ErrorsArrowFormalParameters) { TEST(ErrorsArrowFormalParameters) {
const char* context_data[][2] = { const char* context_data[][2] = {
{ "()", "=>{}" }, { "()", "=>{}" },
......
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