| 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 | 
|---|