OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 obj->Set(Number::New(1.1), Number::New(6), DontDelete); | 349 obj->Set(Number::New(1.1), Number::New(6), DontDelete); |
350 obj->Delete(String::New("foo")); | 350 obj->Delete(String::New("foo")); |
351 obj->Delete(1); | 351 obj->Delete(1); |
352 obj->ForceDelete(Number::New(1.1)); | 352 obj->ForceDelete(Number::New(1.1)); |
353 | 353 |
354 // Force delivery | 354 // Force delivery |
355 // TODO(adamk): Should the above set methods trigger delivery themselves? | 355 // TODO(adamk): Should the above set methods trigger delivery themselves? |
356 CompileRun("void 0"); | 356 CompileRun("void 0"); |
357 CHECK_EQ(9, CompileRun("records.length")->Int32Value()); | 357 CHECK_EQ(9, CompileRun("records.length")->Int32Value()); |
358 const RecordExpectation expected_records[] = { | 358 const RecordExpectation expected_records[] = { |
359 { obj, "new", "foo", Handle<Value>() }, | 359 { obj, "add", "foo", Handle<Value>() }, |
360 { obj, "new", "1", Handle<Value>() }, | 360 { obj, "add", "1", Handle<Value>() }, |
361 // Note: use 7 not 1 below, as the latter triggers a nifty VS10 compiler bug | 361 // Note: use 7 not 1 below, as the latter triggers a nifty VS10 compiler bug |
362 // where instead of 1.0, a garbage value would be passed into Number::New. | 362 // where instead of 1.0, a garbage value would be passed into Number::New. |
363 { obj, "updated", "foo", Number::New(7) }, | 363 { obj, "update", "foo", Number::New(7) }, |
364 { obj, "updated", "1", Number::New(2) }, | 364 { obj, "update", "1", Number::New(2) }, |
365 { obj, "updated", "1", Number::New(4) }, | 365 { obj, "update", "1", Number::New(4) }, |
366 { obj, "new", "1.1", Handle<Value>() }, | 366 { obj, "add", "1.1", Handle<Value>() }, |
367 { obj, "deleted", "foo", Number::New(3) }, | 367 { obj, "delete", "foo", Number::New(3) }, |
368 { obj, "deleted", "1", Number::New(5) }, | 368 { obj, "delete", "1", Number::New(5) }, |
369 { obj, "deleted", "1.1", Number::New(6) } | 369 { obj, "delete", "1.1", Number::New(6) } |
370 }; | 370 }; |
371 EXPECT_RECORDS(CompileRun("records"), expected_records); | 371 EXPECT_RECORDS(CompileRun("records"), expected_records); |
372 } | 372 } |
373 | 373 |
374 | 374 |
375 TEST(HiddenPrototypeObservation) { | 375 TEST(HiddenPrototypeObservation) { |
376 HarmonyIsolate isolate; | 376 HarmonyIsolate isolate; |
377 HandleScope scope(isolate.GetIsolate()); | 377 HandleScope scope(isolate.GetIsolate()); |
378 LocalContext context(isolate.GetIsolate()); | 378 LocalContext context(isolate.GetIsolate()); |
379 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); | 379 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); |
380 tmpl->SetHiddenPrototype(true); | 380 tmpl->SetHiddenPrototype(true); |
381 tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); | 381 tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); |
382 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); | 382 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); |
383 Handle<Object> obj = Object::New(); | 383 Handle<Object> obj = Object::New(); |
384 obj->SetPrototype(proto); | 384 obj->SetPrototype(proto); |
385 context->Global()->Set(String::New("obj"), obj); | 385 context->Global()->Set(String::New("obj"), obj); |
386 context->Global()->Set(String::New("proto"), proto); | 386 context->Global()->Set(String::New("proto"), proto); |
387 CompileRun( | 387 CompileRun( |
388 "var records;" | 388 "var records;" |
389 "function observer(r) { records = r; };" | 389 "function observer(r) { records = r; };" |
390 "Object.observe(obj, observer);" | 390 "Object.observe(obj, observer);" |
391 "obj.foo = 41;" // triggers a notification | 391 "obj.foo = 41;" // triggers a notification |
392 "proto.foo = 42;"); // does not trigger a notification | 392 "proto.foo = 42;"); // does not trigger a notification |
393 const RecordExpectation expected_records[] = { | 393 const RecordExpectation expected_records[] = { |
394 { obj, "updated", "foo", Number::New(75) } | 394 { obj, "update", "foo", Number::New(75) } |
395 }; | 395 }; |
396 EXPECT_RECORDS(CompileRun("records"), expected_records); | 396 EXPECT_RECORDS(CompileRun("records"), expected_records); |
397 obj->SetPrototype(Null(isolate.GetIsolate())); | 397 obj->SetPrototype(Null(isolate.GetIsolate())); |
398 CompileRun("obj.foo = 43"); | 398 CompileRun("obj.foo = 43"); |
399 const RecordExpectation expected_records2[] = { | 399 const RecordExpectation expected_records2[] = { |
400 { obj, "new", "foo", Handle<Value>() } | 400 { obj, "add", "foo", Handle<Value>() } |
401 }; | 401 }; |
402 EXPECT_RECORDS(CompileRun("records"), expected_records2); | 402 EXPECT_RECORDS(CompileRun("records"), expected_records2); |
403 obj->SetPrototype(proto); | 403 obj->SetPrototype(proto); |
404 CompileRun( | 404 CompileRun( |
405 "Object.observe(proto, observer);" | 405 "Object.observe(proto, observer);" |
406 "proto.bar = 1;" | 406 "proto.bar = 1;" |
407 "Object.unobserve(obj, observer);" | 407 "Object.unobserve(obj, observer);" |
408 "obj.foo = 44;"); | 408 "obj.foo = 44;"); |
409 const RecordExpectation expected_records3[] = { | 409 const RecordExpectation expected_records3[] = { |
410 { proto, "new", "bar", Handle<Value>() } | 410 { proto, "add", "bar", Handle<Value>() } |
411 // TODO(adamk): The below record should be emitted since proto is observed | 411 // TODO(adamk): The below record should be emitted since proto is observed |
412 // and has been modified. Not clear if this happens in practice. | 412 // and has been modified. Not clear if this happens in practice. |
413 // { proto, "updated", "foo", Number::New(43) } | 413 // { proto, "update", "foo", Number::New(43) } |
414 }; | 414 }; |
415 EXPECT_RECORDS(CompileRun("records"), expected_records3); | 415 EXPECT_RECORDS(CompileRun("records"), expected_records3); |
416 } | 416 } |
417 | 417 |
418 | 418 |
419 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { | 419 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { |
420 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); | 420 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); |
421 } | 421 } |
422 | 422 |
423 | 423 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 CompileRun("var records2 = null;" | 541 CompileRun("var records2 = null;" |
542 "var observer2 = function(r) { records2 = r };" | 542 "var observer2 = function(r) { records2 = r };" |
543 "Object.observe(obj, observer2);" | 543 "Object.observe(obj, observer2);" |
544 "Object.observe(objNoCheck, observer2);" | 544 "Object.observe(objNoCheck, observer2);" |
545 "obj.foo = 'bar';" | 545 "obj.foo = 'bar';" |
546 "Object.defineProperty(obj, 'foo', {value: 5});" | 546 "Object.defineProperty(obj, 'foo', {value: 5});" |
547 "Object.defineProperty(obj, 'foo', {get: function(){}});" | 547 "Object.defineProperty(obj, 'foo', {get: function(){}});" |
548 "obj.bar = 'baz';" | 548 "obj.bar = 'baz';" |
549 "objNoCheck.baz = 'quux'"); | 549 "objNoCheck.baz = 'quux'"); |
550 const RecordExpectation expected_records2[] = { | 550 const RecordExpectation expected_records2[] = { |
551 { instance, "new", "foo", Handle<Value>() }, | 551 { instance, "add", "foo", Handle<Value>() }, |
552 { instance, "updated", "foo", String::New("bar") }, | 552 { instance, "update", "foo", String::New("bar") }, |
553 { instance, "reconfigured", "foo", Number::New(5) }, | 553 { instance, "reconfigure", "foo", Number::New(5) }, |
554 { instance, "new", "bar", Handle<Value>() }, | 554 { instance, "add", "bar", Handle<Value>() }, |
555 { obj_no_check, "new", "baz", Handle<Value>() }, | 555 { obj_no_check, "add", "baz", Handle<Value>() }, |
556 }; | 556 }; |
557 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 557 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
558 } | 558 } |
559 const RecordExpectation expected_records[] = { | 559 const RecordExpectation expected_records[] = { |
560 { instance, "new", "bar", Handle<Value>() }, | 560 { instance, "add", "bar", Handle<Value>() }, |
561 { obj_no_check, "new", "baz", Handle<Value>() } | 561 { obj_no_check, "add", "baz", Handle<Value>() } |
562 }; | 562 }; |
563 EXPECT_RECORDS(CompileRun("records"), expected_records); | 563 EXPECT_RECORDS(CompileRun("records"), expected_records); |
564 } | 564 } |
565 } | 565 } |
566 | 566 |
567 | 567 |
568 TEST(IndexedAccessCheck) { | 568 TEST(IndexedAccessCheck) { |
569 HarmonyIsolate isolate; | 569 HarmonyIsolate isolate; |
570 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 570 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
571 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 571 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
(...skipping 16 matching lines...) Expand all Loading... |
588 CompileRun("var records2 = null;" | 588 CompileRun("var records2 = null;" |
589 "var observer2 = function(r) { records2 = r };" | 589 "var observer2 = function(r) { records2 = r };" |
590 "Object.observe(obj, observer2);" | 590 "Object.observe(obj, observer2);" |
591 "Object.observe(objNoCheck, observer2);" | 591 "Object.observe(objNoCheck, observer2);" |
592 "obj[7] = 'foo';" | 592 "obj[7] = 'foo';" |
593 "Object.defineProperty(obj, '7', {value: 5});" | 593 "Object.defineProperty(obj, '7', {value: 5});" |
594 "Object.defineProperty(obj, '7', {get: function(){}});" | 594 "Object.defineProperty(obj, '7', {get: function(){}});" |
595 "obj[8] = 'bar';" | 595 "obj[8] = 'bar';" |
596 "objNoCheck[42] = 'quux'"); | 596 "objNoCheck[42] = 'quux'"); |
597 const RecordExpectation expected_records2[] = { | 597 const RecordExpectation expected_records2[] = { |
598 { instance, "new", "7", Handle<Value>() }, | 598 { instance, "add", "7", Handle<Value>() }, |
599 { instance, "updated", "7", String::New("foo") }, | 599 { instance, "update", "7", String::New("foo") }, |
600 { instance, "reconfigured", "7", Number::New(5) }, | 600 { instance, "reconfigure", "7", Number::New(5) }, |
601 { instance, "new", "8", Handle<Value>() }, | 601 { instance, "add", "8", Handle<Value>() }, |
602 { obj_no_check, "new", "42", Handle<Value>() } | 602 { obj_no_check, "add", "42", Handle<Value>() } |
603 }; | 603 }; |
604 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 604 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
605 } | 605 } |
606 const RecordExpectation expected_records[] = { | 606 const RecordExpectation expected_records[] = { |
607 { instance, "new", "8", Handle<Value>() }, | 607 { instance, "add", "8", Handle<Value>() }, |
608 { obj_no_check, "new", "42", Handle<Value>() } | 608 { obj_no_check, "add", "42", Handle<Value>() } |
609 }; | 609 }; |
610 EXPECT_RECORDS(CompileRun("records"), expected_records); | 610 EXPECT_RECORDS(CompileRun("records"), expected_records); |
611 } | 611 } |
612 } | 612 } |
613 | 613 |
614 | 614 |
615 TEST(SpliceAccessCheck) { | 615 TEST(SpliceAccessCheck) { |
616 HarmonyIsolate isolate; | 616 HarmonyIsolate isolate; |
617 HandleScope scope(isolate.GetIsolate()); | 617 HandleScope scope(isolate.GetIsolate()); |
618 LocalContext context(isolate.GetIsolate()); | 618 LocalContext context(isolate.GetIsolate()); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
674 context2->Global()->Set(String::New("obj"), instance); | 674 context2->Global()->Set(String::New("obj"), instance); |
675 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 675 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
676 CompileRun("var records2 = null;" | 676 CompileRun("var records2 = null;" |
677 "var observer2 = function(r) { records2 = r };" | 677 "var observer2 = function(r) { records2 = r };" |
678 "Object.observe(obj, observer2);" | 678 "Object.observe(obj, observer2);" |
679 "Object.observe(objNoCheck, observer2);" | 679 "Object.observe(objNoCheck, observer2);" |
680 "obj.foo = 'bar';" | 680 "obj.foo = 'bar';" |
681 "obj[5] = 'baz';" | 681 "obj[5] = 'baz';" |
682 "objNoCheck.baz = 'quux'"); | 682 "objNoCheck.baz = 'quux'"); |
683 const RecordExpectation expected_records2[] = { | 683 const RecordExpectation expected_records2[] = { |
684 { instance, "new", "foo", Handle<Value>() }, | 684 { instance, "add", "foo", Handle<Value>() }, |
685 { instance, "new", "5", Handle<Value>() }, | 685 { instance, "add", "5", Handle<Value>() }, |
686 { obj_no_check, "new", "baz", Handle<Value>() }, | 686 { obj_no_check, "add", "baz", Handle<Value>() }, |
687 }; | 687 }; |
688 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 688 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
689 } | 689 } |
690 const RecordExpectation expected_records[] = { | 690 const RecordExpectation expected_records[] = { |
691 { obj_no_check, "new", "baz", Handle<Value>() } | 691 { obj_no_check, "add", "baz", Handle<Value>() } |
692 }; | 692 }; |
693 EXPECT_RECORDS(CompileRun("records"), expected_records); | 693 EXPECT_RECORDS(CompileRun("records"), expected_records); |
694 } | 694 } |
695 | 695 |
696 | 696 |
697 TEST(AccessCheckDisallowApiModifications) { | 697 TEST(AccessCheckDisallowApiModifications) { |
698 HarmonyIsolate isolate; | 698 HarmonyIsolate isolate; |
699 HandleScope scope(isolate.GetIsolate()); | 699 HandleScope scope(isolate.GetIsolate()); |
700 LocalContext context(isolate.GetIsolate()); | 700 LocalContext context(isolate.GetIsolate()); |
701 Handle<Object> instance = CreateAccessCheckedObject( | 701 Handle<Object> instance = CreateAccessCheckedObject( |
702 BlockAccessKeys, IndexedAccessAlwaysAllowed); | 702 BlockAccessKeys, IndexedAccessAlwaysAllowed); |
703 CompileRun("var records = null;" | 703 CompileRun("var records = null;" |
704 "var observer = function(r) { records = r };" | 704 "var observer = function(r) { records = r };" |
705 "Object.observe(obj, observer);"); | 705 "Object.observe(obj, observer);"); |
706 { | 706 { |
707 LocalContext context2(isolate.GetIsolate()); | 707 LocalContext context2(isolate.GetIsolate()); |
708 context2->Global()->Set(String::New("obj"), instance); | 708 context2->Global()->Set(String::New("obj"), instance); |
709 CompileRun("var records2 = null;" | 709 CompileRun("var records2 = null;" |
710 "var observer2 = function(r) { records2 = r };" | 710 "var observer2 = function(r) { records2 = r };" |
711 "Object.observe(obj, observer2);"); | 711 "Object.observe(obj, observer2);"); |
712 instance->Set(5, String::New("bar")); | 712 instance->Set(5, String::New("bar")); |
713 instance->Set(String::New("foo"), String::New("bar")); | 713 instance->Set(String::New("foo"), String::New("bar")); |
714 CompileRun(""); // trigger delivery | 714 CompileRun(""); // trigger delivery |
715 const RecordExpectation expected_records2[] = { | 715 const RecordExpectation expected_records2[] = { |
716 { instance, "new", "5", Handle<Value>() }, | 716 { instance, "add", "5", Handle<Value>() }, |
717 { instance, "new", "foo", Handle<Value>() } | 717 { instance, "add", "foo", Handle<Value>() } |
718 }; | 718 }; |
719 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 719 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
720 } | 720 } |
721 CHECK(CompileRun("records")->IsNull()); | 721 CHECK(CompileRun("records")->IsNull()); |
722 } | 722 } |
723 | 723 |
724 | 724 |
725 TEST(HiddenPropertiesLeakage) { | 725 TEST(HiddenPropertiesLeakage) { |
726 HarmonyIsolate isolate; | 726 HarmonyIsolate isolate; |
727 HandleScope scope(isolate.GetIsolate()); | 727 HandleScope scope(isolate.GetIsolate()); |
728 LocalContext context(isolate.GetIsolate()); | 728 LocalContext context(isolate.GetIsolate()); |
729 CompileRun("var obj = {};" | 729 CompileRun("var obj = {};" |
730 "var records = null;" | 730 "var records = null;" |
731 "var observer = function(r) { records = r };" | 731 "var observer = function(r) { records = r };" |
732 "Object.observe(obj, observer);"); | 732 "Object.observe(obj, observer);"); |
733 Handle<Value> obj = context->Global()->Get(String::New("obj")); | 733 Handle<Value> obj = context->Global()->Get(String::New("obj")); |
734 Handle<Object>::Cast(obj)->SetHiddenValue(String::New("foo"), Null()); | 734 Handle<Object>::Cast(obj)->SetHiddenValue(String::New("foo"), Null()); |
735 CompileRun(""); // trigger delivery | 735 CompileRun(""); // trigger delivery |
736 CHECK(CompileRun("records")->IsNull()); | 736 CHECK(CompileRun("records")->IsNull()); |
737 } | 737 } |
OLD | NEW |