| 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 24 matching lines...) Expand all Loading... |
| 35 using namespace v8; | 35 using namespace v8; |
| 36 namespace i = v8::internal; | 36 namespace i = v8::internal; |
| 37 | 37 |
| 38 inline int32_t ToInt32(v8::Local<v8::Value> value) { | 38 inline int32_t ToInt32(v8::Local<v8::Value> value) { |
| 39 return value->Int32Value(v8::Isolate::GetCurrent()->GetCurrentContext()) | 39 return value->Int32Value(v8::Isolate::GetCurrent()->GetCurrentContext()) |
| 40 .FromJust(); | 40 .FromJust(); |
| 41 } | 41 } |
| 42 | 42 |
| 43 | 43 |
| 44 TEST(PerIsolateState) { | 44 TEST(PerIsolateState) { |
| 45 i::FLAG_harmony_object_observe = true; |
| 45 HandleScope scope(CcTest::isolate()); | 46 HandleScope scope(CcTest::isolate()); |
| 46 LocalContext context1(CcTest::isolate()); | 47 LocalContext context1(CcTest::isolate()); |
| 47 | 48 |
| 48 Local<Value> foo = v8_str("foo"); | 49 Local<Value> foo = v8_str("foo"); |
| 49 context1->SetSecurityToken(foo); | 50 context1->SetSecurityToken(foo); |
| 50 | 51 |
| 51 CompileRun( | 52 CompileRun( |
| 52 "var count = 0;" | 53 "var count = 0;" |
| 53 "var calls = 0;" | 54 "var calls = 0;" |
| 54 "var observer = function(records) { count = records.length; calls++ };" | 55 "var observer = function(records) { count = records.length; calls++ };" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 notify_fun3) | 99 notify_fun3) |
| 99 .FromJust(); | 100 .FromJust(); |
| 100 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); | 101 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); |
| 101 } | 102 } |
| 102 CHECK_EQ(1, ToInt32(CompileRun("calls"))); | 103 CHECK_EQ(1, ToInt32(CompileRun("calls"))); |
| 103 CHECK_EQ(3, ToInt32(CompileRun("count"))); | 104 CHECK_EQ(3, ToInt32(CompileRun("count"))); |
| 104 } | 105 } |
| 105 | 106 |
| 106 | 107 |
| 107 TEST(EndOfMicrotaskDelivery) { | 108 TEST(EndOfMicrotaskDelivery) { |
| 109 i::FLAG_harmony_object_observe = true; |
| 108 HandleScope scope(CcTest::isolate()); | 110 HandleScope scope(CcTest::isolate()); |
| 109 LocalContext context(CcTest::isolate()); | 111 LocalContext context(CcTest::isolate()); |
| 110 CompileRun( | 112 CompileRun( |
| 111 "var obj = {};" | 113 "var obj = {};" |
| 112 "var count = 0;" | 114 "var count = 0;" |
| 113 "var observer = function(records) { count = records.length };" | 115 "var observer = function(records) { count = records.length };" |
| 114 "Object.observe(obj, observer);" | 116 "Object.observe(obj, observer);" |
| 115 "obj.foo = 'bar';"); | 117 "obj.foo = 'bar';"); |
| 116 CHECK_EQ(1, ToInt32(CompileRun("count"))); | 118 CHECK_EQ(1, ToInt32(CompileRun("count"))); |
| 117 } | 119 } |
| 118 | 120 |
| 119 | 121 |
| 120 TEST(DeliveryOrdering) { | 122 TEST(DeliveryOrdering) { |
| 123 i::FLAG_harmony_object_observe = true; |
| 121 HandleScope scope(CcTest::isolate()); | 124 HandleScope scope(CcTest::isolate()); |
| 122 LocalContext context(CcTest::isolate()); | 125 LocalContext context(CcTest::isolate()); |
| 123 CompileRun( | 126 CompileRun( |
| 124 "var obj1 = {};" | 127 "var obj1 = {};" |
| 125 "var obj2 = {};" | 128 "var obj2 = {};" |
| 126 "var ordering = [];" | 129 "var ordering = [];" |
| 127 "function observer2() { ordering.push(2); };" | 130 "function observer2() { ordering.push(2); };" |
| 128 "function observer1() { ordering.push(1); };" | 131 "function observer1() { ordering.push(1); };" |
| 129 "function observer3() { ordering.push(3); };" | 132 "function observer3() { ordering.push(3); };" |
| 130 "Object.observe(obj1, observer1);" | 133 "Object.observe(obj1, observer1);" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 142 "Object.observe(obj2, observer1);" | 145 "Object.observe(obj2, observer1);" |
| 143 "obj2.foo = 'baz'"); | 146 "obj2.foo = 'baz'"); |
| 144 CHECK_EQ(3, ToInt32(CompileRun("ordering.length"))); | 147 CHECK_EQ(3, ToInt32(CompileRun("ordering.length"))); |
| 145 CHECK_EQ(1, ToInt32(CompileRun("ordering[0]"))); | 148 CHECK_EQ(1, ToInt32(CompileRun("ordering[0]"))); |
| 146 CHECK_EQ(2, ToInt32(CompileRun("ordering[1]"))); | 149 CHECK_EQ(2, ToInt32(CompileRun("ordering[1]"))); |
| 147 CHECK_EQ(3, ToInt32(CompileRun("ordering[2]"))); | 150 CHECK_EQ(3, ToInt32(CompileRun("ordering[2]"))); |
| 148 } | 151 } |
| 149 | 152 |
| 150 | 153 |
| 151 TEST(DeliveryCallbackThrows) { | 154 TEST(DeliveryCallbackThrows) { |
| 155 i::FLAG_harmony_object_observe = true; |
| 152 HandleScope scope(CcTest::isolate()); | 156 HandleScope scope(CcTest::isolate()); |
| 153 LocalContext context(CcTest::isolate()); | 157 LocalContext context(CcTest::isolate()); |
| 154 CompileRun( | 158 CompileRun( |
| 155 "var obj = {};" | 159 "var obj = {};" |
| 156 "var ordering = [];" | 160 "var ordering = [];" |
| 157 "function observer1() { ordering.push(1); };" | 161 "function observer1() { ordering.push(1); };" |
| 158 "function observer2() { ordering.push(2); };" | 162 "function observer2() { ordering.push(2); };" |
| 159 "function observer_throws() {" | 163 "function observer_throws() {" |
| 160 " ordering.push(0);" | 164 " ordering.push(0);" |
| 161 " throw new Error();" | 165 " throw new Error();" |
| 162 " ordering.push(-1);" | 166 " ordering.push(-1);" |
| 163 "};" | 167 "};" |
| 164 "Object.observe(obj, observer_throws.bind());" | 168 "Object.observe(obj, observer_throws.bind());" |
| 165 "Object.observe(obj, observer1);" | 169 "Object.observe(obj, observer1);" |
| 166 "Object.observe(obj, observer_throws.bind());" | 170 "Object.observe(obj, observer_throws.bind());" |
| 167 "Object.observe(obj, observer2);" | 171 "Object.observe(obj, observer2);" |
| 168 "Object.observe(obj, observer_throws.bind());" | 172 "Object.observe(obj, observer_throws.bind());" |
| 169 "obj.foo = 'bar';"); | 173 "obj.foo = 'bar';"); |
| 170 CHECK_EQ(5, ToInt32(CompileRun("ordering.length"))); | 174 CHECK_EQ(5, ToInt32(CompileRun("ordering.length"))); |
| 171 CHECK_EQ(0, ToInt32(CompileRun("ordering[0]"))); | 175 CHECK_EQ(0, ToInt32(CompileRun("ordering[0]"))); |
| 172 CHECK_EQ(1, ToInt32(CompileRun("ordering[1]"))); | 176 CHECK_EQ(1, ToInt32(CompileRun("ordering[1]"))); |
| 173 CHECK_EQ(0, ToInt32(CompileRun("ordering[2]"))); | 177 CHECK_EQ(0, ToInt32(CompileRun("ordering[2]"))); |
| 174 CHECK_EQ(2, ToInt32(CompileRun("ordering[3]"))); | 178 CHECK_EQ(2, ToInt32(CompileRun("ordering[3]"))); |
| 175 CHECK_EQ(0, ToInt32(CompileRun("ordering[4]"))); | 179 CHECK_EQ(0, ToInt32(CompileRun("ordering[4]"))); |
| 176 } | 180 } |
| 177 | 181 |
| 178 | 182 |
| 179 TEST(DeliveryChangesMutationInCallback) { | 183 TEST(DeliveryChangesMutationInCallback) { |
| 184 i::FLAG_harmony_object_observe = true; |
| 180 HandleScope scope(CcTest::isolate()); | 185 HandleScope scope(CcTest::isolate()); |
| 181 LocalContext context(CcTest::isolate()); | 186 LocalContext context(CcTest::isolate()); |
| 182 CompileRun( | 187 CompileRun( |
| 183 "var obj = {};" | 188 "var obj = {};" |
| 184 "var ordering = [];" | 189 "var ordering = [];" |
| 185 "function observer1(records) {" | 190 "function observer1(records) {" |
| 186 " ordering.push(100 + records.length);" | 191 " ordering.push(100 + records.length);" |
| 187 " records.push(11);" | 192 " records.push(11);" |
| 188 " records.push(22);" | 193 " records.push(22);" |
| 189 "};" | 194 "};" |
| 190 "function observer2(records) {" | 195 "function observer2(records) {" |
| 191 " ordering.push(200 + records.length);" | 196 " ordering.push(200 + records.length);" |
| 192 " records.push(33);" | 197 " records.push(33);" |
| 193 " records.push(44);" | 198 " records.push(44);" |
| 194 "};" | 199 "};" |
| 195 "Object.observe(obj, observer1);" | 200 "Object.observe(obj, observer1);" |
| 196 "Object.observe(obj, observer2);" | 201 "Object.observe(obj, observer2);" |
| 197 "obj.foo = 'bar';"); | 202 "obj.foo = 'bar';"); |
| 198 CHECK_EQ(2, ToInt32(CompileRun("ordering.length"))); | 203 CHECK_EQ(2, ToInt32(CompileRun("ordering.length"))); |
| 199 CHECK_EQ(101, ToInt32(CompileRun("ordering[0]"))); | 204 CHECK_EQ(101, ToInt32(CompileRun("ordering[0]"))); |
| 200 CHECK_EQ(201, ToInt32(CompileRun("ordering[1]"))); | 205 CHECK_EQ(201, ToInt32(CompileRun("ordering[1]"))); |
| 201 } | 206 } |
| 202 | 207 |
| 203 | 208 |
| 204 TEST(DeliveryOrderingReentrant) { | 209 TEST(DeliveryOrderingReentrant) { |
| 210 i::FLAG_harmony_object_observe = true; |
| 205 HandleScope scope(CcTest::isolate()); | 211 HandleScope scope(CcTest::isolate()); |
| 206 LocalContext context(CcTest::isolate()); | 212 LocalContext context(CcTest::isolate()); |
| 207 CompileRun( | 213 CompileRun( |
| 208 "var obj = {};" | 214 "var obj = {};" |
| 209 "var reentered = false;" | 215 "var reentered = false;" |
| 210 "var ordering = [];" | 216 "var ordering = [];" |
| 211 "function observer1() { ordering.push(1); };" | 217 "function observer1() { ordering.push(1); };" |
| 212 "function observer2() {" | 218 "function observer2() {" |
| 213 " if (!reentered) {" | 219 " if (!reentered) {" |
| 214 " obj.foo = 'baz';" | 220 " obj.foo = 'baz';" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 226 CHECK_EQ(2, ToInt32(CompileRun("ordering[1]"))); | 232 CHECK_EQ(2, ToInt32(CompileRun("ordering[1]"))); |
| 227 CHECK_EQ(3, ToInt32(CompileRun("ordering[2]"))); | 233 CHECK_EQ(3, ToInt32(CompileRun("ordering[2]"))); |
| 228 // Note that we re-deliver to observers 1 and 2, while observer3 | 234 // Note that we re-deliver to observers 1 and 2, while observer3 |
| 229 // already received the second record during the first round. | 235 // already received the second record during the first round. |
| 230 CHECK_EQ(1, ToInt32(CompileRun("ordering[3]"))); | 236 CHECK_EQ(1, ToInt32(CompileRun("ordering[3]"))); |
| 231 CHECK_EQ(2, ToInt32(CompileRun("ordering[1]"))); | 237 CHECK_EQ(2, ToInt32(CompileRun("ordering[1]"))); |
| 232 } | 238 } |
| 233 | 239 |
| 234 | 240 |
| 235 TEST(DeliveryOrderingDeliverChangeRecords) { | 241 TEST(DeliveryOrderingDeliverChangeRecords) { |
| 242 i::FLAG_harmony_object_observe = true; |
| 236 HandleScope scope(CcTest::isolate()); | 243 HandleScope scope(CcTest::isolate()); |
| 237 LocalContext context(CcTest::isolate()); | 244 LocalContext context(CcTest::isolate()); |
| 238 CompileRun( | 245 CompileRun( |
| 239 "var obj = {};" | 246 "var obj = {};" |
| 240 "var ordering = [];" | 247 "var ordering = [];" |
| 241 "function observer1() { ordering.push(1); if (!obj.b) obj.b = true };" | 248 "function observer1() { ordering.push(1); if (!obj.b) obj.b = true };" |
| 242 "function observer2() { ordering.push(2); };" | 249 "function observer2() { ordering.push(2); };" |
| 243 "Object.observe(obj, observer1);" | 250 "Object.observe(obj, observer1);" |
| 244 "Object.observe(obj, observer2);" | 251 "Object.observe(obj, observer2);" |
| 245 "obj.a = 1;" | 252 "obj.a = 1;" |
| 246 "Object.deliverChangeRecords(observer2);"); | 253 "Object.deliverChangeRecords(observer2);"); |
| 247 CHECK_EQ(4, ToInt32(CompileRun("ordering.length"))); | 254 CHECK_EQ(4, ToInt32(CompileRun("ordering.length"))); |
| 248 // First, observer2 is called due to deliverChangeRecords | 255 // First, observer2 is called due to deliverChangeRecords |
| 249 CHECK_EQ(2, ToInt32(CompileRun("ordering[0]"))); | 256 CHECK_EQ(2, ToInt32(CompileRun("ordering[0]"))); |
| 250 // Then, observer1 is called when the stack unwinds | 257 // Then, observer1 is called when the stack unwinds |
| 251 CHECK_EQ(1, ToInt32(CompileRun("ordering[1]"))); | 258 CHECK_EQ(1, ToInt32(CompileRun("ordering[1]"))); |
| 252 // observer1's mutation causes both 1 and 2 to be reactivated, | 259 // observer1's mutation causes both 1 and 2 to be reactivated, |
| 253 // with 1 having priority. | 260 // with 1 having priority. |
| 254 CHECK_EQ(1, ToInt32(CompileRun("ordering[2]"))); | 261 CHECK_EQ(1, ToInt32(CompileRun("ordering[2]"))); |
| 255 CHECK_EQ(2, ToInt32(CompileRun("ordering[3]"))); | 262 CHECK_EQ(2, ToInt32(CompileRun("ordering[3]"))); |
| 256 } | 263 } |
| 257 | 264 |
| 258 | 265 |
| 259 TEST(ObjectHashTableGrowth) { | 266 TEST(ObjectHashTableGrowth) { |
| 267 i::FLAG_harmony_object_observe = true; |
| 260 HandleScope scope(CcTest::isolate()); | 268 HandleScope scope(CcTest::isolate()); |
| 261 // Initializing this context sets up initial hash tables. | 269 // Initializing this context sets up initial hash tables. |
| 262 LocalContext context(CcTest::isolate()); | 270 LocalContext context(CcTest::isolate()); |
| 263 Local<Value> obj = CompileRun("obj = {};"); | 271 Local<Value> obj = CompileRun("obj = {};"); |
| 264 Local<Value> observer = CompileRun( | 272 Local<Value> observer = CompileRun( |
| 265 "var ran = false;" | 273 "var ran = false;" |
| 266 "(function() { ran = true })"); | 274 "(function() { ran = true })"); |
| 267 { | 275 { |
| 268 // As does initializing this context. | 276 // As does initializing this context. |
| 269 LocalContext context2(CcTest::isolate()); | 277 LocalContext context2(CcTest::isolate()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 345 } | 353 } |
| 346 } | 354 } |
| 347 } | 355 } |
| 348 } | 356 } |
| 349 | 357 |
| 350 #define EXPECT_RECORDS(records, expectations) \ | 358 #define EXPECT_RECORDS(records, expectations) \ |
| 351 ExpectRecords(CcTest::isolate(), records, expectations, \ | 359 ExpectRecords(CcTest::isolate(), records, expectations, \ |
| 352 arraysize(expectations)) | 360 arraysize(expectations)) |
| 353 | 361 |
| 354 TEST(APITestBasicMutation) { | 362 TEST(APITestBasicMutation) { |
| 363 i::FLAG_harmony_object_observe = true; |
| 355 v8::Isolate* v8_isolate = CcTest::isolate(); | 364 v8::Isolate* v8_isolate = CcTest::isolate(); |
| 356 HandleScope scope(v8_isolate); | 365 HandleScope scope(v8_isolate); |
| 357 LocalContext context(v8_isolate); | 366 LocalContext context(v8_isolate); |
| 358 Local<Object> obj = Local<Object>::Cast( | 367 Local<Object> obj = Local<Object>::Cast( |
| 359 CompileRun("var records = [];" | 368 CompileRun("var records = [];" |
| 360 "var obj = {};" | 369 "var obj = {};" |
| 361 "function observer(r) { [].push.apply(records, r); };" | 370 "function observer(r) { [].push.apply(records, r); };" |
| 362 "Object.observe(obj, observer);" | 371 "Object.observe(obj, observer);" |
| 363 "obj")); | 372 "obj")); |
| 364 obj->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("foo"), | 373 obj->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("foo"), |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 {obj, "update", "1", Number::New(v8_isolate, 4)}, | 413 {obj, "update", "1", Number::New(v8_isolate, 4)}, |
| 405 {obj, "add", "1.1", Local<Value>()}, | 414 {obj, "add", "1.1", Local<Value>()}, |
| 406 {obj, "delete", "foo", Number::New(v8_isolate, 3)}, | 415 {obj, "delete", "foo", Number::New(v8_isolate, 3)}, |
| 407 {obj, "delete", "1", Number::New(v8_isolate, 5)}, | 416 {obj, "delete", "1", Number::New(v8_isolate, 5)}, |
| 408 {obj, "delete", "1.1", Number::New(v8_isolate, 6)}}; | 417 {obj, "delete", "1.1", Number::New(v8_isolate, 6)}}; |
| 409 EXPECT_RECORDS(CompileRun("records"), expected_records); | 418 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 410 } | 419 } |
| 411 | 420 |
| 412 | 421 |
| 413 TEST(HiddenPrototypeObservation) { | 422 TEST(HiddenPrototypeObservation) { |
| 423 i::FLAG_harmony_object_observe = true; |
| 414 v8::Isolate* v8_isolate = CcTest::isolate(); | 424 v8::Isolate* v8_isolate = CcTest::isolate(); |
| 415 HandleScope scope(v8_isolate); | 425 HandleScope scope(v8_isolate); |
| 416 LocalContext context(v8_isolate); | 426 LocalContext context(v8_isolate); |
| 417 Local<FunctionTemplate> tmpl = FunctionTemplate::New(v8_isolate); | 427 Local<FunctionTemplate> tmpl = FunctionTemplate::New(v8_isolate); |
| 418 tmpl->SetHiddenPrototype(true); | 428 tmpl->SetHiddenPrototype(true); |
| 419 tmpl->InstanceTemplate()->Set(v8_str("foo"), Number::New(v8_isolate, 75)); | 429 tmpl->InstanceTemplate()->Set(v8_str("foo"), Number::New(v8_isolate, 75)); |
| 420 Local<Function> function = | 430 Local<Function> function = |
| 421 tmpl->GetFunction(v8::Isolate::GetCurrent()->GetCurrentContext()) | 431 tmpl->GetFunction(v8::Isolate::GetCurrent()->GetCurrentContext()) |
| 422 .ToLocalChecked(); | 432 .ToLocalChecked(); |
| 423 Local<Object> proto = | 433 Local<Object> proto = |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 EXPECT_RECORDS(CompileRun("records"), expected_records3); | 476 EXPECT_RECORDS(CompileRun("records"), expected_records3); |
| 467 } | 477 } |
| 468 | 478 |
| 469 | 479 |
| 470 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { | 480 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { |
| 471 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); | 481 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); |
| 472 } | 482 } |
| 473 | 483 |
| 474 | 484 |
| 475 TEST(ObservationWeakMap) { | 485 TEST(ObservationWeakMap) { |
| 486 i::FLAG_harmony_object_observe = true; |
| 476 HandleScope scope(CcTest::isolate()); | 487 HandleScope scope(CcTest::isolate()); |
| 477 LocalContext context(CcTest::isolate()); | 488 LocalContext context(CcTest::isolate()); |
| 478 CompileRun( | 489 CompileRun( |
| 479 "var obj = {};" | 490 "var obj = {};" |
| 480 "Object.observe(obj, function(){});" | 491 "Object.observe(obj, function(){});" |
| 481 "Object.getNotifier(obj);" | 492 "Object.getNotifier(obj);" |
| 482 "obj = null;"); | 493 "obj = null;"); |
| 483 i::Isolate* i_isolate = CcTest::i_isolate(); | 494 i::Isolate* i_isolate = CcTest::i_isolate(); |
| 484 i::Handle<i::JSObject> observation_state = | 495 i::Handle<i::JSObject> observation_state = |
| 485 i_isolate->factory()->observation_state(); | 496 i_isolate->factory()->observation_state(); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 "Array.prototype.splice.call(obj, 1, 2, 2, 4);" | 547 "Array.prototype.splice.call(obj, 1, 2, 2, 4);" |
| 537 "Array.prototype.pop.call(obj);" | 548 "Array.prototype.pop.call(obj);" |
| 538 "Array.prototype.shift.call(obj);"); | 549 "Array.prototype.shift.call(obj);"); |
| 539 } | 550 } |
| 540 } | 551 } |
| 541 return ToInt32(CompileRun("records ? records.length : 0")); | 552 return ToInt32(CompileRun("records ? records.length : 0")); |
| 542 } | 553 } |
| 543 | 554 |
| 544 | 555 |
| 545 TEST(ObserverSecurityAAA) { | 556 TEST(ObserverSecurityAAA) { |
| 557 i::FLAG_harmony_object_observe = true; |
| 546 v8::Isolate* isolate = CcTest::isolate(); | 558 v8::Isolate* isolate = CcTest::isolate(); |
| 547 v8::HandleScope scope(isolate); | 559 v8::HandleScope scope(isolate); |
| 548 v8::Local<Context> contextA = Context::New(isolate); | 560 v8::Local<Context> contextA = Context::New(isolate); |
| 549 CHECK_EQ(8, TestObserveSecurity(contextA, contextA, contextA)); | 561 CHECK_EQ(8, TestObserveSecurity(contextA, contextA, contextA)); |
| 550 } | 562 } |
| 551 | 563 |
| 552 | 564 |
| 553 TEST(ObserverSecurityA1A2A3) { | 565 TEST(ObserverSecurityA1A2A3) { |
| 566 i::FLAG_harmony_object_observe = true; |
| 554 v8::Isolate* isolate = CcTest::isolate(); | 567 v8::Isolate* isolate = CcTest::isolate(); |
| 555 v8::HandleScope scope(isolate); | 568 v8::HandleScope scope(isolate); |
| 556 | 569 |
| 557 v8::Local<Context> contextA1 = Context::New(isolate); | 570 v8::Local<Context> contextA1 = Context::New(isolate); |
| 558 v8::Local<Context> contextA2 = Context::New(isolate); | 571 v8::Local<Context> contextA2 = Context::New(isolate); |
| 559 v8::Local<Context> contextA3 = Context::New(isolate); | 572 v8::Local<Context> contextA3 = Context::New(isolate); |
| 560 | 573 |
| 561 Local<Value> foo = v8_str("foo"); | 574 Local<Value> foo = v8_str("foo"); |
| 562 contextA1->SetSecurityToken(foo); | 575 contextA1->SetSecurityToken(foo); |
| 563 contextA2->SetSecurityToken(foo); | 576 contextA2->SetSecurityToken(foo); |
| 564 contextA3->SetSecurityToken(foo); | 577 contextA3->SetSecurityToken(foo); |
| 565 | 578 |
| 566 CHECK_EQ(8, TestObserveSecurity(contextA1, contextA2, contextA3)); | 579 CHECK_EQ(8, TestObserveSecurity(contextA1, contextA2, contextA3)); |
| 567 } | 580 } |
| 568 | 581 |
| 569 | 582 |
| 570 TEST(ObserverSecurityAAB) { | 583 TEST(ObserverSecurityAAB) { |
| 584 i::FLAG_harmony_object_observe = true; |
| 571 v8::Isolate* isolate = CcTest::isolate(); | 585 v8::Isolate* isolate = CcTest::isolate(); |
| 572 v8::HandleScope scope(isolate); | 586 v8::HandleScope scope(isolate); |
| 573 v8::Local<Context> contextA = Context::New(isolate); | 587 v8::Local<Context> contextA = Context::New(isolate); |
| 574 v8::Local<Context> contextB = Context::New(isolate); | 588 v8::Local<Context> contextB = Context::New(isolate); |
| 575 CHECK_EQ(0, TestObserveSecurity(contextA, contextA, contextB)); | 589 CHECK_EQ(0, TestObserveSecurity(contextA, contextA, contextB)); |
| 576 } | 590 } |
| 577 | 591 |
| 578 | 592 |
| 579 TEST(ObserverSecurityA1A2B) { | 593 TEST(ObserverSecurityA1A2B) { |
| 594 i::FLAG_harmony_object_observe = true; |
| 580 v8::Isolate* isolate = CcTest::isolate(); | 595 v8::Isolate* isolate = CcTest::isolate(); |
| 581 v8::HandleScope scope(isolate); | 596 v8::HandleScope scope(isolate); |
| 582 | 597 |
| 583 v8::Local<Context> contextA1 = Context::New(isolate); | 598 v8::Local<Context> contextA1 = Context::New(isolate); |
| 584 v8::Local<Context> contextA2 = Context::New(isolate); | 599 v8::Local<Context> contextA2 = Context::New(isolate); |
| 585 v8::Local<Context> contextB = Context::New(isolate); | 600 v8::Local<Context> contextB = Context::New(isolate); |
| 586 | 601 |
| 587 Local<Value> foo = v8_str("foo"); | 602 Local<Value> foo = v8_str("foo"); |
| 588 contextA1->SetSecurityToken(foo); | 603 contextA1->SetSecurityToken(foo); |
| 589 contextA2->SetSecurityToken(foo); | 604 contextA2->SetSecurityToken(foo); |
| 590 | 605 |
| 591 CHECK_EQ(0, TestObserveSecurity(contextA1, contextA2, contextB)); | 606 CHECK_EQ(0, TestObserveSecurity(contextA1, contextA2, contextB)); |
| 592 } | 607 } |
| 593 | 608 |
| 594 | 609 |
| 595 TEST(ObserverSecurityABA) { | 610 TEST(ObserverSecurityABA) { |
| 611 i::FLAG_harmony_object_observe = true; |
| 596 v8::Isolate* isolate = CcTest::isolate(); | 612 v8::Isolate* isolate = CcTest::isolate(); |
| 597 v8::HandleScope scope(isolate); | 613 v8::HandleScope scope(isolate); |
| 598 v8::Local<Context> contextA = Context::New(isolate); | 614 v8::Local<Context> contextA = Context::New(isolate); |
| 599 v8::Local<Context> contextB = Context::New(isolate); | 615 v8::Local<Context> contextB = Context::New(isolate); |
| 600 CHECK_EQ(0, TestObserveSecurity(contextA, contextB, contextA)); | 616 CHECK_EQ(0, TestObserveSecurity(contextA, contextB, contextA)); |
| 601 } | 617 } |
| 602 | 618 |
| 603 | 619 |
| 604 TEST(ObserverSecurityA1BA2) { | 620 TEST(ObserverSecurityA1BA2) { |
| 621 i::FLAG_harmony_object_observe = true; |
| 605 v8::Isolate* isolate = CcTest::isolate(); | 622 v8::Isolate* isolate = CcTest::isolate(); |
| 606 v8::HandleScope scope(isolate); | 623 v8::HandleScope scope(isolate); |
| 607 v8::Local<Context> contextA1 = Context::New(isolate); | 624 v8::Local<Context> contextA1 = Context::New(isolate); |
| 608 v8::Local<Context> contextA2 = Context::New(isolate); | 625 v8::Local<Context> contextA2 = Context::New(isolate); |
| 609 v8::Local<Context> contextB = Context::New(isolate); | 626 v8::Local<Context> contextB = Context::New(isolate); |
| 610 | 627 |
| 611 Local<Value> foo = v8_str("foo"); | 628 Local<Value> foo = v8_str("foo"); |
| 612 contextA1->SetSecurityToken(foo); | 629 contextA1->SetSecurityToken(foo); |
| 613 contextA2->SetSecurityToken(foo); | 630 contextA2->SetSecurityToken(foo); |
| 614 | 631 |
| 615 CHECK_EQ(0, TestObserveSecurity(contextA1, contextB, contextA2)); | 632 CHECK_EQ(0, TestObserveSecurity(contextA1, contextB, contextA2)); |
| 616 } | 633 } |
| 617 | 634 |
| 618 | 635 |
| 619 TEST(ObserverSecurityBAA) { | 636 TEST(ObserverSecurityBAA) { |
| 637 i::FLAG_harmony_object_observe = true; |
| 620 v8::Isolate* isolate = CcTest::isolate(); | 638 v8::Isolate* isolate = CcTest::isolate(); |
| 621 v8::HandleScope scope(isolate); | 639 v8::HandleScope scope(isolate); |
| 622 v8::Local<Context> contextA = Context::New(isolate); | 640 v8::Local<Context> contextA = Context::New(isolate); |
| 623 v8::Local<Context> contextB = Context::New(isolate); | 641 v8::Local<Context> contextB = Context::New(isolate); |
| 624 CHECK_EQ(0, TestObserveSecurity(contextB, contextA, contextA)); | 642 CHECK_EQ(0, TestObserveSecurity(contextB, contextA, contextA)); |
| 625 } | 643 } |
| 626 | 644 |
| 627 | 645 |
| 628 TEST(ObserverSecurityBA1A2) { | 646 TEST(ObserverSecurityBA1A2) { |
| 647 i::FLAG_harmony_object_observe = true; |
| 629 v8::Isolate* isolate = CcTest::isolate(); | 648 v8::Isolate* isolate = CcTest::isolate(); |
| 630 v8::HandleScope scope(isolate); | 649 v8::HandleScope scope(isolate); |
| 631 v8::Local<Context> contextA1 = Context::New(isolate); | 650 v8::Local<Context> contextA1 = Context::New(isolate); |
| 632 v8::Local<Context> contextA2 = Context::New(isolate); | 651 v8::Local<Context> contextA2 = Context::New(isolate); |
| 633 v8::Local<Context> contextB = Context::New(isolate); | 652 v8::Local<Context> contextB = Context::New(isolate); |
| 634 | 653 |
| 635 Local<Value> foo = v8_str("foo"); | 654 Local<Value> foo = v8_str("foo"); |
| 636 contextA1->SetSecurityToken(foo); | 655 contextA1->SetSecurityToken(foo); |
| 637 contextA2->SetSecurityToken(foo); | 656 contextA2->SetSecurityToken(foo); |
| 638 | 657 |
| 639 CHECK_EQ(0, TestObserveSecurity(contextB, contextA1, contextA2)); | 658 CHECK_EQ(0, TestObserveSecurity(contextB, contextA1, contextA2)); |
| 640 } | 659 } |
| 641 | 660 |
| 642 | 661 |
| 643 TEST(ObserverSecurityNotify) { | 662 TEST(ObserverSecurityNotify) { |
| 663 i::FLAG_harmony_object_observe = true; |
| 644 v8::Isolate* isolate = CcTest::isolate(); | 664 v8::Isolate* isolate = CcTest::isolate(); |
| 645 v8::HandleScope scope(isolate); | 665 v8::HandleScope scope(isolate); |
| 646 v8::Local<Context> contextA = Context::New(isolate); | 666 v8::Local<Context> contextA = Context::New(isolate); |
| 647 v8::Local<Context> contextB = Context::New(isolate); | 667 v8::Local<Context> contextB = Context::New(isolate); |
| 648 | 668 |
| 649 Context::Scope scopeA(contextA); | 669 Context::Scope scopeA(contextA); |
| 650 CompileRun("var obj = {};" | 670 CompileRun("var obj = {};" |
| 651 "var recordsA = null;" | 671 "var recordsA = null;" |
| 652 "var observerA = function(r) { recordsA = r };" | 672 "var observerA = function(r) { recordsA = r };" |
| 653 "Object.observe(obj, observerA);"); | 673 "Object.observe(obj, observerA);"); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 669 CHECK_EQ(1, ToInt32(CompileRun("recordsA ? recordsA.length : 0"))); | 689 CHECK_EQ(1, ToInt32(CompileRun("recordsA ? recordsA.length : 0"))); |
| 670 | 690 |
| 671 { | 691 { |
| 672 Context::Scope scopeB(contextB); | 692 Context::Scope scopeB(contextB); |
| 673 CHECK_EQ(0, ToInt32(CompileRun("recordsB ? recordsB.length : 0"))); | 693 CHECK_EQ(0, ToInt32(CompileRun("recordsB ? recordsB.length : 0"))); |
| 674 } | 694 } |
| 675 } | 695 } |
| 676 | 696 |
| 677 | 697 |
| 678 TEST(HiddenPropertiesLeakage) { | 698 TEST(HiddenPropertiesLeakage) { |
| 699 i::FLAG_harmony_object_observe = true; |
| 679 HandleScope scope(CcTest::isolate()); | 700 HandleScope scope(CcTest::isolate()); |
| 680 LocalContext context(CcTest::isolate()); | 701 LocalContext context(CcTest::isolate()); |
| 681 CompileRun("var obj = {};" | 702 CompileRun("var obj = {};" |
| 682 "var records = null;" | 703 "var records = null;" |
| 683 "var observer = function(r) { records = r };" | 704 "var observer = function(r) { records = r };" |
| 684 "Object.observe(obj, observer);"); | 705 "Object.observe(obj, observer);"); |
| 685 Local<Value> obj = | 706 Local<Value> obj = |
| 686 context->Global() | 707 context->Global() |
| 687 ->Get(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj")) | 708 ->Get(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj")) |
| 688 .ToLocalChecked(); | 709 .ToLocalChecked(); |
| 689 Local<Object>::Cast(obj) | 710 Local<Object>::Cast(obj) |
| 690 ->SetPrivate(v8::Isolate::GetCurrent()->GetCurrentContext(), | 711 ->SetPrivate(v8::Isolate::GetCurrent()->GetCurrentContext(), |
| 691 v8::Private::New(CcTest::isolate(), v8_str("foo")), | 712 v8::Private::New(CcTest::isolate(), v8_str("foo")), |
| 692 Null(CcTest::isolate())) | 713 Null(CcTest::isolate())) |
| 693 .FromJust(); | 714 .FromJust(); |
| 694 CompileRun(""); // trigger delivery | 715 CompileRun(""); // trigger delivery |
| 695 CHECK(CompileRun("records")->IsNull()); | 716 CHECK(CompileRun("records")->IsNull()); |
| 696 } | 717 } |
| 697 | 718 |
| 698 | 719 |
| 699 TEST(GetNotifierFromOtherContext) { | 720 TEST(GetNotifierFromOtherContext) { |
| 721 i::FLAG_harmony_object_observe = true; |
| 700 HandleScope scope(CcTest::isolate()); | 722 HandleScope scope(CcTest::isolate()); |
| 701 LocalContext context(CcTest::isolate()); | 723 LocalContext context(CcTest::isolate()); |
| 702 CompileRun("var obj = {};"); | 724 CompileRun("var obj = {};"); |
| 703 Local<Value> instance = CompileRun("obj"); | 725 Local<Value> instance = CompileRun("obj"); |
| 704 { | 726 { |
| 705 LocalContext context2(CcTest::isolate()); | 727 LocalContext context2(CcTest::isolate()); |
| 706 context2->Global() | 728 context2->Global() |
| 707 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), | 729 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), |
| 708 instance) | 730 instance) |
| 709 .FromJust(); | 731 .FromJust(); |
| 710 CHECK(CompileRun("Object.getNotifier(obj)")->IsNull()); | 732 CHECK(CompileRun("Object.getNotifier(obj)")->IsNull()); |
| 711 } | 733 } |
| 712 } | 734 } |
| 713 | 735 |
| 714 | 736 |
| 715 TEST(GetNotifierFromOtherOrigin) { | 737 TEST(GetNotifierFromOtherOrigin) { |
| 738 i::FLAG_harmony_object_observe = true; |
| 716 HandleScope scope(CcTest::isolate()); | 739 HandleScope scope(CcTest::isolate()); |
| 717 Local<Value> foo = v8_str("foo"); | 740 Local<Value> foo = v8_str("foo"); |
| 718 Local<Value> bar = v8_str("bar"); | 741 Local<Value> bar = v8_str("bar"); |
| 719 LocalContext context(CcTest::isolate()); | 742 LocalContext context(CcTest::isolate()); |
| 720 context->SetSecurityToken(foo); | 743 context->SetSecurityToken(foo); |
| 721 CompileRun("var obj = {};"); | 744 CompileRun("var obj = {};"); |
| 722 Local<Value> instance = CompileRun("obj"); | 745 Local<Value> instance = CompileRun("obj"); |
| 723 { | 746 { |
| 724 LocalContext context2(CcTest::isolate()); | 747 LocalContext context2(CcTest::isolate()); |
| 725 context2->SetSecurityToken(bar); | 748 context2->SetSecurityToken(bar); |
| 726 context2->Global() | 749 context2->Global() |
| 727 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), | 750 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), |
| 728 instance) | 751 instance) |
| 729 .FromJust(); | 752 .FromJust(); |
| 730 CHECK(CompileRun("Object.getNotifier(obj)")->IsNull()); | 753 CHECK(CompileRun("Object.getNotifier(obj)")->IsNull()); |
| 731 } | 754 } |
| 732 } | 755 } |
| 733 | 756 |
| 734 | 757 |
| 735 TEST(GetNotifierFromSameOrigin) { | 758 TEST(GetNotifierFromSameOrigin) { |
| 759 i::FLAG_harmony_object_observe = true; |
| 736 HandleScope scope(CcTest::isolate()); | 760 HandleScope scope(CcTest::isolate()); |
| 737 Local<Value> foo = v8_str("foo"); | 761 Local<Value> foo = v8_str("foo"); |
| 738 LocalContext context(CcTest::isolate()); | 762 LocalContext context(CcTest::isolate()); |
| 739 context->SetSecurityToken(foo); | 763 context->SetSecurityToken(foo); |
| 740 CompileRun("var obj = {};"); | 764 CompileRun("var obj = {};"); |
| 741 Local<Value> instance = CompileRun("obj"); | 765 Local<Value> instance = CompileRun("obj"); |
| 742 { | 766 { |
| 743 LocalContext context2(CcTest::isolate()); | 767 LocalContext context2(CcTest::isolate()); |
| 744 context2->SetSecurityToken(foo); | 768 context2->SetSecurityToken(foo); |
| 745 context2->Global() | 769 context2->Global() |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 777 CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); | 801 CcTest::heap()->CollectAllGarbage(i::Heap::kMakeHeapIterableMask); |
| 778 int count = GetGlobalObjectsCount(); | 802 int count = GetGlobalObjectsCount(); |
| 779 #ifdef DEBUG | 803 #ifdef DEBUG |
| 780 if (count != expected) CcTest::heap()->TracePathToGlobal(); | 804 if (count != expected) CcTest::heap()->TracePathToGlobal(); |
| 781 #endif | 805 #endif |
| 782 CHECK_EQ(expected, count); | 806 CHECK_EQ(expected, count); |
| 783 } | 807 } |
| 784 | 808 |
| 785 | 809 |
| 786 TEST(DontLeakContextOnObserve) { | 810 TEST(DontLeakContextOnObserve) { |
| 811 i::FLAG_harmony_object_observe = true; |
| 787 HandleScope scope(CcTest::isolate()); | 812 HandleScope scope(CcTest::isolate()); |
| 788 Local<Value> foo = v8_str("foo"); | 813 Local<Value> foo = v8_str("foo"); |
| 789 LocalContext context(CcTest::isolate()); | 814 LocalContext context(CcTest::isolate()); |
| 790 context->SetSecurityToken(foo); | 815 context->SetSecurityToken(foo); |
| 791 CompileRun("var obj = {};"); | 816 CompileRun("var obj = {};"); |
| 792 Local<Value> object = CompileRun("obj"); | 817 Local<Value> object = CompileRun("obj"); |
| 793 { | 818 { |
| 794 HandleScope scope(CcTest::isolate()); | 819 HandleScope scope(CcTest::isolate()); |
| 795 LocalContext context2(CcTest::isolate()); | 820 LocalContext context2(CcTest::isolate()); |
| 796 context2->SetSecurityToken(foo); | 821 context2->SetSecurityToken(foo); |
| 797 context2->Global() | 822 context2->Global() |
| 798 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), | 823 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), |
| 799 object) | 824 object) |
| 800 .FromJust(); | 825 .FromJust(); |
| 801 CompileRun("function observer() {};" | 826 CompileRun("function observer() {};" |
| 802 "Object.observe(obj, observer, ['foo', 'bar', 'baz']);" | 827 "Object.observe(obj, observer, ['foo', 'bar', 'baz']);" |
| 803 "Object.unobserve(obj, observer);"); | 828 "Object.unobserve(obj, observer);"); |
| 804 } | 829 } |
| 805 | 830 |
| 806 CcTest::isolate()->ContextDisposedNotification(); | 831 CcTest::isolate()->ContextDisposedNotification(); |
| 807 CheckSurvivingGlobalObjectsCount(0); | 832 CheckSurvivingGlobalObjectsCount(0); |
| 808 } | 833 } |
| 809 | 834 |
| 810 | 835 |
| 811 TEST(DontLeakContextOnGetNotifier) { | 836 TEST(DontLeakContextOnGetNotifier) { |
| 837 i::FLAG_harmony_object_observe = true; |
| 812 HandleScope scope(CcTest::isolate()); | 838 HandleScope scope(CcTest::isolate()); |
| 813 Local<Value> foo = v8_str("foo"); | 839 Local<Value> foo = v8_str("foo"); |
| 814 LocalContext context(CcTest::isolate()); | 840 LocalContext context(CcTest::isolate()); |
| 815 context->SetSecurityToken(foo); | 841 context->SetSecurityToken(foo); |
| 816 CompileRun("var obj = {};"); | 842 CompileRun("var obj = {};"); |
| 817 Local<Value> object = CompileRun("obj"); | 843 Local<Value> object = CompileRun("obj"); |
| 818 { | 844 { |
| 819 HandleScope scope(CcTest::isolate()); | 845 HandleScope scope(CcTest::isolate()); |
| 820 LocalContext context2(CcTest::isolate()); | 846 LocalContext context2(CcTest::isolate()); |
| 821 context2->SetSecurityToken(foo); | 847 context2->SetSecurityToken(foo); |
| 822 context2->Global() | 848 context2->Global() |
| 823 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), | 849 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), |
| 824 object) | 850 object) |
| 825 .FromJust(); | 851 .FromJust(); |
| 826 CompileRun("Object.getNotifier(obj);"); | 852 CompileRun("Object.getNotifier(obj);"); |
| 827 } | 853 } |
| 828 | 854 |
| 829 CcTest::isolate()->ContextDisposedNotification(); | 855 CcTest::isolate()->ContextDisposedNotification(); |
| 830 CheckSurvivingGlobalObjectsCount(0); | 856 CheckSurvivingGlobalObjectsCount(0); |
| 831 } | 857 } |
| 832 | 858 |
| 833 | 859 |
| 834 TEST(DontLeakContextOnNotifierPerformChange) { | 860 TEST(DontLeakContextOnNotifierPerformChange) { |
| 861 i::FLAG_harmony_object_observe = true; |
| 835 HandleScope scope(CcTest::isolate()); | 862 HandleScope scope(CcTest::isolate()); |
| 836 Local<Value> foo = v8_str("foo"); | 863 Local<Value> foo = v8_str("foo"); |
| 837 LocalContext context(CcTest::isolate()); | 864 LocalContext context(CcTest::isolate()); |
| 838 context->SetSecurityToken(foo); | 865 context->SetSecurityToken(foo); |
| 839 CompileRun("var obj = {};"); | 866 CompileRun("var obj = {};"); |
| 840 Local<Value> object = CompileRun("obj"); | 867 Local<Value> object = CompileRun("obj"); |
| 841 Local<Value> notifier = CompileRun("Object.getNotifier(obj)"); | 868 Local<Value> notifier = CompileRun("Object.getNotifier(obj)"); |
| 842 { | 869 { |
| 843 HandleScope scope(CcTest::isolate()); | 870 HandleScope scope(CcTest::isolate()); |
| 844 LocalContext context2(CcTest::isolate()); | 871 LocalContext context2(CcTest::isolate()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 862 } | 889 } |
| 863 | 890 |
| 864 | 891 |
| 865 static void ObserverCallback(const FunctionCallbackInfo<Value>& args) { | 892 static void ObserverCallback(const FunctionCallbackInfo<Value>& args) { |
| 866 *static_cast<int*>(Local<External>::Cast(args.Data())->Value()) = | 893 *static_cast<int*>(Local<External>::Cast(args.Data())->Value()) = |
| 867 Local<Array>::Cast(args[0])->Length(); | 894 Local<Array>::Cast(args[0])->Length(); |
| 868 } | 895 } |
| 869 | 896 |
| 870 | 897 |
| 871 TEST(ObjectObserveCallsCppFunction) { | 898 TEST(ObjectObserveCallsCppFunction) { |
| 899 i::FLAG_harmony_object_observe = true; |
| 872 Isolate* isolate = CcTest::isolate(); | 900 Isolate* isolate = CcTest::isolate(); |
| 873 HandleScope scope(isolate); | 901 HandleScope scope(isolate); |
| 874 LocalContext context(isolate); | 902 LocalContext context(isolate); |
| 875 int numRecordsSent = 0; | 903 int numRecordsSent = 0; |
| 876 Local<Function> observer = | 904 Local<Function> observer = |
| 877 Function::New(CcTest::isolate()->GetCurrentContext(), ObserverCallback, | 905 Function::New(CcTest::isolate()->GetCurrentContext(), ObserverCallback, |
| 878 External::New(isolate, &numRecordsSent)) | 906 External::New(isolate, &numRecordsSent)) |
| 879 .ToLocalChecked(); | 907 .ToLocalChecked(); |
| 880 context->Global() | 908 context->Global() |
| 881 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("observer"), | 909 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("observer"), |
| 882 observer) | 910 observer) |
| 883 .FromJust(); | 911 .FromJust(); |
| 884 CompileRun( | 912 CompileRun( |
| 885 "var obj = {};" | 913 "var obj = {};" |
| 886 "Object.observe(obj, observer);" | 914 "Object.observe(obj, observer);" |
| 887 "obj.foo = 1;" | 915 "obj.foo = 1;" |
| 888 "obj.bar = 2;"); | 916 "obj.bar = 2;"); |
| 889 CHECK_EQ(2, numRecordsSent); | 917 CHECK_EQ(2, numRecordsSent); |
| 890 } | 918 } |
| 891 | 919 |
| 892 | 920 |
| 893 TEST(ObjectObserveCallsFunctionTemplateInstance) { | 921 TEST(ObjectObserveCallsFunctionTemplateInstance) { |
| 922 i::FLAG_harmony_object_observe = true; |
| 894 Isolate* isolate = CcTest::isolate(); | 923 Isolate* isolate = CcTest::isolate(); |
| 895 HandleScope scope(isolate); | 924 HandleScope scope(isolate); |
| 896 LocalContext context(isolate); | 925 LocalContext context(isolate); |
| 897 int numRecordsSent = 0; | 926 int numRecordsSent = 0; |
| 898 Local<FunctionTemplate> tmpl = FunctionTemplate::New( | 927 Local<FunctionTemplate> tmpl = FunctionTemplate::New( |
| 899 isolate, ObserverCallback, External::New(isolate, &numRecordsSent)); | 928 isolate, ObserverCallback, External::New(isolate, &numRecordsSent)); |
| 900 Local<Function> function = | 929 Local<Function> function = |
| 901 tmpl->GetFunction(v8::Isolate::GetCurrent()->GetCurrentContext()) | 930 tmpl->GetFunction(v8::Isolate::GetCurrent()->GetCurrentContext()) |
| 902 .ToLocalChecked(); | 931 .ToLocalChecked(); |
| 903 context->Global() | 932 context->Global() |
| (...skipping 15 matching lines...) Expand all Loading... |
| 919 } | 948 } |
| 920 | 949 |
| 921 | 950 |
| 922 static void AccessorSetter(Local<Name> property, Local<Value> value, | 951 static void AccessorSetter(Local<Name> property, Local<Value> value, |
| 923 const PropertyCallbackInfo<void>& info) { | 952 const PropertyCallbackInfo<void>& info) { |
| 924 info.GetReturnValue().SetUndefined(); | 953 info.GetReturnValue().SetUndefined(); |
| 925 } | 954 } |
| 926 | 955 |
| 927 | 956 |
| 928 TEST(APIAccessorsShouldNotNotify) { | 957 TEST(APIAccessorsShouldNotNotify) { |
| 958 i::FLAG_harmony_object_observe = true; |
| 929 Isolate* isolate = CcTest::isolate(); | 959 Isolate* isolate = CcTest::isolate(); |
| 930 HandleScope handle_scope(isolate); | 960 HandleScope handle_scope(isolate); |
| 931 LocalContext context(isolate); | 961 LocalContext context(isolate); |
| 932 Local<Object> object = Object::New(isolate); | 962 Local<Object> object = Object::New(isolate); |
| 933 object->SetAccessor(v8::Isolate::GetCurrent()->GetCurrentContext(), | 963 object->SetAccessor(v8::Isolate::GetCurrent()->GetCurrentContext(), |
| 934 v8_str("accessor"), &AccessorGetter, &AccessorSetter) | 964 v8_str("accessor"), &AccessorGetter, &AccessorSetter) |
| 935 .FromJust(); | 965 .FromJust(); |
| 936 context->Global() | 966 context->Global() |
| 937 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), | 967 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), |
| 938 object) | 968 object) |
| (...skipping 13 matching lines...) Expand all Loading... |
| 952 int* global_use_counts = NULL; | 982 int* global_use_counts = NULL; |
| 953 | 983 |
| 954 void MockUseCounterCallback(v8::Isolate* isolate, | 984 void MockUseCounterCallback(v8::Isolate* isolate, |
| 955 v8::Isolate::UseCounterFeature feature) { | 985 v8::Isolate::UseCounterFeature feature) { |
| 956 ++global_use_counts[feature]; | 986 ++global_use_counts[feature]; |
| 957 } | 987 } |
| 958 } | 988 } |
| 959 | 989 |
| 960 | 990 |
| 961 TEST(UseCountObjectObserve) { | 991 TEST(UseCountObjectObserve) { |
| 992 i::FLAG_harmony_object_observe = true; |
| 962 i::Isolate* isolate = CcTest::i_isolate(); | 993 i::Isolate* isolate = CcTest::i_isolate(); |
| 963 i::HandleScope scope(isolate); | 994 i::HandleScope scope(isolate); |
| 964 LocalContext env; | 995 LocalContext env; |
| 965 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; | 996 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; |
| 966 global_use_counts = use_counts; | 997 global_use_counts = use_counts; |
| 967 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); | 998 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); |
| 968 CompileRun( | 999 CompileRun( |
| 969 "var obj = {};" | 1000 "var obj = {};" |
| 970 "Object.observe(obj, function(){})"); | 1001 "Object.observe(obj, function(){})"); |
| 971 CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); | 1002 CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); |
| 972 CompileRun( | 1003 CompileRun( |
| 973 "var obj2 = {};" | 1004 "var obj2 = {};" |
| 974 "Object.observe(obj2, function(){})"); | 1005 "Object.observe(obj2, function(){})"); |
| 975 // Only counts the first use of observe in a given context. | 1006 // Only counts the first use of observe in a given context. |
| 976 CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); | 1007 CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); |
| 977 { | 1008 { |
| 978 LocalContext env2; | 1009 LocalContext env2; |
| 979 CompileRun( | 1010 CompileRun( |
| 980 "var obj = {};" | 1011 "var obj = {};" |
| 981 "Object.observe(obj, function(){})"); | 1012 "Object.observe(obj, function(){})"); |
| 982 } | 1013 } |
| 983 // Counts different contexts separately. | 1014 // Counts different contexts separately. |
| 984 CHECK_EQ(2, use_counts[v8::Isolate::kObjectObserve]); | 1015 CHECK_EQ(2, use_counts[v8::Isolate::kObjectObserve]); |
| 985 } | 1016 } |
| 986 | 1017 |
| 987 | 1018 |
| 988 TEST(UseCountObjectGetNotifier) { | 1019 TEST(UseCountObjectGetNotifier) { |
| 1020 i::FLAG_harmony_object_observe = true; |
| 989 i::Isolate* isolate = CcTest::i_isolate(); | 1021 i::Isolate* isolate = CcTest::i_isolate(); |
| 990 i::HandleScope scope(isolate); | 1022 i::HandleScope scope(isolate); |
| 991 LocalContext env; | 1023 LocalContext env; |
| 992 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; | 1024 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; |
| 993 global_use_counts = use_counts; | 1025 global_use_counts = use_counts; |
| 994 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); | 1026 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); |
| 995 CompileRun("var obj = {}"); | 1027 CompileRun("var obj = {}"); |
| 996 CompileRun("Object.getNotifier(obj)"); | 1028 CompileRun("Object.getNotifier(obj)"); |
| 997 CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); | 1029 CHECK_EQ(1, use_counts[v8::Isolate::kObjectObserve]); |
| 998 } | 1030 } |
| 999 | 1031 |
| 1000 | 1032 |
| 1001 static bool NamedAccessCheckAlwaysAllow(Local<v8::Context> accessing_context, | 1033 static bool NamedAccessCheckAlwaysAllow(Local<v8::Context> accessing_context, |
| 1002 Local<v8::Object> accessed_object) { | 1034 Local<v8::Object> accessed_object) { |
| 1003 return true; | 1035 return true; |
| 1004 } | 1036 } |
| 1005 | 1037 |
| 1006 | 1038 |
| 1007 TEST(DisallowObserveAccessCheckedObject) { | 1039 TEST(DisallowObserveAccessCheckedObject) { |
| 1040 i::FLAG_harmony_object_observe = true; |
| 1008 v8::Isolate* isolate = CcTest::isolate(); | 1041 v8::Isolate* isolate = CcTest::isolate(); |
| 1009 v8::HandleScope scope(isolate); | 1042 v8::HandleScope scope(isolate); |
| 1010 LocalContext env; | 1043 LocalContext env; |
| 1011 v8::Local<v8::ObjectTemplate> object_template = | 1044 v8::Local<v8::ObjectTemplate> object_template = |
| 1012 v8::ObjectTemplate::New(isolate); | 1045 v8::ObjectTemplate::New(isolate); |
| 1013 object_template->SetAccessCheckCallback(NamedAccessCheckAlwaysAllow); | 1046 object_template->SetAccessCheckCallback(NamedAccessCheckAlwaysAllow); |
| 1014 Local<Object> new_instance = | 1047 Local<Object> new_instance = |
| 1015 object_template->NewInstance( | 1048 object_template->NewInstance( |
| 1016 v8::Isolate::GetCurrent()->GetCurrentContext()) | 1049 v8::Isolate::GetCurrent()->GetCurrentContext()) |
| 1017 .ToLocalChecked(); | 1050 .ToLocalChecked(); |
| 1018 env->Global() | 1051 env->Global() |
| 1019 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), | 1052 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), |
| 1020 new_instance) | 1053 new_instance) |
| 1021 .FromJust(); | 1054 .FromJust(); |
| 1022 v8::TryCatch try_catch(isolate); | 1055 v8::TryCatch try_catch(isolate); |
| 1023 CompileRun("Object.observe(obj, function(){})"); | 1056 CompileRun("Object.observe(obj, function(){})"); |
| 1024 CHECK(try_catch.HasCaught()); | 1057 CHECK(try_catch.HasCaught()); |
| 1025 } | 1058 } |
| 1026 | 1059 |
| 1027 | 1060 |
| 1028 TEST(DisallowGetNotifierAccessCheckedObject) { | 1061 TEST(DisallowGetNotifierAccessCheckedObject) { |
| 1062 i::FLAG_harmony_object_observe = true; |
| 1029 v8::Isolate* isolate = CcTest::isolate(); | 1063 v8::Isolate* isolate = CcTest::isolate(); |
| 1030 v8::HandleScope scope(isolate); | 1064 v8::HandleScope scope(isolate); |
| 1031 LocalContext env; | 1065 LocalContext env; |
| 1032 v8::Local<v8::ObjectTemplate> object_template = | 1066 v8::Local<v8::ObjectTemplate> object_template = |
| 1033 v8::ObjectTemplate::New(isolate); | 1067 v8::ObjectTemplate::New(isolate); |
| 1034 object_template->SetAccessCheckCallback(NamedAccessCheckAlwaysAllow); | 1068 object_template->SetAccessCheckCallback(NamedAccessCheckAlwaysAllow); |
| 1035 Local<Object> new_instance = | 1069 Local<Object> new_instance = |
| 1036 object_template->NewInstance( | 1070 object_template->NewInstance( |
| 1037 v8::Isolate::GetCurrent()->GetCurrentContext()) | 1071 v8::Isolate::GetCurrent()->GetCurrentContext()) |
| 1038 .ToLocalChecked(); | 1072 .ToLocalChecked(); |
| 1039 env->Global() | 1073 env->Global() |
| 1040 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), | 1074 ->Set(v8::Isolate::GetCurrent()->GetCurrentContext(), v8_str("obj"), |
| 1041 new_instance) | 1075 new_instance) |
| 1042 .FromJust(); | 1076 .FromJust(); |
| 1043 v8::TryCatch try_catch(isolate); | 1077 v8::TryCatch try_catch(isolate); |
| 1044 CompileRun("Object.getNotifier(obj)"); | 1078 CompileRun("Object.getNotifier(obj)"); |
| 1045 CHECK(try_catch.HasCaught()); | 1079 CHECK(try_catch.HasCaught()); |
| 1046 } | 1080 } |
| OLD | NEW |