diff --git a/AUTHORS b/AUTHORS index 0d6f6241a3..35edca97e5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -81,6 +81,7 @@ Julien Brianceau JunHo Seo Kang-Hao (Kenny) Lu Karl Skomski +Kevin Gibbons Luis Reis Luke Zarko Maciej MaƂecki diff --git a/include/v8.h b/include/v8.h index b566da4bc8..cfd04056bb 100644 --- a/include/v8.h +++ b/include/v8.h @@ -6488,6 +6488,8 @@ class V8_EXPORT Isolate { kLegacyDateParser = 33, kDefineGetterOrSetterWouldThrow = 34, kFunctionConstructorReturnedUndefined = 35, + kAssigmentExpressionLHSIsCallInSloppy = 36, + kAssigmentExpressionLHSIsCallInStrict = 37, // If you add new values here, you'll also need to update Chromium's: // UseCounter.h, V8PerIsolateData.cpp, histograms.xml diff --git a/src/parsing/parser-base.h b/src/parsing/parser-base.h index 6e407eef6d..9ce9c32309 100644 --- a/src/parsing/parser-base.h +++ b/src/parsing/parser-base.h @@ -4331,7 +4331,12 @@ ParserBase::CheckAndRewriteReferenceExpression( } if (expression->IsCall()) { // If it is a call, make it a runtime error for legacy web compatibility. + // Bug: https://bugs.chromium.org/p/v8/issues/detail?id=4480 // Rewrite `expr' to `expr[throw ReferenceError]'. + impl()->CountUsage( + is_strict(language_mode()) + ? v8::Isolate::kAssigmentExpressionLHSIsCallInStrict + : v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy); ExpressionT error = impl()->NewThrowReferenceError(message, beg_pos); return factory()->NewProperty(expression, error, beg_pos); } diff --git a/test/cctest/test-usecounters.cc b/test/cctest/test-usecounters.cc index 8d4628c9f7..3482476b76 100644 --- a/test/cctest/test-usecounters.cc +++ b/test/cctest/test-usecounters.cc @@ -71,3 +71,46 @@ TEST(DefineGetterSetterThrowUseCount) { "a.__defineSetter__('b', ()=>{});"); CHECK_EQ(2, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]); } + +TEST(AssigmentExpressionLHSIsCall) { + v8::Isolate* isolate = CcTest::isolate(); + v8::HandleScope scope(isolate); + LocalContext env; + int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; + global_use_counts = use_counts; + CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); + + // AssignmentExpressions whose LHS is not a call do not increment counters + CompileRun("function f(){ a = 0; a()[b] = 0; }"); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + CompileRun("function f(){ ++a; ++a()[b]; }"); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + CompileRun("function f(){ 'use strict'; a = 0; a()[b] = 0; }"); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + CompileRun("function f(){ 'use strict'; ++a; ++a()[b]; }"); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + + // AssignmentExpressions whose LHS is a call increment appropriate counters + CompileRun("function f(){ a() = 0; }"); + CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0; + CompileRun("function f(){ 'use strict'; a() = 0; }"); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0; + + // UpdateExpressions whose LHS is a call increment appropriate counters + CompileRun("function f(){ ++a(); }"); + CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0; + CompileRun("function f(){ 'use strict'; ++a(); }"); + CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]); + CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]); + use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0; +}