| OLD | NEW |
| 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 void Check(const char* source, | 63 void Check(const char* source, |
| 64 int get, int set, int has, | 64 int get, int set, int has, |
| 65 Expectations expectations, | 65 Expectations expectations, |
| 66 v8::Handle<Value> value = Local<Value>()); | 66 v8::Handle<Value> value = Local<Value>()); |
| 67 | 67 |
| 68 int get_count() const { return get_count_; } | 68 int get_count() const { return get_count_; } |
| 69 int set_count() const { return set_count_; } | 69 int set_count() const { return set_count_; } |
| 70 int query_count() const { return query_count_; } | 70 int query_count() const { return query_count_; } |
| 71 | 71 |
| 72 protected: | 72 protected: |
| 73 virtual v8::Handle<Value> Get(Local<String> key); | 73 virtual v8::Handle<Value> Get(Local<Name> key); |
| 74 virtual v8::Handle<Value> Set(Local<String> key, Local<Value> value); | 74 virtual v8::Handle<Value> Set(Local<Name> key, Local<Value> value); |
| 75 virtual v8::Handle<Integer> Query(Local<String> key); | 75 virtual v8::Handle<Integer> Query(Local<Name> key); |
| 76 | 76 |
| 77 void InitializeIfNeeded(); | 77 void InitializeIfNeeded(); |
| 78 | 78 |
| 79 // Perform optional initialization steps on the context after it has | 79 // Perform optional initialization steps on the context after it has |
| 80 // been created. Defaults to none but may be overwritten. | 80 // been created. Defaults to none but may be overwritten. |
| 81 virtual void PostInitializeContext(Handle<Context> context) {} | 81 virtual void PostInitializeContext(Handle<Context> context) {} |
| 82 | 82 |
| 83 // Get the holder for the interceptor. Default to the instance template | 83 // Get the holder for the interceptor. Default to the instance template |
| 84 // but may be overwritten. | 84 // but may be overwritten. |
| 85 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { | 85 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
| 86 return function->InstanceTemplate(); | 86 return function->InstanceTemplate(); |
| 87 } | 87 } |
| 88 | 88 |
| 89 // The handlers are called as static functions that forward | 89 // The handlers are called as static functions that forward |
| 90 // to the instance specific virtual methods. | 90 // to the instance specific virtual methods. |
| 91 static void HandleGet(Local<String> key, | 91 static void HandleGet(Local<Name> key, |
| 92 const v8::PropertyCallbackInfo<v8::Value>& info); | 92 const v8::PropertyCallbackInfo<v8::Value>& info); |
| 93 static void HandleSet(Local<String> key, | 93 static void HandleSet(Local<Name> key, Local<Value> value, |
| 94 Local<Value> value, | |
| 95 const v8::PropertyCallbackInfo<v8::Value>& info); | 94 const v8::PropertyCallbackInfo<v8::Value>& info); |
| 96 static void HandleQuery(Local<String> key, | 95 static void HandleQuery(Local<Name> key, |
| 97 const v8::PropertyCallbackInfo<v8::Integer>& info); | 96 const v8::PropertyCallbackInfo<v8::Integer>& info); |
| 98 | 97 |
| 99 v8::Isolate* isolate() const { return CcTest::isolate(); } | 98 v8::Isolate* isolate() const { return CcTest::isolate(); } |
| 100 | 99 |
| 101 private: | 100 private: |
| 102 bool is_initialized_; | 101 bool is_initialized_; |
| 103 Persistent<Context> context_; | 102 Persistent<Context> context_; |
| 104 | 103 |
| 105 int get_count_; | 104 int get_count_; |
| 106 int set_count_; | 105 int set_count_; |
| 107 int query_count_; | 106 int query_count_; |
| 108 | 107 |
| 109 static DeclarationContext* GetInstance(Local<Value> data); | 108 static DeclarationContext* GetInstance(Local<Value> data); |
| 110 }; | 109 }; |
| 111 | 110 |
| 112 | 111 |
| 113 DeclarationContext::DeclarationContext() | 112 DeclarationContext::DeclarationContext() |
| 114 : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) { | 113 : is_initialized_(false), get_count_(0), set_count_(0), query_count_(0) { |
| 115 // Do nothing. | 114 // Do nothing. |
| 116 } | 115 } |
| 117 | 116 |
| 118 | 117 |
| 119 void DeclarationContext::InitializeIfNeeded() { | 118 void DeclarationContext::InitializeIfNeeded() { |
| 120 if (is_initialized_) return; | 119 if (is_initialized_) return; |
| 121 Isolate* isolate = CcTest::isolate(); | 120 Isolate* isolate = CcTest::isolate(); |
| 122 HandleScope scope(isolate); | 121 HandleScope scope(isolate); |
| 123 Local<FunctionTemplate> function = FunctionTemplate::New(isolate); | 122 Local<FunctionTemplate> function = FunctionTemplate::New(isolate); |
| 124 Local<Value> data = External::New(CcTest::isolate(), this); | 123 Local<Value> data = External::New(CcTest::isolate(), this); |
| 125 GetHolder(function)->SetNamedPropertyHandler(&HandleGet, | 124 GetHolder(function)->SetHandler(v8::NamedPropertyHandlerConfiguration( |
| 126 &HandleSet, | 125 &HandleGet, &HandleSet, &HandleQuery, 0, 0, data)); |
| 127 &HandleQuery, | |
| 128 0, 0, | |
| 129 data); | |
| 130 Local<Context> context = Context::New(isolate, | 126 Local<Context> context = Context::New(isolate, |
| 131 0, | 127 0, |
| 132 function->InstanceTemplate(), | 128 function->InstanceTemplate(), |
| 133 Local<Value>()); | 129 Local<Value>()); |
| 134 context_.Reset(isolate, context); | 130 context_.Reset(isolate, context); |
| 135 context->Enter(); | 131 context->Enter(); |
| 136 is_initialized_ = true; | 132 is_initialized_ = true; |
| 137 PostInitializeContext(context); | 133 PostInitializeContext(context); |
| 138 } | 134 } |
| 139 | 135 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 if (!value.IsEmpty()) { | 167 if (!value.IsEmpty()) { |
| 172 CHECK_EQ(value, catcher.Exception()); | 168 CHECK_EQ(value, catcher.Exception()); |
| 173 } | 169 } |
| 174 } | 170 } |
| 175 // Clean slate for the next test. | 171 // Clean slate for the next test. |
| 176 CcTest::heap()->CollectAllAvailableGarbage(); | 172 CcTest::heap()->CollectAllAvailableGarbage(); |
| 177 } | 173 } |
| 178 | 174 |
| 179 | 175 |
| 180 void DeclarationContext::HandleGet( | 176 void DeclarationContext::HandleGet( |
| 181 Local<String> key, | 177 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 182 const v8::PropertyCallbackInfo<v8::Value>& info) { | |
| 183 DeclarationContext* context = GetInstance(info.Data()); | 178 DeclarationContext* context = GetInstance(info.Data()); |
| 184 context->get_count_++; | 179 context->get_count_++; |
| 185 info.GetReturnValue().Set(context->Get(key)); | 180 info.GetReturnValue().Set(context->Get(key)); |
| 186 } | 181 } |
| 187 | 182 |
| 188 | 183 |
| 189 void DeclarationContext::HandleSet( | 184 void DeclarationContext::HandleSet( |
| 190 Local<String> key, | 185 Local<Name> key, Local<Value> value, |
| 191 Local<Value> value, | |
| 192 const v8::PropertyCallbackInfo<v8::Value>& info) { | 186 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 193 DeclarationContext* context = GetInstance(info.Data()); | 187 DeclarationContext* context = GetInstance(info.Data()); |
| 194 context->set_count_++; | 188 context->set_count_++; |
| 195 info.GetReturnValue().Set(context->Set(key, value)); | 189 info.GetReturnValue().Set(context->Set(key, value)); |
| 196 } | 190 } |
| 197 | 191 |
| 198 | 192 |
| 199 void DeclarationContext::HandleQuery( | 193 void DeclarationContext::HandleQuery( |
| 200 Local<String> key, | 194 Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) { |
| 201 const v8::PropertyCallbackInfo<v8::Integer>& info) { | |
| 202 DeclarationContext* context = GetInstance(info.Data()); | 195 DeclarationContext* context = GetInstance(info.Data()); |
| 203 context->query_count_++; | 196 context->query_count_++; |
| 204 info.GetReturnValue().Set(context->Query(key)); | 197 info.GetReturnValue().Set(context->Query(key)); |
| 205 } | 198 } |
| 206 | 199 |
| 207 | 200 |
| 208 DeclarationContext* DeclarationContext::GetInstance(Local<Value> data) { | 201 DeclarationContext* DeclarationContext::GetInstance(Local<Value> data) { |
| 209 void* value = Local<External>::Cast(data)->Value(); | 202 void* value = Local<External>::Cast(data)->Value(); |
| 210 return static_cast<DeclarationContext*>(value); | 203 return static_cast<DeclarationContext*>(value); |
| 211 } | 204 } |
| 212 | 205 |
| 213 | 206 |
| 214 v8::Handle<Value> DeclarationContext::Get(Local<String> key) { | 207 v8::Handle<Value> DeclarationContext::Get(Local<Name> key) { |
| 215 return v8::Handle<Value>(); | 208 return v8::Handle<Value>(); |
| 216 } | 209 } |
| 217 | 210 |
| 218 | 211 |
| 219 v8::Handle<Value> DeclarationContext::Set(Local<String> key, | 212 v8::Handle<Value> DeclarationContext::Set(Local<Name> key, Local<Value> value) { |
| 220 Local<Value> value) { | |
| 221 return v8::Handle<Value>(); | 213 return v8::Handle<Value>(); |
| 222 } | 214 } |
| 223 | 215 |
| 224 | 216 |
| 225 v8::Handle<Integer> DeclarationContext::Query(Local<String> key) { | 217 v8::Handle<Integer> DeclarationContext::Query(Local<Name> key) { |
| 226 return v8::Handle<Integer>(); | 218 return v8::Handle<Integer>(); |
| 227 } | 219 } |
| 228 | 220 |
| 229 | 221 |
| 230 // Test global declaration of a property the interceptor doesn't know | 222 // Test global declaration of a property the interceptor doesn't know |
| 231 // about and doesn't handle. | 223 // about and doesn't handle. |
| 232 TEST(Unknown) { | 224 TEST(Unknown) { |
| 233 HandleScope scope(CcTest::isolate()); | 225 HandleScope scope(CcTest::isolate()); |
| 234 v8::V8::Initialize(); | 226 v8::V8::Initialize(); |
| 235 | 227 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 265 1, // access | 257 1, // access |
| 266 0, | 258 0, |
| 267 0, | 259 0, |
| 268 EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); | 260 EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); |
| 269 } | 261 } |
| 270 } | 262 } |
| 271 | 263 |
| 272 | 264 |
| 273 class AbsentPropertyContext: public DeclarationContext { | 265 class AbsentPropertyContext: public DeclarationContext { |
| 274 protected: | 266 protected: |
| 275 virtual v8::Handle<Integer> Query(Local<String> key) { | 267 virtual v8::Handle<Integer> Query(Local<Name> key) { |
| 276 return v8::Handle<Integer>(); | 268 return v8::Handle<Integer>(); |
| 277 } | 269 } |
| 278 }; | 270 }; |
| 279 | 271 |
| 280 | 272 |
| 281 TEST(Absent) { | 273 TEST(Absent) { |
| 282 v8::Isolate* isolate = CcTest::isolate(); | 274 v8::Isolate* isolate = CcTest::isolate(); |
| 283 v8::V8::Initialize(); | 275 v8::V8::Initialize(); |
| 284 HandleScope scope(isolate); | 276 HandleScope scope(isolate); |
| 285 | 277 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 public: | 321 public: |
| 330 enum State { | 322 enum State { |
| 331 DECLARE, | 323 DECLARE, |
| 332 INITIALIZE_IF_ASSIGN, | 324 INITIALIZE_IF_ASSIGN, |
| 333 UNKNOWN | 325 UNKNOWN |
| 334 }; | 326 }; |
| 335 | 327 |
| 336 AppearingPropertyContext() : state_(DECLARE) { } | 328 AppearingPropertyContext() : state_(DECLARE) { } |
| 337 | 329 |
| 338 protected: | 330 protected: |
| 339 virtual v8::Handle<Integer> Query(Local<String> key) { | 331 virtual v8::Handle<Integer> Query(Local<Name> key) { |
| 340 switch (state_) { | 332 switch (state_) { |
| 341 case DECLARE: | 333 case DECLARE: |
| 342 // Force declaration by returning that the | 334 // Force declaration by returning that the |
| 343 // property is absent. | 335 // property is absent. |
| 344 state_ = INITIALIZE_IF_ASSIGN; | 336 state_ = INITIALIZE_IF_ASSIGN; |
| 345 return Handle<Integer>(); | 337 return Handle<Integer>(); |
| 346 case INITIALIZE_IF_ASSIGN: | 338 case INITIALIZE_IF_ASSIGN: |
| 347 // Return that the property is present so we only get the | 339 // Return that the property is present so we only get the |
| 348 // setter called when initializing with a value. | 340 // setter called when initializing with a value. |
| 349 state_ = UNKNOWN; | 341 state_ = UNKNOWN; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 398 0, 0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); | 390 0, 0, EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); |
| 399 } | 391 } |
| 400 } | 392 } |
| 401 | 393 |
| 402 | 394 |
| 403 | 395 |
| 404 class ExistsInPrototypeContext: public DeclarationContext { | 396 class ExistsInPrototypeContext: public DeclarationContext { |
| 405 public: | 397 public: |
| 406 ExistsInPrototypeContext() { InitializeIfNeeded(); } | 398 ExistsInPrototypeContext() { InitializeIfNeeded(); } |
| 407 protected: | 399 protected: |
| 408 virtual v8::Handle<Integer> Query(Local<String> key) { | 400 virtual v8::Handle<Integer> Query(Local<Name> key) { |
| 409 // Let it seem that the property exists in the prototype object. | 401 // Let it seem that the property exists in the prototype object. |
| 410 return Integer::New(isolate(), v8::None); | 402 return Integer::New(isolate(), v8::None); |
| 411 } | 403 } |
| 412 | 404 |
| 413 // Use the prototype as the holder for the interceptors. | 405 // Use the prototype as the holder for the interceptors. |
| 414 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { | 406 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
| 415 return function->PrototypeTemplate(); | 407 return function->PrototypeTemplate(); |
| 416 } | 408 } |
| 417 }; | 409 }; |
| 418 | 410 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 0, | 449 0, |
| 458 0, | 450 0, |
| 459 EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); | 451 EXPECT_RESULT, Number::New(CcTest::isolate(), 0)); |
| 460 } | 452 } |
| 461 } | 453 } |
| 462 | 454 |
| 463 | 455 |
| 464 | 456 |
| 465 class AbsentInPrototypeContext: public DeclarationContext { | 457 class AbsentInPrototypeContext: public DeclarationContext { |
| 466 protected: | 458 protected: |
| 467 virtual v8::Handle<Integer> Query(Local<String> key) { | 459 virtual v8::Handle<Integer> Query(Local<Name> key) { |
| 468 // Let it seem that the property is absent in the prototype object. | 460 // Let it seem that the property is absent in the prototype object. |
| 469 return Handle<Integer>(); | 461 return Handle<Integer>(); |
| 470 } | 462 } |
| 471 | 463 |
| 472 // Use the prototype as the holder for the interceptors. | 464 // Use the prototype as the holder for the interceptors. |
| 473 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { | 465 virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { |
| 474 return function->PrototypeTemplate(); | 466 return function->PrototypeTemplate(); |
| 475 } | 467 } |
| 476 }; | 468 }; |
| 477 | 469 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 492 | 484 |
| 493 | 485 |
| 494 class ExistsInHiddenPrototypeContext: public DeclarationContext { | 486 class ExistsInHiddenPrototypeContext: public DeclarationContext { |
| 495 public: | 487 public: |
| 496 ExistsInHiddenPrototypeContext() { | 488 ExistsInHiddenPrototypeContext() { |
| 497 hidden_proto_ = FunctionTemplate::New(CcTest::isolate()); | 489 hidden_proto_ = FunctionTemplate::New(CcTest::isolate()); |
| 498 hidden_proto_->SetHiddenPrototype(true); | 490 hidden_proto_->SetHiddenPrototype(true); |
| 499 } | 491 } |
| 500 | 492 |
| 501 protected: | 493 protected: |
| 502 virtual v8::Handle<Integer> Query(Local<String> key) { | 494 virtual v8::Handle<Integer> Query(Local<Name> key) { |
| 503 // Let it seem that the property exists in the hidden prototype object. | 495 // Let it seem that the property exists in the hidden prototype object. |
| 504 return Integer::New(isolate(), v8::None); | 496 return Integer::New(isolate(), v8::None); |
| 505 } | 497 } |
| 506 | 498 |
| 507 // Install the hidden prototype after the global object has been created. | 499 // Install the hidden prototype after the global object has been created. |
| 508 virtual void PostInitializeContext(Handle<Context> context) { | 500 virtual void PostInitializeContext(Handle<Context> context) { |
| 509 Local<Object> global_object = context->Global(); | 501 Local<Object> global_object = context->Global(); |
| 510 Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance(); | 502 Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance(); |
| 511 Local<Object> inner_global = | 503 Local<Object> inner_global = |
| 512 Local<Object>::Cast(global_object->GetPrototype()); | 504 Local<Object>::Cast(global_object->GetPrototype()); |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 context.Check("'use strict';const x = 1; x", EXPECT_RESULT, | 1144 context.Check("'use strict';const x = 1; x", EXPECT_RESULT, |
| 1153 Number::New(CcTest::isolate(), 1)); | 1145 Number::New(CcTest::isolate(), 1)); |
| 1154 context.Check("f();", EXPECT_EXCEPTION); | 1146 context.Check("f();", EXPECT_EXCEPTION); |
| 1155 context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1)); | 1147 context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1)); |
| 1156 context.Check("f();", EXPECT_EXCEPTION); | 1148 context.Check("f();", EXPECT_EXCEPTION); |
| 1157 context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1)); | 1149 context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1)); |
| 1158 context.Check("%OptimizeFunctionOnNextCall(f);f();", EXPECT_EXCEPTION); | 1150 context.Check("%OptimizeFunctionOnNextCall(f);f();", EXPECT_EXCEPTION); |
| 1159 context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1)); | 1151 context.Check("x", EXPECT_RESULT, Number::New(CcTest::isolate(), 1)); |
| 1160 } | 1152 } |
| 1161 } | 1153 } |
| OLD | NEW |