OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "test/cctest/cctest.h" | 5 #include "test/cctest/cctest.h" |
6 | 6 |
| 7 #include "include/v8-experimental.h" |
7 #include "include/v8.h" | 8 #include "include/v8.h" |
8 #include "include/v8-experimental.h" | 9 #include "src/api.h" |
9 | |
10 | 10 |
11 namespace i = v8::internal; | 11 namespace i = v8::internal; |
12 | 12 |
13 static void CppAccessor42(const v8::FunctionCallbackInfo<v8::Value>& info) { | 13 static void CppAccessor42(const v8::FunctionCallbackInfo<v8::Value>& info) { |
14 info.GetReturnValue().Set(42); | 14 info.GetReturnValue().Set(42); |
15 } | 15 } |
16 | 16 |
17 | 17 |
18 static void CppAccessor41(const v8::FunctionCallbackInfo<v8::Value>& info) { | 18 static void CppAccessor41(const v8::FunctionCallbackInfo<v8::Value>& info) { |
19 info.GetReturnValue().Set(41); | 19 info.GetReturnValue().Set(41); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 "var g = Object.getOwnPropertyDescriptor(" | 104 "var g = Object.getOwnPropertyDescriptor(" |
105 " n.__proto__.__proto__, 'firstChildRaw')['get'];" | 105 " n.__proto__.__proto__, 'firstChildRaw')['get'];" |
106 "try {" | 106 "try {" |
107 " var f = { firstChildRaw: '51' };" | 107 " var f = { firstChildRaw: '51' };" |
108 " g.apply(f);" | 108 " g.apply(f);" |
109 "} catch(e) {" | 109 "} catch(e) {" |
110 " 31415;" | 110 " 31415;" |
111 "}", | 111 "}", |
112 31415); | 112 31415); |
113 } | 113 } |
| 114 |
| 115 // The goal is to avoid the callback. |
| 116 static void UnreachableCallback( |
| 117 const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 118 UNREACHABLE(); |
| 119 } |
| 120 |
| 121 TEST(CachedAccessor) { |
| 122 // Crankshaft support for fast accessors is not implemented; crankshafted |
| 123 // code uses the slow accessor which breaks this test's expectations. |
| 124 v8::internal::FLAG_always_opt = false; |
| 125 LocalContext env; |
| 126 v8::Isolate* isolate = env->GetIsolate(); |
| 127 v8::HandleScope scope(isolate); |
| 128 |
| 129 // Create 'foo' class, with a hidden property. |
| 130 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); |
| 131 |
| 132 v8::Local<v8::Private> priv = |
| 133 v8::Private::ForApi(isolate, v8_str("Foo#draft")); |
| 134 |
| 135 foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache( |
| 136 isolate, UnreachableCallback, |
| 137 priv, v8::Local<v8::Value>())); |
| 138 |
| 139 // Create 'obj', instance of 'foo'. |
| 140 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); |
| 141 |
| 142 // Install the private property on the instance. |
| 143 CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv, |
| 144 v8::Undefined(isolate)) |
| 145 .FromJust()); |
| 146 |
| 147 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); |
| 148 |
| 149 // Access cached accessor. |
| 150 ExpectUndefined("obj.draft"); |
| 151 |
| 152 // Set hidden property. |
| 153 CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv, |
| 154 v8_str("Shhh, I'm private!")) |
| 155 .FromJust()); |
| 156 |
| 157 ExpectString("obj.draft", "Shhh, I'm private!"); |
| 158 |
| 159 // Stress the accessor to use the IC. |
| 160 ExpectString( |
| 161 "var result = '';" |
| 162 "for (var i = 0; i < 10; ++i) { " |
| 163 " result = obj.draft; " |
| 164 "} " |
| 165 "result; ", |
| 166 "Shhh, I'm private!"); |
| 167 } |
| 168 |
| 169 TEST(CachedAccessorCrankshaft) { |
| 170 i::FLAG_allow_natives_syntax = true; |
| 171 // v8::internal::FLAG_always_opt = false; |
| 172 LocalContext env; |
| 173 v8::Isolate* isolate = env->GetIsolate(); |
| 174 v8::HandleScope scope(isolate); |
| 175 |
| 176 // Create 'foo' class, with a hidden property. |
| 177 v8::Local<v8::ObjectTemplate> foo = v8::ObjectTemplate::New(isolate); |
| 178 v8::Local<v8::Private> priv = |
| 179 v8::Private::ForApi(isolate, v8_str("Foo#draft")); |
| 180 |
| 181 // Install the private property on the template. |
| 182 // foo->SetPrivate(priv, v8::Undefined(isolate)); |
| 183 |
| 184 foo->SetAccessorProperty(v8_str("draft"), v8::FunctionTemplate::NewWithCache( |
| 185 isolate, UnreachableCallback, |
| 186 priv, v8::Local<v8::Value>())); |
| 187 |
| 188 // Create 'obj', instance of 'foo'. |
| 189 v8::Local<v8::Object> obj = foo->NewInstance(env.local()).ToLocalChecked(); |
| 190 |
| 191 // Install the private property on the instance. |
| 192 CHECK(obj->SetPrivate(isolate->GetCurrentContext(), priv, |
| 193 v8::Undefined(isolate)) |
| 194 .FromJust()); |
| 195 |
| 196 CHECK(env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust()); |
| 197 |
| 198 // Access surrogate accessor. |
| 199 ExpectUndefined("obj.draft"); |
| 200 |
| 201 // Set hidden property. |
| 202 CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 123)) |
| 203 .FromJust()); |
| 204 |
| 205 // Test ICs. |
| 206 CompileRun( |
| 207 "function f() {" |
| 208 " var x;" |
| 209 " for (var i = 0; i < 100; i++) {" |
| 210 " x = obj.draft;" |
| 211 " }" |
| 212 " return x;" |
| 213 "}"); |
| 214 |
| 215 ExpectInt32("f()", 123); |
| 216 |
| 217 // Reset hidden property. |
| 218 CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456)) |
| 219 .FromJust()); |
| 220 |
| 221 // Test Crankshaft. |
| 222 CompileRun("%OptimizeFunctionOnNextCall(f);"); |
| 223 |
| 224 ExpectInt32("f()", 456); |
| 225 |
| 226 CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 456)) |
| 227 .FromJust()); |
| 228 // Test non-global ICs. |
| 229 CompileRun( |
| 230 "function g() {" |
| 231 " var x = obj;" |
| 232 " var r = 0;" |
| 233 " for (var i = 0; i < 100; i++) {" |
| 234 " r = x.draft;" |
| 235 " }" |
| 236 " return r;" |
| 237 "}"); |
| 238 |
| 239 ExpectInt32("g()", 456); |
| 240 |
| 241 // Reset hidden property. |
| 242 CHECK(obj->SetPrivate(env.local(), priv, v8::Integer::New(isolate, 789)) |
| 243 .FromJust()); |
| 244 |
| 245 // Test non-global access in Crankshaft. |
| 246 CompileRun("%OptimizeFunctionOnNextCall(g);"); |
| 247 |
| 248 ExpectInt32("g()", 789); |
| 249 } |
OLD | NEW |