| 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 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 } | 327 } |
| 328 | 328 |
| 329 #define EXPECT_RECORDS(records, expectations) \ | 329 #define EXPECT_RECORDS(records, expectations) \ |
| 330 ExpectRecords(isolate.GetIsolate(), records, expectations, \ | 330 ExpectRecords(isolate.GetIsolate(), records, expectations, \ |
| 331 ARRAY_SIZE(expectations)) | 331 ARRAY_SIZE(expectations)) |
| 332 | 332 |
| 333 TEST(APITestBasicMutation) { | 333 TEST(APITestBasicMutation) { |
| 334 HarmonyIsolate isolate; | 334 HarmonyIsolate isolate; |
| 335 v8::Isolate* v8_isolate = isolate.GetIsolate(); | 335 HandleScope scope(isolate.GetIsolate()); |
| 336 HandleScope scope(v8_isolate); | 336 LocalContext context(isolate.GetIsolate()); |
| 337 LocalContext context(v8_isolate); | |
| 338 Handle<Object> obj = Handle<Object>::Cast(CompileRun( | 337 Handle<Object> obj = Handle<Object>::Cast(CompileRun( |
| 339 "var records = [];" | 338 "var records = [];" |
| 340 "var obj = {};" | 339 "var obj = {};" |
| 341 "function observer(r) { [].push.apply(records, r); };" | 340 "function observer(r) { [].push.apply(records, r); };" |
| 342 "Object.observe(obj, observer);" | 341 "Object.observe(obj, observer);" |
| 343 "obj")); | 342 "obj")); |
| 344 obj->Set(String::NewFromUtf8(v8_isolate, "foo"), | 343 obj->Set(String::NewFromUtf8(isolate.GetIsolate(), "foo"), Number::New(7)); |
| 345 Number::New(v8_isolate, 7)); | 344 obj->Set(1, Number::New(2)); |
| 346 obj->Set(1, Number::New(v8_isolate, 2)); | |
| 347 // ForceSet should work just as well as Set | 345 // ForceSet should work just as well as Set |
| 348 obj->ForceSet(String::NewFromUtf8(v8_isolate, "foo"), | 346 obj->ForceSet(String::NewFromUtf8(isolate.GetIsolate(), "foo"), |
| 349 Number::New(v8_isolate, 3)); | 347 Number::New(3)); |
| 350 obj->ForceSet(Number::New(v8_isolate, 1), Number::New(v8_isolate, 4)); | 348 obj->ForceSet(Number::New(1), Number::New(4)); |
| 351 // Setting an indexed element via the property setting method | 349 // Setting an indexed element via the property setting method |
| 352 obj->Set(Number::New(v8_isolate, 1), Number::New(v8_isolate, 5)); | 350 obj->Set(Number::New(1), Number::New(5)); |
| 353 // Setting with a non-String, non-uint32 key | 351 // Setting with a non-String, non-uint32 key |
| 354 obj->Set(Number::New(v8_isolate, 1.1), | 352 obj->Set(Number::New(1.1), Number::New(6), DontDelete); |
| 355 Number::New(v8_isolate, 6), DontDelete); | 353 obj->Delete(String::NewFromUtf8(isolate.GetIsolate(), "foo")); |
| 356 obj->Delete(String::NewFromUtf8(v8_isolate, "foo")); | |
| 357 obj->Delete(1); | 354 obj->Delete(1); |
| 358 obj->ForceDelete(Number::New(v8_isolate, 1.1)); | 355 obj->ForceDelete(Number::New(1.1)); |
| 359 | 356 |
| 360 // Force delivery | 357 // Force delivery |
| 361 // TODO(adamk): Should the above set methods trigger delivery themselves? | 358 // TODO(adamk): Should the above set methods trigger delivery themselves? |
| 362 CompileRun("void 0"); | 359 CompileRun("void 0"); |
| 363 CHECK_EQ(9, CompileRun("records.length")->Int32Value()); | 360 CHECK_EQ(9, CompileRun("records.length")->Int32Value()); |
| 364 const RecordExpectation expected_records[] = { | 361 const RecordExpectation expected_records[] = { |
| 365 { obj, "add", "foo", Handle<Value>() }, | 362 { obj, "add", "foo", Handle<Value>() }, |
| 366 { obj, "add", "1", Handle<Value>() }, | 363 { obj, "add", "1", Handle<Value>() }, |
| 367 // Note: use 7 not 1 below, as the latter triggers a nifty VS10 compiler bug | 364 // Note: use 7 not 1 below, as the latter triggers a nifty VS10 compiler bug |
| 368 // where instead of 1.0, a garbage value would be passed into Number::New. | 365 // where instead of 1.0, a garbage value would be passed into Number::New. |
| 369 { obj, "update", "foo", Number::New(v8_isolate, 7) }, | 366 { obj, "update", "foo", Number::New(7) }, |
| 370 { obj, "update", "1", Number::New(v8_isolate, 2) }, | 367 { obj, "update", "1", Number::New(2) }, |
| 371 { obj, "update", "1", Number::New(v8_isolate, 4) }, | 368 { obj, "update", "1", Number::New(4) }, |
| 372 { obj, "add", "1.1", Handle<Value>() }, | 369 { obj, "add", "1.1", Handle<Value>() }, |
| 373 { obj, "delete", "foo", Number::New(v8_isolate, 3) }, | 370 { obj, "delete", "foo", Number::New(3) }, |
| 374 { obj, "delete", "1", Number::New(v8_isolate, 5) }, | 371 { obj, "delete", "1", Number::New(5) }, |
| 375 { obj, "delete", "1.1", Number::New(v8_isolate, 6) } | 372 { obj, "delete", "1.1", Number::New(6) } |
| 376 }; | 373 }; |
| 377 EXPECT_RECORDS(CompileRun("records"), expected_records); | 374 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 378 } | 375 } |
| 379 | 376 |
| 380 | 377 |
| 381 TEST(HiddenPrototypeObservation) { | 378 TEST(HiddenPrototypeObservation) { |
| 382 HarmonyIsolate isolate; | 379 HarmonyIsolate isolate; |
| 383 v8::Isolate* v8_isolate = isolate.GetIsolate(); | 380 HandleScope scope(isolate.GetIsolate()); |
| 384 HandleScope scope(v8_isolate); | 381 LocalContext context(isolate.GetIsolate()); |
| 385 LocalContext context(v8_isolate); | 382 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(isolate.GetIsolate()); |
| 386 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(v8_isolate); | |
| 387 tmpl->SetHiddenPrototype(true); | 383 tmpl->SetHiddenPrototype(true); |
| 388 tmpl->InstanceTemplate()->Set( | 384 tmpl->InstanceTemplate()->Set( |
| 389 String::NewFromUtf8(v8_isolate, "foo"), Number::New(v8_isolate, 75)); | 385 String::NewFromUtf8(isolate.GetIsolate(), "foo"), Number::New(75)); |
| 390 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); | 386 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); |
| 391 Handle<Object> obj = Object::New(v8_isolate); | 387 Handle<Object> obj = Object::New(); |
| 392 obj->SetPrototype(proto); | 388 obj->SetPrototype(proto); |
| 393 context->Global()->Set(String::NewFromUtf8(v8_isolate, "obj"), obj); | 389 context->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj); |
| 394 context->Global()->Set(String::NewFromUtf8(v8_isolate, "proto"), | 390 context->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "proto"), |
| 395 proto); | 391 proto); |
| 396 CompileRun( | 392 CompileRun( |
| 397 "var records;" | 393 "var records;" |
| 398 "function observer(r) { records = r; };" | 394 "function observer(r) { records = r; };" |
| 399 "Object.observe(obj, observer);" | 395 "Object.observe(obj, observer);" |
| 400 "obj.foo = 41;" // triggers a notification | 396 "obj.foo = 41;" // triggers a notification |
| 401 "proto.foo = 42;"); // does not trigger a notification | 397 "proto.foo = 42;"); // does not trigger a notification |
| 402 const RecordExpectation expected_records[] = { | 398 const RecordExpectation expected_records[] = { |
| 403 { obj, "update", "foo", Number::New(v8_isolate, 75) } | 399 { obj, "update", "foo", Number::New(75) } |
| 404 }; | 400 }; |
| 405 EXPECT_RECORDS(CompileRun("records"), expected_records); | 401 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 406 obj->SetPrototype(Null(v8_isolate)); | 402 obj->SetPrototype(Null(isolate.GetIsolate())); |
| 407 CompileRun("obj.foo = 43"); | 403 CompileRun("obj.foo = 43"); |
| 408 const RecordExpectation expected_records2[] = { | 404 const RecordExpectation expected_records2[] = { |
| 409 { obj, "add", "foo", Handle<Value>() } | 405 { obj, "add", "foo", Handle<Value>() } |
| 410 }; | 406 }; |
| 411 EXPECT_RECORDS(CompileRun("records"), expected_records2); | 407 EXPECT_RECORDS(CompileRun("records"), expected_records2); |
| 412 obj->SetPrototype(proto); | 408 obj->SetPrototype(proto); |
| 413 CompileRun( | 409 CompileRun( |
| 414 "Object.observe(proto, observer);" | 410 "Object.observe(proto, observer);" |
| 415 "proto.bar = 1;" | 411 "proto.bar = 1;" |
| 416 "Object.unobserve(obj, observer);" | 412 "Object.unobserve(obj, observer);" |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 558 "Object.observe(objNoCheck, observer2);" | 554 "Object.observe(objNoCheck, observer2);" |
| 559 "obj.foo = 'bar';" | 555 "obj.foo = 'bar';" |
| 560 "Object.defineProperty(obj, 'foo', {value: 5});" | 556 "Object.defineProperty(obj, 'foo', {value: 5});" |
| 561 "Object.defineProperty(obj, 'foo', {get: function(){}});" | 557 "Object.defineProperty(obj, 'foo', {get: function(){}});" |
| 562 "obj.bar = 'baz';" | 558 "obj.bar = 'baz';" |
| 563 "objNoCheck.baz = 'quux'"); | 559 "objNoCheck.baz = 'quux'"); |
| 564 const RecordExpectation expected_records2[] = { | 560 const RecordExpectation expected_records2[] = { |
| 565 { instance, "add", "foo", Handle<Value>() }, | 561 { instance, "add", "foo", Handle<Value>() }, |
| 566 { instance, "update", "foo", | 562 { instance, "update", "foo", |
| 567 String::NewFromUtf8(isolate.GetIsolate(), "bar") }, | 563 String::NewFromUtf8(isolate.GetIsolate(), "bar") }, |
| 568 { instance, "reconfigure", "foo", | 564 { instance, "reconfigure", "foo", Number::New(5) }, |
| 569 Number::New(isolate.GetIsolate(), 5) }, | |
| 570 { instance, "add", "bar", Handle<Value>() }, | 565 { instance, "add", "bar", Handle<Value>() }, |
| 571 { obj_no_check, "add", "baz", Handle<Value>() }, | 566 { obj_no_check, "add", "baz", Handle<Value>() }, |
| 572 }; | 567 }; |
| 573 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 568 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
| 574 } | 569 } |
| 575 const RecordExpectation expected_records[] = { | 570 const RecordExpectation expected_records[] = { |
| 576 { instance, "add", "bar", Handle<Value>() }, | 571 { instance, "add", "bar", Handle<Value>() }, |
| 577 { obj_no_check, "add", "baz", Handle<Value>() } | 572 { obj_no_check, "add", "baz", Handle<Value>() } |
| 578 }; | 573 }; |
| 579 EXPECT_RECORDS(CompileRun("records"), expected_records); | 574 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 580 } | 575 } |
| 581 } | 576 } |
| 582 | 577 |
| 583 | 578 |
| 584 TEST(IndexedAccessCheck) { | 579 TEST(IndexedAccessCheck) { |
| 585 HarmonyIsolate isolate; | 580 HarmonyIsolate isolate; |
| 586 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 581 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
| 587 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 582 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
| 588 HandleScope scope(isolate.GetIsolate()); | 583 HandleScope scope(isolate.GetIsolate()); |
| 589 LocalContext context(isolate.GetIsolate()); | 584 LocalContext context(isolate.GetIsolate()); |
| 590 g_access_block_type = types[i]; | 585 g_access_block_type = types[i]; |
| 591 Handle<Object> instance = CreateAccessCheckedObject( | 586 Handle<Object> instance = CreateAccessCheckedObject( |
| 592 isolate.GetIsolate(), NamedAccessAlwaysAllowed, | 587 isolate.GetIsolate(), NamedAccessAlwaysAllowed, |
| 593 IndexedAccessAllowUnlessBlocked, Number::New(isolate.GetIsolate(), 7)); | 588 IndexedAccessAllowUnlessBlocked, Number::New(7)); |
| 594 CompileRun("var records = null;" | 589 CompileRun("var records = null;" |
| 595 "var objNoCheck = {};" | 590 "var objNoCheck = {};" |
| 596 "var observer = function(r) { records = r };" | 591 "var observer = function(r) { records = r };" |
| 597 "Object.observe(obj, observer);" | 592 "Object.observe(obj, observer);" |
| 598 "Object.observe(objNoCheck, observer);"); | 593 "Object.observe(objNoCheck, observer);"); |
| 599 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 594 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
| 600 { | 595 { |
| 601 LocalContext context2(isolate.GetIsolate()); | 596 LocalContext context2(isolate.GetIsolate()); |
| 602 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), | 597 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 603 instance); | 598 instance); |
| 604 context2->Global()->Set( | 599 context2->Global()->Set( |
| 605 String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), | 600 String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), |
| 606 obj_no_check); | 601 obj_no_check); |
| 607 CompileRun("var records2 = null;" | 602 CompileRun("var records2 = null;" |
| 608 "var observer2 = function(r) { records2 = r };" | 603 "var observer2 = function(r) { records2 = r };" |
| 609 "Object.observe(obj, observer2);" | 604 "Object.observe(obj, observer2);" |
| 610 "Object.observe(objNoCheck, observer2);" | 605 "Object.observe(objNoCheck, observer2);" |
| 611 "obj[7] = 'foo';" | 606 "obj[7] = 'foo';" |
| 612 "Object.defineProperty(obj, '7', {value: 5});" | 607 "Object.defineProperty(obj, '7', {value: 5});" |
| 613 "Object.defineProperty(obj, '7', {get: function(){}});" | 608 "Object.defineProperty(obj, '7', {get: function(){}});" |
| 614 "obj[8] = 'bar';" | 609 "obj[8] = 'bar';" |
| 615 "objNoCheck[42] = 'quux'"); | 610 "objNoCheck[42] = 'quux'"); |
| 616 const RecordExpectation expected_records2[] = { | 611 const RecordExpectation expected_records2[] = { |
| 617 { instance, "add", "7", Handle<Value>() }, | 612 { instance, "add", "7", Handle<Value>() }, |
| 618 { instance, "update", "7", | 613 { instance, "update", "7", |
| 619 String::NewFromUtf8(isolate.GetIsolate(), "foo") }, | 614 String::NewFromUtf8(isolate.GetIsolate(), "foo") }, |
| 620 { instance, "reconfigure", "7", Number::New(isolate.GetIsolate(), 5) }, | 615 { instance, "reconfigure", "7", Number::New(5) }, |
| 621 { instance, "add", "8", Handle<Value>() }, | 616 { instance, "add", "8", Handle<Value>() }, |
| 622 { obj_no_check, "add", "42", Handle<Value>() } | 617 { obj_no_check, "add", "42", Handle<Value>() } |
| 623 }; | 618 }; |
| 624 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 619 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
| 625 } | 620 } |
| 626 const RecordExpectation expected_records[] = { | 621 const RecordExpectation expected_records[] = { |
| 627 { instance, "add", "8", Handle<Value>() }, | 622 { instance, "add", "8", Handle<Value>() }, |
| 628 { obj_no_check, "add", "42", Handle<Value>() } | 623 { obj_no_check, "add", "42", Handle<Value>() } |
| 629 }; | 624 }; |
| 630 EXPECT_RECORDS(CompileRun("records"), expected_records); | 625 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 631 } | 626 } |
| 632 } | 627 } |
| 633 | 628 |
| 634 | 629 |
| 635 TEST(SpliceAccessCheck) { | 630 TEST(SpliceAccessCheck) { |
| 636 HarmonyIsolate isolate; | 631 HarmonyIsolate isolate; |
| 637 HandleScope scope(isolate.GetIsolate()); | 632 HandleScope scope(isolate.GetIsolate()); |
| 638 LocalContext context(isolate.GetIsolate()); | 633 LocalContext context(isolate.GetIsolate()); |
| 639 g_access_block_type = ACCESS_GET; | 634 g_access_block_type = ACCESS_GET; |
| 640 Handle<Object> instance = CreateAccessCheckedObject( | 635 Handle<Object> instance = CreateAccessCheckedObject( |
| 641 isolate.GetIsolate(), NamedAccessAlwaysAllowed, | 636 isolate.GetIsolate(), NamedAccessAlwaysAllowed, |
| 642 IndexedAccessAllowUnlessBlocked, Number::New(isolate.GetIsolate(), 1)); | 637 IndexedAccessAllowUnlessBlocked, Number::New(1)); |
| 643 CompileRun("var records = null;" | 638 CompileRun("var records = null;" |
| 644 "obj[1] = 'foo';" | 639 "obj[1] = 'foo';" |
| 645 "obj.length = 2;" | 640 "obj.length = 2;" |
| 646 "var objNoCheck = {1: 'bar', length: 2};" | 641 "var objNoCheck = {1: 'bar', length: 2};" |
| 647 "observer = function(r) { records = r };" | 642 "observer = function(r) { records = r };" |
| 648 "Array.observe(obj, observer);" | 643 "Array.observe(obj, observer);" |
| 649 "Array.observe(objNoCheck, observer);"); | 644 "Array.observe(objNoCheck, observer);"); |
| 650 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 645 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
| 651 { | 646 { |
| 652 LocalContext context2(isolate.GetIsolate()); | 647 LocalContext context2(isolate.GetIsolate()); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 "var observer = function(r) { records = r };" | 752 "var observer = function(r) { records = r };" |
| 758 "Object.observe(obj, observer);"); | 753 "Object.observe(obj, observer);"); |
| 759 Handle<Value> obj = | 754 Handle<Value> obj = |
| 760 context->Global()->Get(String::NewFromUtf8(isolate.GetIsolate(), "obj")); | 755 context->Global()->Get(String::NewFromUtf8(isolate.GetIsolate(), "obj")); |
| 761 Handle<Object>::Cast(obj) | 756 Handle<Object>::Cast(obj) |
| 762 ->SetHiddenValue(String::NewFromUtf8(isolate.GetIsolate(), "foo"), | 757 ->SetHiddenValue(String::NewFromUtf8(isolate.GetIsolate(), "foo"), |
| 763 Null(isolate.GetIsolate())); | 758 Null(isolate.GetIsolate())); |
| 764 CompileRun(""); // trigger delivery | 759 CompileRun(""); // trigger delivery |
| 765 CHECK(CompileRun("records")->IsNull()); | 760 CHECK(CompileRun("records")->IsNull()); |
| 766 } | 761 } |
| OLD | NEW |