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