Revision f230a1cf deps/v8/test/cctest/test-object-observe.cc
deps/v8/test/cctest/test-object-observe.cc | ||
---|---|---|
58 | 58 |
TEST(PerIsolateState) { |
59 | 59 |
HarmonyIsolate isolate; |
60 | 60 |
HandleScope scope(isolate.GetIsolate()); |
61 |
LocalContext context1; |
|
61 |
LocalContext context1(isolate.GetIsolate());
|
|
62 | 62 |
CompileRun( |
63 | 63 |
"var count = 0;" |
64 | 64 |
"var calls = 0;" |
... | ... | |
71 | 71 |
"(function() { obj.foo = 'bar'; })"); |
72 | 72 |
Handle<Value> notify_fun2; |
73 | 73 |
{ |
74 |
LocalContext context2; |
|
74 |
LocalContext context2(isolate.GetIsolate());
|
|
75 | 75 |
context2->Global()->Set(String::New("obj"), obj); |
76 | 76 |
notify_fun2 = CompileRun( |
77 | 77 |
"(function() { obj.foo = 'baz'; })"); |
78 | 78 |
} |
79 | 79 |
Handle<Value> notify_fun3; |
80 | 80 |
{ |
81 |
LocalContext context3; |
|
81 |
LocalContext context3(isolate.GetIsolate());
|
|
82 | 82 |
context3->Global()->Set(String::New("obj"), obj); |
83 | 83 |
notify_fun3 = CompileRun( |
84 | 84 |
"(function() { obj.foo = 'bat'; })"); |
85 | 85 |
} |
86 | 86 |
{ |
87 |
LocalContext context4; |
|
87 |
LocalContext context4(isolate.GetIsolate());
|
|
88 | 88 |
context4->Global()->Set(String::New("observer"), observer); |
89 | 89 |
context4->Global()->Set(String::New("fun1"), notify_fun1); |
90 | 90 |
context4->Global()->Set(String::New("fun2"), notify_fun2); |
... | ... | |
99 | 99 |
TEST(EndOfMicrotaskDelivery) { |
100 | 100 |
HarmonyIsolate isolate; |
101 | 101 |
HandleScope scope(isolate.GetIsolate()); |
102 |
LocalContext context; |
|
102 |
LocalContext context(isolate.GetIsolate());
|
|
103 | 103 |
CompileRun( |
104 | 104 |
"var obj = {};" |
105 | 105 |
"var count = 0;" |
... | ... | |
113 | 113 |
TEST(DeliveryOrdering) { |
114 | 114 |
HarmonyIsolate isolate; |
115 | 115 |
HandleScope scope(isolate.GetIsolate()); |
116 |
LocalContext context; |
|
116 |
LocalContext context(isolate.GetIsolate());
|
|
117 | 117 |
CompileRun( |
118 | 118 |
"var obj1 = {};" |
119 | 119 |
"var obj2 = {};" |
... | ... | |
145 | 145 |
TEST(DeliveryOrderingReentrant) { |
146 | 146 |
HarmonyIsolate isolate; |
147 | 147 |
HandleScope scope(isolate.GetIsolate()); |
148 |
LocalContext context; |
|
148 |
LocalContext context(isolate.GetIsolate());
|
|
149 | 149 |
CompileRun( |
150 | 150 |
"var obj = {};" |
151 | 151 |
"var reentered = false;" |
... | ... | |
177 | 177 |
TEST(DeliveryOrderingDeliverChangeRecords) { |
178 | 178 |
HarmonyIsolate isolate; |
179 | 179 |
HandleScope scope(isolate.GetIsolate()); |
180 |
LocalContext context; |
|
180 |
LocalContext context(isolate.GetIsolate());
|
|
181 | 181 |
CompileRun( |
182 | 182 |
"var obj = {};" |
183 | 183 |
"var ordering = [];" |
... | ... | |
203 | 203 |
HarmonyIsolate isolate; |
204 | 204 |
HandleScope scope(isolate.GetIsolate()); |
205 | 205 |
// Initializing this context sets up initial hash tables. |
206 |
LocalContext context; |
|
206 |
LocalContext context(isolate.GetIsolate());
|
|
207 | 207 |
Handle<Value> obj = CompileRun("obj = {};"); |
208 | 208 |
Handle<Value> observer = CompileRun( |
209 | 209 |
"var ran = false;" |
210 | 210 |
"(function() { ran = true })"); |
211 | 211 |
{ |
212 | 212 |
// As does initializing this context. |
213 |
LocalContext context2; |
|
213 |
LocalContext context2(isolate.GetIsolate());
|
|
214 | 214 |
context2->Global()->Set(String::New("obj"), obj); |
215 | 215 |
context2->Global()->Set(String::New("observer"), observer); |
216 | 216 |
CompileRun( |
... | ... | |
231 | 231 |
|
232 | 232 |
TEST(GlobalObjectObservation) { |
233 | 233 |
HarmonyIsolate isolate; |
234 |
LocalContext context; |
|
234 |
LocalContext context(isolate.GetIsolate());
|
|
235 | 235 |
HandleScope scope(isolate.GetIsolate()); |
236 | 236 |
Handle<Object> global_proxy = context->Global(); |
237 | 237 |
Handle<Object> inner_global = global_proxy->GetPrototype().As<Object>(); |
... | ... | |
263 | 263 |
// to the old context. |
264 | 264 |
context->DetachGlobal(); |
265 | 265 |
{ |
266 |
LocalContext context2; |
|
266 |
LocalContext context2(isolate.GetIsolate());
|
|
267 | 267 |
context2->DetachGlobal(); |
268 | 268 |
context2->ReattachGlobal(global_proxy); |
269 | 269 |
CompileRun( |
... | ... | |
278 | 278 |
// Attaching by passing to Context::New |
279 | 279 |
{ |
280 | 280 |
// Delegates to Context::New |
281 |
LocalContext context3(NULL, Handle<ObjectTemplate>(), global_proxy); |
|
281 |
LocalContext context3( |
|
282 |
isolate.GetIsolate(), NULL, Handle<ObjectTemplate>(), global_proxy); |
|
282 | 283 |
CompileRun( |
283 | 284 |
"var records3 = [];" |
284 | 285 |
"Object.observe(this, function(r) { [].push.apply(records3, r) });" |
... | ... | |
330 | 331 |
TEST(APITestBasicMutation) { |
331 | 332 |
HarmonyIsolate isolate; |
332 | 333 |
HandleScope scope(isolate.GetIsolate()); |
333 |
LocalContext context; |
|
334 |
LocalContext context(isolate.GetIsolate());
|
|
334 | 335 |
Handle<Object> obj = Handle<Object>::Cast(CompileRun( |
335 | 336 |
"var records = [];" |
336 | 337 |
"var obj = {};" |
... | ... | |
374 | 375 |
TEST(HiddenPrototypeObservation) { |
375 | 376 |
HarmonyIsolate isolate; |
376 | 377 |
HandleScope scope(isolate.GetIsolate()); |
377 |
LocalContext context; |
|
378 |
LocalContext context(isolate.GetIsolate());
|
|
378 | 379 |
Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); |
379 | 380 |
tmpl->SetHiddenPrototype(true); |
380 | 381 |
tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); |
... | ... | |
393 | 394 |
{ obj, "updated", "foo", Number::New(75) } |
394 | 395 |
}; |
395 | 396 |
EXPECT_RECORDS(CompileRun("records"), expected_records); |
396 |
obj->SetPrototype(Null()); |
|
397 |
obj->SetPrototype(Null(isolate.GetIsolate()));
|
|
397 | 398 |
CompileRun("obj.foo = 43"); |
398 | 399 |
const RecordExpectation expected_records2[] = { |
399 | 400 |
{ obj, "new", "foo", Handle<Value>() } |
... | ... | |
423 | 424 |
TEST(ObservationWeakMap) { |
424 | 425 |
HarmonyIsolate isolate; |
425 | 426 |
HandleScope scope(isolate.GetIsolate()); |
426 |
LocalContext context; |
|
427 |
LocalContext context(isolate.GetIsolate());
|
|
427 | 428 |
CompileRun( |
428 | 429 |
"var obj = {};" |
429 | 430 |
"Object.observe(obj, function(){});" |
430 | 431 |
"Object.getNotifier(obj);" |
431 | 432 |
"obj = null;"); |
433 |
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate.GetIsolate()); |
|
432 | 434 |
i::Handle<i::JSObject> observation_state = |
433 |
i::Isolate::Current()->factory()->observation_state();
|
|
435 |
i_isolate->factory()->observation_state();
|
|
434 | 436 |
i::Handle<i::JSWeakMap> callbackInfoMap = |
435 | 437 |
i::Handle<i::JSWeakMap>::cast( |
436 | 438 |
i::GetProperty(observation_state, "callbackInfoMap")); |
... | ... | |
443 | 445 |
CHECK_EQ(1, NumberOfElements(callbackInfoMap)); |
444 | 446 |
CHECK_EQ(1, NumberOfElements(objectInfoMap)); |
445 | 447 |
CHECK_EQ(1, NumberOfElements(notifierObjectInfoMap)); |
446 |
HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
|
|
448 |
i_isolate->heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
|
|
447 | 449 |
CHECK_EQ(0, NumberOfElements(callbackInfoMap)); |
448 | 450 |
CHECK_EQ(0, NumberOfElements(objectInfoMap)); |
449 | 451 |
CHECK_EQ(0, NumberOfElements(notifierObjectInfoMap)); |
... | ... | |
463 | 465 |
|
464 | 466 |
|
465 | 467 |
static AccessType g_access_block_type = ACCESS_GET; |
468 |
static const uint32_t kBlockedContextIndex = 1337; |
|
466 | 469 |
|
467 | 470 |
|
468 | 471 |
static bool NamedAccessAllowUnlessBlocked(Local<Object> host, |
469 |
Local<Value> key,
|
|
470 |
AccessType type,
|
|
471 |
Local<Value>) {
|
|
472 |
Local<Value> key, |
|
473 |
AccessType type, |
|
474 |
Local<Value> data) {
|
|
472 | 475 |
if (type != g_access_block_type) return true; |
473 |
Handle<Object> global = Context::GetCurrent()->Global();
|
|
474 |
Handle<Value> blacklist = global->Get(String::New("blacklist"));
|
|
475 |
if (!blacklist->IsObject()) return true;
|
|
476 |
if (key->IsString()) return !blacklist.As<Object>()->Has(key);
|
|
477 |
return true;
|
|
476 |
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(
|
|
477 |
Utils::OpenHandle(*host)->GetIsolate());
|
|
478 |
Handle<Object> global = isolate->GetCurrentContext()->Global();
|
|
479 |
if (!global->Has(kBlockedContextIndex)) return true;
|
|
480 |
return !key->IsString() || !key->Equals(data);
|
|
478 | 481 |
} |
479 | 482 |
|
480 | 483 |
|
481 | 484 |
static bool IndexedAccessAllowUnlessBlocked(Local<Object> host, |
482 |
uint32_t index, |
|
483 |
AccessType type, |
|
484 |
Local<Value>) { |
|
485 |
if (type != ACCESS_GET) return true; |
|
486 |
Handle<Object> global = Context::GetCurrent()->Global(); |
|
487 |
Handle<Value> blacklist = global->Get(String::New("blacklist")); |
|
488 |
if (!blacklist->IsObject()) return true; |
|
489 |
return !blacklist.As<Object>()->Has(index); |
|
485 |
uint32_t index, |
|
486 |
AccessType type, |
|
487 |
Local<Value> data) { |
|
488 |
if (type != g_access_block_type) return true; |
|
489 |
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( |
|
490 |
Utils::OpenHandle(*host)->GetIsolate()); |
|
491 |
Handle<Object> global = isolate->GetCurrentContext()->Global(); |
|
492 |
if (!global->Has(kBlockedContextIndex)) return true; |
|
493 |
return index != data->Uint32Value(); |
|
490 | 494 |
} |
491 | 495 |
|
492 | 496 |
|
493 | 497 |
static bool BlockAccessKeys(Local<Object> host, Local<Value> key, |
494 | 498 |
AccessType type, Local<Value>) { |
495 |
Handle<Object> global = Context::GetCurrent()->Global(); |
|
496 |
Handle<Value> blacklist = global->Get(String::New("blacklist")); |
|
497 |
if (!blacklist->IsObject()) return true; |
|
498 |
return type != ACCESS_KEYS || |
|
499 |
!blacklist.As<Object>()->Has(String::New("__block_access_keys")); |
|
499 |
v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( |
|
500 |
Utils::OpenHandle(*host)->GetIsolate()); |
|
501 |
Handle<Object> global = isolate->GetCurrentContext()->Global(); |
|
502 |
return type != ACCESS_KEYS || !global->Has(kBlockedContextIndex); |
|
500 | 503 |
} |
501 | 504 |
|
502 | 505 |
|
503 | 506 |
static Handle<Object> CreateAccessCheckedObject( |
504 | 507 |
NamedSecurityCallback namedCallback, |
505 |
IndexedSecurityCallback indexedCallback) { |
|
508 |
IndexedSecurityCallback indexedCallback, |
|
509 |
Handle<Value> data = Handle<Value>()) { |
|
506 | 510 |
Handle<ObjectTemplate> tmpl = ObjectTemplate::New(); |
507 |
tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback); |
|
511 |
tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback, data);
|
|
508 | 512 |
Handle<Object> instance = tmpl->NewInstance(); |
509 |
instance->CreationContext()->Global()->Set(String::New("obj"), instance); |
|
513 |
Handle<Object> global = instance->CreationContext()->Global(); |
|
514 |
global->Set(String::New("obj"), instance); |
|
515 |
global->Set(kBlockedContextIndex, v8::True()); |
|
510 | 516 |
return instance; |
511 | 517 |
} |
512 | 518 |
|
... | ... | |
516 | 522 |
const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
517 | 523 |
for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
518 | 524 |
HandleScope scope(isolate.GetIsolate()); |
519 |
LocalContext context; |
|
525 |
LocalContext context(isolate.GetIsolate());
|
|
520 | 526 |
g_access_block_type = types[i]; |
521 | 527 |
Handle<Object> instance = CreateAccessCheckedObject( |
522 |
NamedAccessAllowUnlessBlocked, IndexedAccessAlwaysAllowed); |
|
528 |
NamedAccessAllowUnlessBlocked, |
|
529 |
IndexedAccessAlwaysAllowed, |
|
530 |
String::New("foo")); |
|
523 | 531 |
CompileRun("var records = null;" |
524 | 532 |
"var objNoCheck = {};" |
525 |
"var blacklist = {foo: true};" |
|
526 | 533 |
"var observer = function(r) { records = r };" |
527 | 534 |
"Object.observe(obj, observer);" |
528 | 535 |
"Object.observe(objNoCheck, observer);"); |
529 | 536 |
Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
530 | 537 |
{ |
531 |
LocalContext context2; |
|
538 |
LocalContext context2(isolate.GetIsolate());
|
|
532 | 539 |
context2->Global()->Set(String::New("obj"), instance); |
533 | 540 |
context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
534 | 541 |
CompileRun("var records2 = null;" |
... | ... | |
563 | 570 |
const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
564 | 571 |
for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
565 | 572 |
HandleScope scope(isolate.GetIsolate()); |
566 |
LocalContext context; |
|
573 |
LocalContext context(isolate.GetIsolate());
|
|
567 | 574 |
g_access_block_type = types[i]; |
568 | 575 |
Handle<Object> instance = CreateAccessCheckedObject( |
569 |
NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); |
|
576 |
NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, |
|
577 |
Number::New(7)); |
|
570 | 578 |
CompileRun("var records = null;" |
571 | 579 |
"var objNoCheck = {};" |
572 |
"var blacklist = {7: true};" |
|
573 | 580 |
"var observer = function(r) { records = r };" |
574 | 581 |
"Object.observe(obj, observer);" |
575 | 582 |
"Object.observe(objNoCheck, observer);"); |
576 | 583 |
Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
577 | 584 |
{ |
578 |
LocalContext context2; |
|
585 |
LocalContext context2(isolate.GetIsolate());
|
|
579 | 586 |
context2->Global()->Set(String::New("obj"), instance); |
580 | 587 |
context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
581 | 588 |
CompileRun("var records2 = null;" |
... | ... | |
608 | 615 |
TEST(SpliceAccessCheck) { |
609 | 616 |
HarmonyIsolate isolate; |
610 | 617 |
HandleScope scope(isolate.GetIsolate()); |
611 |
LocalContext context; |
|
618 |
LocalContext context(isolate.GetIsolate());
|
|
612 | 619 |
g_access_block_type = ACCESS_GET; |
613 | 620 |
Handle<Object> instance = CreateAccessCheckedObject( |
614 |
NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); |
|
621 |
NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, |
|
622 |
Number::New(1)); |
|
615 | 623 |
CompileRun("var records = null;" |
616 | 624 |
"obj[1] = 'foo';" |
617 | 625 |
"obj.length = 2;" |
618 | 626 |
"var objNoCheck = {1: 'bar', length: 2};" |
619 |
"var blacklist = {1: true};" |
|
620 | 627 |
"observer = function(r) { records = r };" |
621 | 628 |
"Array.observe(obj, observer);" |
622 | 629 |
"Array.observe(objNoCheck, observer);"); |
623 | 630 |
Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
624 | 631 |
{ |
625 |
LocalContext context2; |
|
632 |
LocalContext context2(isolate.GetIsolate());
|
|
626 | 633 |
context2->Global()->Set(String::New("obj"), instance); |
627 | 634 |
context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
628 | 635 |
CompileRun("var records2 = null;" |
... | ... | |
653 | 660 |
TEST(DisallowAllForAccessKeys) { |
654 | 661 |
HarmonyIsolate isolate; |
655 | 662 |
HandleScope scope(isolate.GetIsolate()); |
656 |
LocalContext context; |
|
663 |
LocalContext context(isolate.GetIsolate());
|
|
657 | 664 |
Handle<Object> instance = CreateAccessCheckedObject( |
658 | 665 |
BlockAccessKeys, IndexedAccessAlwaysAllowed); |
659 | 666 |
CompileRun("var records = null;" |
660 | 667 |
"var objNoCheck = {};" |
661 | 668 |
"var observer = function(r) { records = r };" |
662 |
"var blacklist = {__block_access_keys: true};" |
|
663 | 669 |
"Object.observe(obj, observer);" |
664 | 670 |
"Object.observe(objNoCheck, observer);"); |
665 | 671 |
Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
666 | 672 |
{ |
667 |
LocalContext context2; |
|
673 |
LocalContext context2(isolate.GetIsolate());
|
|
668 | 674 |
context2->Global()->Set(String::New("obj"), instance); |
669 | 675 |
context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
670 | 676 |
CompileRun("var records2 = null;" |
... | ... | |
691 | 697 |
TEST(AccessCheckDisallowApiModifications) { |
692 | 698 |
HarmonyIsolate isolate; |
693 | 699 |
HandleScope scope(isolate.GetIsolate()); |
694 |
LocalContext context; |
|
700 |
LocalContext context(isolate.GetIsolate());
|
|
695 | 701 |
Handle<Object> instance = CreateAccessCheckedObject( |
696 | 702 |
BlockAccessKeys, IndexedAccessAlwaysAllowed); |
697 | 703 |
CompileRun("var records = null;" |
698 | 704 |
"var observer = function(r) { records = r };" |
699 |
"var blacklist = {__block_access_keys: true};" |
|
700 | 705 |
"Object.observe(obj, observer);"); |
701 | 706 |
{ |
702 |
LocalContext context2; |
|
707 |
LocalContext context2(isolate.GetIsolate());
|
|
703 | 708 |
context2->Global()->Set(String::New("obj"), instance); |
704 | 709 |
CompileRun("var records2 = null;" |
705 | 710 |
"var observer2 = function(r) { records2 = r };" |
... | ... | |
715 | 720 |
} |
716 | 721 |
CHECK(CompileRun("records")->IsNull()); |
717 | 722 |
} |
723 |
|
|
724 |
|
|
725 |
TEST(HiddenPropertiesLeakage) { |
|
726 |
HarmonyIsolate isolate; |
|
727 |
HandleScope scope(isolate.GetIsolate()); |
|
728 |
LocalContext context(isolate.GetIsolate()); |
|
729 |
CompileRun("var obj = {};" |
|
730 |
"var records = null;" |
|
731 |
"var observer = function(r) { records = r };" |
|
732 |
"Object.observe(obj, observer);"); |
|
733 |
Handle<Value> obj = context->Global()->Get(String::New("obj")); |
|
734 |
Handle<Object>::Cast(obj)->SetHiddenValue(String::New("foo"), Null()); |
|
735 |
CompileRun(""); // trigger delivery |
|
736 |
CHECK(CompileRun("records")->IsNull()); |
|
737 |
} |
Also available in: Unified diff