Line data Source code
1 : // Copyright 2016 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/v8.h"
6 :
7 : #include "test/cctest/cctest.h"
8 :
9 : namespace v8 {
10 : namespace internal {
11 : namespace test_usecounters {
12 :
13 : int* global_use_counts = nullptr;
14 :
15 168 : void MockUseCounterCallback(v8::Isolate* isolate,
16 : v8::Isolate::UseCounterFeature feature) {
17 168 : ++global_use_counts[feature];
18 168 : }
19 :
20 23724 : TEST(DefineGetterSetterThrowUseCount) {
21 6 : i::FLAG_harmony_strict_legacy_accessor_builtins = false;
22 6 : v8::Isolate* isolate = CcTest::isolate();
23 6 : v8::HandleScope scope(isolate);
24 12 : LocalContext env;
25 6 : int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
26 6 : global_use_counts = use_counts;
27 6 : CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
28 :
29 : // __defineGetter__ and __defineSetter__ do not increment
30 : // kDefineGetterOrSetterWouldThrow on success
31 : CompileRun(
32 : "var a = {};"
33 : "Object.defineProperty(a, 'b', { value: 0, configurable: true });"
34 : "a.__defineGetter__('b', ()=>{});");
35 6 : CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]);
36 : CompileRun(
37 : "var a = {};"
38 : "Object.defineProperty(a, 'b', { value: 0, configurable: true });"
39 : "a.__defineSetter__('b', ()=>{});");
40 6 : CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]);
41 :
42 : // __defineGetter__ and __defineSetter__ do not increment
43 : // kDefineGetterOrSetterWouldThrow on other errors
44 : v8::Local<v8::Value> resultProxyThrow = CompileRun(
45 : "var exception;"
46 : "try {"
47 : "var a = new Proxy({}, { defineProperty: ()=>{throw new Error;} });"
48 : "a.__defineGetter__('b', ()=>{});"
49 : "} catch (e) { exception = e; }"
50 : "exception");
51 6 : CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]);
52 6 : CHECK(resultProxyThrow->IsObject());
53 : resultProxyThrow = CompileRun(
54 : "var exception;"
55 : "try {"
56 : "var a = new Proxy({}, { defineProperty: ()=>{throw new Error;} });"
57 : "a.__defineSetter__('b', ()=>{});"
58 : "} catch (e) { exception = e; }"
59 : "exception");
60 6 : CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]);
61 6 : CHECK(resultProxyThrow->IsObject());
62 :
63 : // __defineGetter__ and __defineSetter__ increment
64 : // kDefineGetterOrSetterWouldThrow when they would throw per spec (B.2.2.2)
65 : CompileRun(
66 : "var a = {};"
67 : "Object.defineProperty(a, 'b', { value: 0, configurable: false });"
68 : "a.__defineGetter__('b', ()=>{});");
69 6 : CHECK_EQ(1, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]);
70 : CompileRun(
71 : "var a = {};"
72 : "Object.defineProperty(a, 'b', { value: 0, configurable: false });"
73 : "a.__defineSetter__('b', ()=>{});");
74 12 : CHECK_EQ(2, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]);
75 6 : }
76 :
77 23724 : TEST(AssigmentExpressionLHSIsCall) {
78 6 : v8::Isolate* isolate = CcTest::isolate();
79 6 : v8::HandleScope scope(isolate);
80 12 : LocalContext env;
81 6 : int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
82 6 : global_use_counts = use_counts;
83 6 : CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
84 :
85 : // AssignmentExpressions whose LHS is not a call do not increment counters
86 : CompileRun("function f(){ a = 0; a()[b] = 0; }");
87 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
88 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
89 : CompileRun("function f(){ ++a; ++a()[b]; }");
90 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
91 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
92 : CompileRun("function f(){ 'use strict'; a = 0; a()[b] = 0; }");
93 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
94 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
95 : CompileRun("function f(){ 'use strict'; ++a; ++a()[b]; }");
96 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
97 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
98 :
99 : // AssignmentExpressions whose LHS is a call increment appropriate counters
100 : CompileRun("function f(){ a() = 0; }");
101 6 : CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
102 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
103 6 : use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0;
104 : CompileRun("function f(){ 'use strict'; a() = 0; }");
105 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
106 6 : CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
107 6 : use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0;
108 :
109 : // UpdateExpressions whose LHS is a call increment appropriate counters
110 : CompileRun("function f(){ ++a(); }");
111 6 : CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
112 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
113 6 : use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy] = 0;
114 : CompileRun("function f(){ 'use strict'; ++a(); }");
115 6 : CHECK_EQ(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInSloppy]);
116 6 : CHECK_NE(0, use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict]);
117 12 : use_counts[v8::Isolate::kAssigmentExpressionLHSIsCallInStrict] = 0;
118 6 : }
119 :
120 23724 : TEST(LabeledExpressionStatement) {
121 6 : v8::Isolate* isolate = CcTest::isolate();
122 6 : v8::HandleScope scope(isolate);
123 12 : LocalContext env;
124 6 : int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
125 6 : global_use_counts = use_counts;
126 6 : CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
127 :
128 : CompileRun("typeof a");
129 6 : CHECK_EQ(0, use_counts[v8::Isolate::kLabeledExpressionStatement]);
130 :
131 : CompileRun("foo: null");
132 6 : CHECK_EQ(1, use_counts[v8::Isolate::kLabeledExpressionStatement]);
133 :
134 : CompileRun("foo: bar: baz: undefined");
135 6 : CHECK_EQ(2, use_counts[v8::Isolate::kLabeledExpressionStatement]);
136 :
137 : CompileRun(
138 : "foo: if (false);"
139 : "bar: { }"
140 : "baz: switch (false) { }"
141 : "bat: do { } while (false);");
142 12 : CHECK_EQ(2, use_counts[v8::Isolate::kLabeledExpressionStatement]);
143 6 : }
144 :
145 : } // namespace test_usecounters
146 : } // namespace internal
147 71154 : } // namespace v8
|