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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 | 51 |
52 private: | 52 private: |
53 Isolate* isolate_; | 53 Isolate* isolate_; |
54 }; | 54 }; |
55 } | 55 } |
56 | 56 |
57 | 57 |
58 TEST(PerIsolateState) { | 58 TEST(PerIsolateState) { |
59 HarmonyIsolate isolate; | 59 HarmonyIsolate isolate; |
60 HandleScope scope(isolate.GetIsolate()); | 60 HandleScope scope(isolate.GetIsolate()); |
61 LocalContext context1; | 61 LocalContext context1(isolate.GetIsolate()); |
62 CompileRun( | 62 CompileRun( |
63 "var count = 0;" | 63 "var count = 0;" |
64 "var calls = 0;" | 64 "var calls = 0;" |
65 "var observer = function(records) { count = records.length; calls++ };" | 65 "var observer = function(records) { count = records.length; calls++ };" |
66 "var obj = {};" | 66 "var obj = {};" |
67 "Object.observe(obj, observer);"); | 67 "Object.observe(obj, observer);"); |
68 Handle<Value> observer = CompileRun("observer"); | 68 Handle<Value> observer = CompileRun("observer"); |
69 Handle<Value> obj = CompileRun("obj"); | 69 Handle<Value> obj = CompileRun("obj"); |
70 Handle<Value> notify_fun1 = CompileRun( | 70 Handle<Value> notify_fun1 = CompileRun( |
71 "(function() { obj.foo = 'bar'; })"); | 71 "(function() { obj.foo = 'bar'; })"); |
72 Handle<Value> notify_fun2; | 72 Handle<Value> notify_fun2; |
73 { | 73 { |
74 LocalContext context2; | 74 LocalContext context2(isolate.GetIsolate()); |
75 context2->Global()->Set(String::New("obj"), obj); | 75 context2->Global()->Set(String::New("obj"), obj); |
76 notify_fun2 = CompileRun( | 76 notify_fun2 = CompileRun( |
77 "(function() { obj.foo = 'baz'; })"); | 77 "(function() { obj.foo = 'baz'; })"); |
78 } | 78 } |
79 Handle<Value> notify_fun3; | 79 Handle<Value> notify_fun3; |
80 { | 80 { |
81 LocalContext context3; | 81 LocalContext context3(isolate.GetIsolate()); |
82 context3->Global()->Set(String::New("obj"), obj); | 82 context3->Global()->Set(String::New("obj"), obj); |
83 notify_fun3 = CompileRun( | 83 notify_fun3 = CompileRun( |
84 "(function() { obj.foo = 'bat'; })"); | 84 "(function() { obj.foo = 'bat'; })"); |
85 } | 85 } |
86 { | 86 { |
87 LocalContext context4; | 87 LocalContext context4(isolate.GetIsolate()); |
88 context4->Global()->Set(String::New("observer"), observer); | 88 context4->Global()->Set(String::New("observer"), observer); |
89 context4->Global()->Set(String::New("fun1"), notify_fun1); | 89 context4->Global()->Set(String::New("fun1"), notify_fun1); |
90 context4->Global()->Set(String::New("fun2"), notify_fun2); | 90 context4->Global()->Set(String::New("fun2"), notify_fun2); |
91 context4->Global()->Set(String::New("fun3"), notify_fun3); | 91 context4->Global()->Set(String::New("fun3"), notify_fun3); |
92 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); | 92 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); |
93 } | 93 } |
94 CHECK_EQ(1, CompileRun("calls")->Int32Value()); | 94 CHECK_EQ(1, CompileRun("calls")->Int32Value()); |
95 CHECK_EQ(3, CompileRun("count")->Int32Value()); | 95 CHECK_EQ(3, CompileRun("count")->Int32Value()); |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 TEST(EndOfMicrotaskDelivery) { | 99 TEST(EndOfMicrotaskDelivery) { |
100 HarmonyIsolate isolate; | 100 HarmonyIsolate isolate; |
101 HandleScope scope(isolate.GetIsolate()); | 101 HandleScope scope(isolate.GetIsolate()); |
102 LocalContext context; | 102 LocalContext context(isolate.GetIsolate()); |
103 CompileRun( | 103 CompileRun( |
104 "var obj = {};" | 104 "var obj = {};" |
105 "var count = 0;" | 105 "var count = 0;" |
106 "var observer = function(records) { count = records.length };" | 106 "var observer = function(records) { count = records.length };" |
107 "Object.observe(obj, observer);" | 107 "Object.observe(obj, observer);" |
108 "obj.foo = 'bar';"); | 108 "obj.foo = 'bar';"); |
109 CHECK_EQ(1, CompileRun("count")->Int32Value()); | 109 CHECK_EQ(1, CompileRun("count")->Int32Value()); |
110 } | 110 } |
111 | 111 |
112 | 112 |
113 TEST(DeliveryOrdering) { | 113 TEST(DeliveryOrdering) { |
114 HarmonyIsolate isolate; | 114 HarmonyIsolate isolate; |
115 HandleScope scope(isolate.GetIsolate()); | 115 HandleScope scope(isolate.GetIsolate()); |
116 LocalContext context; | 116 LocalContext context(isolate.GetIsolate()); |
117 CompileRun( | 117 CompileRun( |
118 "var obj1 = {};" | 118 "var obj1 = {};" |
119 "var obj2 = {};" | 119 "var obj2 = {};" |
120 "var ordering = [];" | 120 "var ordering = [];" |
121 "function observer2() { ordering.push(2); };" | 121 "function observer2() { ordering.push(2); };" |
122 "function observer1() { ordering.push(1); };" | 122 "function observer1() { ordering.push(1); };" |
123 "function observer3() { ordering.push(3); };" | 123 "function observer3() { ordering.push(3); };" |
124 "Object.observe(obj1, observer1);" | 124 "Object.observe(obj1, observer1);" |
125 "Object.observe(obj1, observer2);" | 125 "Object.observe(obj1, observer2);" |
126 "Object.observe(obj1, observer3);" | 126 "Object.observe(obj1, observer3);" |
(...skipping 11 matching lines...) Expand all Loading... |
138 CHECK_EQ(3, CompileRun("ordering.length")->Int32Value()); | 138 CHECK_EQ(3, CompileRun("ordering.length")->Int32Value()); |
139 CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); | 139 CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); |
140 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); | 140 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
141 CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); | 141 CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); |
142 } | 142 } |
143 | 143 |
144 | 144 |
145 TEST(DeliveryOrderingReentrant) { | 145 TEST(DeliveryOrderingReentrant) { |
146 HarmonyIsolate isolate; | 146 HarmonyIsolate isolate; |
147 HandleScope scope(isolate.GetIsolate()); | 147 HandleScope scope(isolate.GetIsolate()); |
148 LocalContext context; | 148 LocalContext context(isolate.GetIsolate()); |
149 CompileRun( | 149 CompileRun( |
150 "var obj = {};" | 150 "var obj = {};" |
151 "var reentered = false;" | 151 "var reentered = false;" |
152 "var ordering = [];" | 152 "var ordering = [];" |
153 "function observer1() { ordering.push(1); };" | 153 "function observer1() { ordering.push(1); };" |
154 "function observer2() {" | 154 "function observer2() {" |
155 " if (!reentered) {" | 155 " if (!reentered) {" |
156 " obj.foo = 'baz';" | 156 " obj.foo = 'baz';" |
157 " reentered = true;" | 157 " reentered = true;" |
158 " }" | 158 " }" |
(...skipping 11 matching lines...) Expand all Loading... |
170 // Note that we re-deliver to observers 1 and 2, while observer3 | 170 // Note that we re-deliver to observers 1 and 2, while observer3 |
171 // already received the second record during the first round. | 171 // already received the second record during the first round. |
172 CHECK_EQ(1, CompileRun("ordering[3]")->Int32Value()); | 172 CHECK_EQ(1, CompileRun("ordering[3]")->Int32Value()); |
173 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); | 173 CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
174 } | 174 } |
175 | 175 |
176 | 176 |
177 TEST(DeliveryOrderingDeliverChangeRecords) { | 177 TEST(DeliveryOrderingDeliverChangeRecords) { |
178 HarmonyIsolate isolate; | 178 HarmonyIsolate isolate; |
179 HandleScope scope(isolate.GetIsolate()); | 179 HandleScope scope(isolate.GetIsolate()); |
180 LocalContext context; | 180 LocalContext context(isolate.GetIsolate()); |
181 CompileRun( | 181 CompileRun( |
182 "var obj = {};" | 182 "var obj = {};" |
183 "var ordering = [];" | 183 "var ordering = [];" |
184 "function observer1() { ordering.push(1); if (!obj.b) obj.b = true };" | 184 "function observer1() { ordering.push(1); if (!obj.b) obj.b = true };" |
185 "function observer2() { ordering.push(2); };" | 185 "function observer2() { ordering.push(2); };" |
186 "Object.observe(obj, observer1);" | 186 "Object.observe(obj, observer1);" |
187 "Object.observe(obj, observer2);" | 187 "Object.observe(obj, observer2);" |
188 "obj.a = 1;" | 188 "obj.a = 1;" |
189 "Object.deliverChangeRecords(observer2);"); | 189 "Object.deliverChangeRecords(observer2);"); |
190 CHECK_EQ(4, CompileRun("ordering.length")->Int32Value()); | 190 CHECK_EQ(4, CompileRun("ordering.length")->Int32Value()); |
191 // First, observer2 is called due to deliverChangeRecords | 191 // First, observer2 is called due to deliverChangeRecords |
192 CHECK_EQ(2, CompileRun("ordering[0]")->Int32Value()); | 192 CHECK_EQ(2, CompileRun("ordering[0]")->Int32Value()); |
193 // Then, observer1 is called when the stack unwinds | 193 // Then, observer1 is called when the stack unwinds |
194 CHECK_EQ(1, CompileRun("ordering[1]")->Int32Value()); | 194 CHECK_EQ(1, CompileRun("ordering[1]")->Int32Value()); |
195 // observer1's mutation causes both 1 and 2 to be reactivated, | 195 // observer1's mutation causes both 1 and 2 to be reactivated, |
196 // with 1 having priority. | 196 // with 1 having priority. |
197 CHECK_EQ(1, CompileRun("ordering[2]")->Int32Value()); | 197 CHECK_EQ(1, CompileRun("ordering[2]")->Int32Value()); |
198 CHECK_EQ(2, CompileRun("ordering[3]")->Int32Value()); | 198 CHECK_EQ(2, CompileRun("ordering[3]")->Int32Value()); |
199 } | 199 } |
200 | 200 |
201 | 201 |
202 TEST(ObjectHashTableGrowth) { | 202 TEST(ObjectHashTableGrowth) { |
203 HarmonyIsolate isolate; | 203 HarmonyIsolate isolate; |
204 HandleScope scope(isolate.GetIsolate()); | 204 HandleScope scope(isolate.GetIsolate()); |
205 // Initializing this context sets up initial hash tables. | 205 // Initializing this context sets up initial hash tables. |
206 LocalContext context; | 206 LocalContext context(isolate.GetIsolate()); |
207 Handle<Value> obj = CompileRun("obj = {};"); | 207 Handle<Value> obj = CompileRun("obj = {};"); |
208 Handle<Value> observer = CompileRun( | 208 Handle<Value> observer = CompileRun( |
209 "var ran = false;" | 209 "var ran = false;" |
210 "(function() { ran = true })"); | 210 "(function() { ran = true })"); |
211 { | 211 { |
212 // As does initializing this context. | 212 // As does initializing this context. |
213 LocalContext context2; | 213 LocalContext context2(isolate.GetIsolate()); |
214 context2->Global()->Set(String::New("obj"), obj); | 214 context2->Global()->Set(String::New("obj"), obj); |
215 context2->Global()->Set(String::New("observer"), observer); | 215 context2->Global()->Set(String::New("observer"), observer); |
216 CompileRun( | 216 CompileRun( |
217 "var objArr = [];" | 217 "var objArr = [];" |
218 // 100 objects should be enough to make the hash table grow | 218 // 100 objects should be enough to make the hash table grow |
219 // (and thus relocate). | 219 // (and thus relocate). |
220 "for (var i = 0; i < 100; ++i) {" | 220 "for (var i = 0; i < 100; ++i) {" |
221 " objArr.push({});" | 221 " objArr.push({});" |
222 " Object.observe(objArr[objArr.length-1], function(){});" | 222 " Object.observe(objArr[objArr.length-1], function(){});" |
223 "}" | 223 "}" |
224 "Object.observe(obj, observer);"); | 224 "Object.observe(obj, observer);"); |
225 } | 225 } |
226 // obj is now marked "is_observed", but our map has moved. | 226 // obj is now marked "is_observed", but our map has moved. |
227 CompileRun("obj.foo = 'bar'"); | 227 CompileRun("obj.foo = 'bar'"); |
228 CHECK(CompileRun("ran")->BooleanValue()); | 228 CHECK(CompileRun("ran")->BooleanValue()); |
229 } | 229 } |
230 | 230 |
231 | 231 |
232 TEST(GlobalObjectObservation) { | 232 TEST(GlobalObjectObservation) { |
233 HarmonyIsolate isolate; | 233 HarmonyIsolate isolate; |
234 LocalContext context; | 234 LocalContext context(isolate.GetIsolate()); |
235 HandleScope scope(isolate.GetIsolate()); | 235 HandleScope scope(isolate.GetIsolate()); |
236 Handle<Object> global_proxy = context->Global(); | 236 Handle<Object> global_proxy = context->Global(); |
237 Handle<Object> inner_global = global_proxy->GetPrototype().As<Object>(); | 237 Handle<Object> inner_global = global_proxy->GetPrototype().As<Object>(); |
238 CompileRun( | 238 CompileRun( |
239 "var records = [];" | 239 "var records = [];" |
240 "var global = this;" | 240 "var global = this;" |
241 "Object.observe(global, function(r) { [].push.apply(records, r) });" | 241 "Object.observe(global, function(r) { [].push.apply(records, r) });" |
242 "global.foo = 'hello';"); | 242 "global.foo = 'hello';"); |
243 CHECK_EQ(1, CompileRun("records.length")->Int32Value()); | 243 CHECK_EQ(1, CompileRun("records.length")->Int32Value()); |
244 CHECK(global_proxy->StrictEquals(CompileRun("records[0].object"))); | 244 CHECK(global_proxy->StrictEquals(CompileRun("records[0].object"))); |
(...skipping 11 matching lines...) Expand all Loading... |
256 // Reattached, back to global proxy. | 256 // Reattached, back to global proxy. |
257 context->ReattachGlobal(global_proxy); | 257 context->ReattachGlobal(global_proxy); |
258 CompileRun("global.baz = 'again';"); | 258 CompileRun("global.baz = 'again';"); |
259 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); | 259 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); |
260 CHECK(global_proxy->StrictEquals(CompileRun("records[2].object"))); | 260 CHECK(global_proxy->StrictEquals(CompileRun("records[2].object"))); |
261 | 261 |
262 // Attached to a different context, should not leak mutations | 262 // Attached to a different context, should not leak mutations |
263 // to the old context. | 263 // to the old context. |
264 context->DetachGlobal(); | 264 context->DetachGlobal(); |
265 { | 265 { |
266 LocalContext context2; | 266 LocalContext context2(isolate.GetIsolate()); |
267 context2->DetachGlobal(); | 267 context2->DetachGlobal(); |
268 context2->ReattachGlobal(global_proxy); | 268 context2->ReattachGlobal(global_proxy); |
269 CompileRun( | 269 CompileRun( |
270 "var records2 = [];" | 270 "var records2 = [];" |
271 "Object.observe(this, function(r) { [].push.apply(records2, r) });" | 271 "Object.observe(this, function(r) { [].push.apply(records2, r) });" |
272 "this.bat = 'context2';"); | 272 "this.bat = 'context2';"); |
273 CHECK_EQ(1, CompileRun("records2.length")->Int32Value()); | 273 CHECK_EQ(1, CompileRun("records2.length")->Int32Value()); |
274 CHECK(global_proxy->StrictEquals(CompileRun("records2[0].object"))); | 274 CHECK(global_proxy->StrictEquals(CompileRun("records2[0].object"))); |
275 } | 275 } |
276 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); | 276 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); |
277 | 277 |
278 // Attaching by passing to Context::New | 278 // Attaching by passing to Context::New |
279 { | 279 { |
280 // Delegates to Context::New | 280 // Delegates to Context::New |
281 LocalContext context3(NULL, Handle<ObjectTemplate>(), global_proxy); | 281 LocalContext context3( |
| 282 isolate.GetIsolate(), NULL, Handle<ObjectTemplate>(), global_proxy); |
282 CompileRun( | 283 CompileRun( |
283 "var records3 = [];" | 284 "var records3 = [];" |
284 "Object.observe(this, function(r) { [].push.apply(records3, r) });" | 285 "Object.observe(this, function(r) { [].push.apply(records3, r) });" |
285 "this.qux = 'context3';"); | 286 "this.qux = 'context3';"); |
286 CHECK_EQ(1, CompileRun("records3.length")->Int32Value()); | 287 CHECK_EQ(1, CompileRun("records3.length")->Int32Value()); |
287 CHECK(global_proxy->StrictEquals(CompileRun("records3[0].object"))); | 288 CHECK(global_proxy->StrictEquals(CompileRun("records3[0].object"))); |
288 } | 289 } |
289 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); | 290 CHECK_EQ(3, CompileRun("records.length")->Int32Value()); |
290 } | 291 } |
291 | 292 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
323 } | 324 } |
324 } | 325 } |
325 } | 326 } |
326 | 327 |
327 #define EXPECT_RECORDS(records, expectations) \ | 328 #define EXPECT_RECORDS(records, expectations) \ |
328 ExpectRecords(records, expectations, ARRAY_SIZE(expectations)) | 329 ExpectRecords(records, expectations, ARRAY_SIZE(expectations)) |
329 | 330 |
330 TEST(APITestBasicMutation) { | 331 TEST(APITestBasicMutation) { |
331 HarmonyIsolate isolate; | 332 HarmonyIsolate isolate; |
332 HandleScope scope(isolate.GetIsolate()); | 333 HandleScope scope(isolate.GetIsolate()); |
333 LocalContext context; | 334 LocalContext context(isolate.GetIsolate()); |
334 Handle<Object> obj = Handle<Object>::Cast(CompileRun( | 335 Handle<Object> obj = Handle<Object>::Cast(CompileRun( |
335 "var records = [];" | 336 "var records = [];" |
336 "var obj = {};" | 337 "var obj = {};" |
337 "function observer(r) { [].push.apply(records, r); };" | 338 "function observer(r) { [].push.apply(records, r); };" |
338 "Object.observe(obj, observer);" | 339 "Object.observe(obj, observer);" |
339 "obj")); | 340 "obj")); |
340 obj->Set(String::New("foo"), Number::New(7)); | 341 obj->Set(String::New("foo"), Number::New(7)); |
341 obj->Set(1, Number::New(2)); | 342 obj->Set(1, Number::New(2)); |
342 // ForceSet should work just as well as Set | 343 // ForceSet should work just as well as Set |
343 obj->ForceSet(String::New("foo"), Number::New(3)); | 344 obj->ForceSet(String::New("foo"), Number::New(3)); |
(...skipping 23 matching lines...) Expand all Loading... |
367 { obj, "deleted", "1", Number::New(5) }, | 368 { obj, "deleted", "1", Number::New(5) }, |
368 { obj, "deleted", "1.1", Number::New(6) } | 369 { obj, "deleted", "1.1", Number::New(6) } |
369 }; | 370 }; |
370 EXPECT_RECORDS(CompileRun("records"), expected_records); | 371 EXPECT_RECORDS(CompileRun("records"), expected_records); |
371 } | 372 } |
372 | 373 |
373 | 374 |
374 TEST(HiddenPrototypeObservation) { | 375 TEST(HiddenPrototypeObservation) { |
375 HarmonyIsolate isolate; | 376 HarmonyIsolate isolate; |
376 HandleScope scope(isolate.GetIsolate()); | 377 HandleScope scope(isolate.GetIsolate()); |
377 LocalContext context; | 378 LocalContext context(isolate.GetIsolate()); |
378 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); | 379 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); |
379 tmpl->SetHiddenPrototype(true); | 380 tmpl->SetHiddenPrototype(true); |
380 tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); | 381 tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); |
381 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); | 382 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); |
382 Handle<Object> obj = Object::New(); | 383 Handle<Object> obj = Object::New(); |
383 obj->SetPrototype(proto); | 384 obj->SetPrototype(proto); |
384 context->Global()->Set(String::New("obj"), obj); | 385 context->Global()->Set(String::New("obj"), obj); |
385 context->Global()->Set(String::New("proto"), proto); | 386 context->Global()->Set(String::New("proto"), proto); |
386 CompileRun( | 387 CompileRun( |
387 "var records;" | 388 "var records;" |
(...skipping 28 matching lines...) Expand all Loading... |
416 | 417 |
417 | 418 |
418 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { | 419 static int NumberOfElements(i::Handle<i::JSWeakMap> map) { |
419 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); | 420 return i::ObjectHashTable::cast(map->table())->NumberOfElements(); |
420 } | 421 } |
421 | 422 |
422 | 423 |
423 TEST(ObservationWeakMap) { | 424 TEST(ObservationWeakMap) { |
424 HarmonyIsolate isolate; | 425 HarmonyIsolate isolate; |
425 HandleScope scope(isolate.GetIsolate()); | 426 HandleScope scope(isolate.GetIsolate()); |
426 LocalContext context; | 427 LocalContext context(isolate.GetIsolate()); |
427 CompileRun( | 428 CompileRun( |
428 "var obj = {};" | 429 "var obj = {};" |
429 "Object.observe(obj, function(){});" | 430 "Object.observe(obj, function(){});" |
430 "Object.getNotifier(obj);" | 431 "Object.getNotifier(obj);" |
431 "obj = null;"); | 432 "obj = null;"); |
432 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate.GetIsolate()); | 433 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate.GetIsolate()); |
433 i::Handle<i::JSObject> observation_state = | 434 i::Handle<i::JSObject> observation_state = |
434 i_isolate->factory()->observation_state(); | 435 i_isolate->factory()->observation_state(); |
435 i::Handle<i::JSWeakMap> callbackInfoMap = | 436 i::Handle<i::JSWeakMap> callbackInfoMap = |
436 i::Handle<i::JSWeakMap>::cast( | 437 i::Handle<i::JSWeakMap>::cast( |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 instance->CreationContext()->Global()->Set(String::New("obj"), instance); | 511 instance->CreationContext()->Global()->Set(String::New("obj"), instance); |
511 return instance; | 512 return instance; |
512 } | 513 } |
513 | 514 |
514 | 515 |
515 TEST(NamedAccessCheck) { | 516 TEST(NamedAccessCheck) { |
516 HarmonyIsolate isolate; | 517 HarmonyIsolate isolate; |
517 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 518 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
518 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 519 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
519 HandleScope scope(isolate.GetIsolate()); | 520 HandleScope scope(isolate.GetIsolate()); |
520 LocalContext context; | 521 LocalContext context(isolate.GetIsolate()); |
521 g_access_block_type = types[i]; | 522 g_access_block_type = types[i]; |
522 Handle<Object> instance = CreateAccessCheckedObject( | 523 Handle<Object> instance = CreateAccessCheckedObject( |
523 NamedAccessAllowUnlessBlocked, IndexedAccessAlwaysAllowed); | 524 NamedAccessAllowUnlessBlocked, IndexedAccessAlwaysAllowed); |
524 CompileRun("var records = null;" | 525 CompileRun("var records = null;" |
525 "var objNoCheck = {};" | 526 "var objNoCheck = {};" |
526 "var blacklist = {foo: true};" | 527 "var blacklist = {foo: true};" |
527 "var observer = function(r) { records = r };" | 528 "var observer = function(r) { records = r };" |
528 "Object.observe(obj, observer);" | 529 "Object.observe(obj, observer);" |
529 "Object.observe(objNoCheck, observer);"); | 530 "Object.observe(objNoCheck, observer);"); |
530 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 531 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
531 { | 532 { |
532 LocalContext context2; | 533 LocalContext context2(isolate.GetIsolate()); |
533 context2->Global()->Set(String::New("obj"), instance); | 534 context2->Global()->Set(String::New("obj"), instance); |
534 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 535 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
535 CompileRun("var records2 = null;" | 536 CompileRun("var records2 = null;" |
536 "var observer2 = function(r) { records2 = r };" | 537 "var observer2 = function(r) { records2 = r };" |
537 "Object.observe(obj, observer2);" | 538 "Object.observe(obj, observer2);" |
538 "Object.observe(objNoCheck, observer2);" | 539 "Object.observe(objNoCheck, observer2);" |
539 "obj.foo = 'bar';" | 540 "obj.foo = 'bar';" |
540 "Object.defineProperty(obj, 'foo', {value: 5});" | 541 "Object.defineProperty(obj, 'foo', {value: 5});" |
541 "Object.defineProperty(obj, 'foo', {get: function(){}});" | 542 "Object.defineProperty(obj, 'foo', {get: function(){}});" |
542 "obj.bar = 'baz';" | 543 "obj.bar = 'baz';" |
(...skipping 14 matching lines...) Expand all Loading... |
557 EXPECT_RECORDS(CompileRun("records"), expected_records); | 558 EXPECT_RECORDS(CompileRun("records"), expected_records); |
558 } | 559 } |
559 } | 560 } |
560 | 561 |
561 | 562 |
562 TEST(IndexedAccessCheck) { | 563 TEST(IndexedAccessCheck) { |
563 HarmonyIsolate isolate; | 564 HarmonyIsolate isolate; |
564 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 565 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
565 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 566 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
566 HandleScope scope(isolate.GetIsolate()); | 567 HandleScope scope(isolate.GetIsolate()); |
567 LocalContext context; | 568 LocalContext context(isolate.GetIsolate()); |
568 g_access_block_type = types[i]; | 569 g_access_block_type = types[i]; |
569 Handle<Object> instance = CreateAccessCheckedObject( | 570 Handle<Object> instance = CreateAccessCheckedObject( |
570 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); | 571 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); |
571 CompileRun("var records = null;" | 572 CompileRun("var records = null;" |
572 "var objNoCheck = {};" | 573 "var objNoCheck = {};" |
573 "var blacklist = {7: true};" | 574 "var blacklist = {7: true};" |
574 "var observer = function(r) { records = r };" | 575 "var observer = function(r) { records = r };" |
575 "Object.observe(obj, observer);" | 576 "Object.observe(obj, observer);" |
576 "Object.observe(objNoCheck, observer);"); | 577 "Object.observe(objNoCheck, observer);"); |
577 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 578 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
578 { | 579 { |
579 LocalContext context2; | 580 LocalContext context2(isolate.GetIsolate()); |
580 context2->Global()->Set(String::New("obj"), instance); | 581 context2->Global()->Set(String::New("obj"), instance); |
581 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 582 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
582 CompileRun("var records2 = null;" | 583 CompileRun("var records2 = null;" |
583 "var observer2 = function(r) { records2 = r };" | 584 "var observer2 = function(r) { records2 = r };" |
584 "Object.observe(obj, observer2);" | 585 "Object.observe(obj, observer2);" |
585 "Object.observe(objNoCheck, observer2);" | 586 "Object.observe(objNoCheck, observer2);" |
586 "obj[7] = 'foo';" | 587 "obj[7] = 'foo';" |
587 "Object.defineProperty(obj, '7', {value: 5});" | 588 "Object.defineProperty(obj, '7', {value: 5});" |
588 "Object.defineProperty(obj, '7', {get: function(){}});" | 589 "Object.defineProperty(obj, '7', {get: function(){}});" |
589 "obj[8] = 'bar';" | 590 "obj[8] = 'bar';" |
(...skipping 12 matching lines...) Expand all Loading... |
602 { obj_no_check, "new", "42", Handle<Value>() } | 603 { obj_no_check, "new", "42", Handle<Value>() } |
603 }; | 604 }; |
604 EXPECT_RECORDS(CompileRun("records"), expected_records); | 605 EXPECT_RECORDS(CompileRun("records"), expected_records); |
605 } | 606 } |
606 } | 607 } |
607 | 608 |
608 | 609 |
609 TEST(SpliceAccessCheck) { | 610 TEST(SpliceAccessCheck) { |
610 HarmonyIsolate isolate; | 611 HarmonyIsolate isolate; |
611 HandleScope scope(isolate.GetIsolate()); | 612 HandleScope scope(isolate.GetIsolate()); |
612 LocalContext context; | 613 LocalContext context(isolate.GetIsolate()); |
613 g_access_block_type = ACCESS_GET; | 614 g_access_block_type = ACCESS_GET; |
614 Handle<Object> instance = CreateAccessCheckedObject( | 615 Handle<Object> instance = CreateAccessCheckedObject( |
615 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); | 616 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked); |
616 CompileRun("var records = null;" | 617 CompileRun("var records = null;" |
617 "obj[1] = 'foo';" | 618 "obj[1] = 'foo';" |
618 "obj.length = 2;" | 619 "obj.length = 2;" |
619 "var objNoCheck = {1: 'bar', length: 2};" | 620 "var objNoCheck = {1: 'bar', length: 2};" |
620 "var blacklist = {1: true};" | 621 "var blacklist = {1: true};" |
621 "observer = function(r) { records = r };" | 622 "observer = function(r) { records = r };" |
622 "Array.observe(obj, observer);" | 623 "Array.observe(obj, observer);" |
623 "Array.observe(objNoCheck, observer);"); | 624 "Array.observe(objNoCheck, observer);"); |
624 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 625 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
625 { | 626 { |
626 LocalContext context2; | 627 LocalContext context2(isolate.GetIsolate()); |
627 context2->Global()->Set(String::New("obj"), instance); | 628 context2->Global()->Set(String::New("obj"), instance); |
628 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 629 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
629 CompileRun("var records2 = null;" | 630 CompileRun("var records2 = null;" |
630 "var observer2 = function(r) { records2 = r };" | 631 "var observer2 = function(r) { records2 = r };" |
631 "Array.observe(obj, observer2);" | 632 "Array.observe(obj, observer2);" |
632 "Array.observe(objNoCheck, observer2);" | 633 "Array.observe(objNoCheck, observer2);" |
633 // No one should hear about this: no splice records are emitted | 634 // No one should hear about this: no splice records are emitted |
634 // for access-checked objects | 635 // for access-checked objects |
635 "[].push.call(obj, 5);" | 636 "[].push.call(obj, 5);" |
636 "[].splice.call(obj, 1, 1);" | 637 "[].splice.call(obj, 1, 1);" |
(...skipping 10 matching lines...) Expand all Loading... |
647 const RecordExpectation expected_records[] = { | 648 const RecordExpectation expected_records[] = { |
648 { obj_no_check, "splice", "", Handle<Value>() } | 649 { obj_no_check, "splice", "", Handle<Value>() } |
649 }; | 650 }; |
650 EXPECT_RECORDS(CompileRun("records"), expected_records); | 651 EXPECT_RECORDS(CompileRun("records"), expected_records); |
651 } | 652 } |
652 | 653 |
653 | 654 |
654 TEST(DisallowAllForAccessKeys) { | 655 TEST(DisallowAllForAccessKeys) { |
655 HarmonyIsolate isolate; | 656 HarmonyIsolate isolate; |
656 HandleScope scope(isolate.GetIsolate()); | 657 HandleScope scope(isolate.GetIsolate()); |
657 LocalContext context; | 658 LocalContext context(isolate.GetIsolate()); |
658 Handle<Object> instance = CreateAccessCheckedObject( | 659 Handle<Object> instance = CreateAccessCheckedObject( |
659 BlockAccessKeys, IndexedAccessAlwaysAllowed); | 660 BlockAccessKeys, IndexedAccessAlwaysAllowed); |
660 CompileRun("var records = null;" | 661 CompileRun("var records = null;" |
661 "var objNoCheck = {};" | 662 "var objNoCheck = {};" |
662 "var observer = function(r) { records = r };" | 663 "var observer = function(r) { records = r };" |
663 "var blacklist = {__block_access_keys: true};" | 664 "var blacklist = {__block_access_keys: true};" |
664 "Object.observe(obj, observer);" | 665 "Object.observe(obj, observer);" |
665 "Object.observe(objNoCheck, observer);"); | 666 "Object.observe(objNoCheck, observer);"); |
666 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 667 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
667 { | 668 { |
668 LocalContext context2; | 669 LocalContext context2(isolate.GetIsolate()); |
669 context2->Global()->Set(String::New("obj"), instance); | 670 context2->Global()->Set(String::New("obj"), instance); |
670 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 671 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); |
671 CompileRun("var records2 = null;" | 672 CompileRun("var records2 = null;" |
672 "var observer2 = function(r) { records2 = r };" | 673 "var observer2 = function(r) { records2 = r };" |
673 "Object.observe(obj, observer2);" | 674 "Object.observe(obj, observer2);" |
674 "Object.observe(objNoCheck, observer2);" | 675 "Object.observe(objNoCheck, observer2);" |
675 "obj.foo = 'bar';" | 676 "obj.foo = 'bar';" |
676 "obj[5] = 'baz';" | 677 "obj[5] = 'baz';" |
677 "objNoCheck.baz = 'quux'"); | 678 "objNoCheck.baz = 'quux'"); |
678 const RecordExpectation expected_records2[] = { | 679 const RecordExpectation expected_records2[] = { |
679 { instance, "new", "foo", Handle<Value>() }, | 680 { instance, "new", "foo", Handle<Value>() }, |
680 { instance, "new", "5", Handle<Value>() }, | 681 { instance, "new", "5", Handle<Value>() }, |
681 { obj_no_check, "new", "baz", Handle<Value>() }, | 682 { obj_no_check, "new", "baz", Handle<Value>() }, |
682 }; | 683 }; |
683 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 684 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
684 } | 685 } |
685 const RecordExpectation expected_records[] = { | 686 const RecordExpectation expected_records[] = { |
686 { obj_no_check, "new", "baz", Handle<Value>() } | 687 { obj_no_check, "new", "baz", Handle<Value>() } |
687 }; | 688 }; |
688 EXPECT_RECORDS(CompileRun("records"), expected_records); | 689 EXPECT_RECORDS(CompileRun("records"), expected_records); |
689 } | 690 } |
690 | 691 |
691 | 692 |
692 TEST(AccessCheckDisallowApiModifications) { | 693 TEST(AccessCheckDisallowApiModifications) { |
693 HarmonyIsolate isolate; | 694 HarmonyIsolate isolate; |
694 HandleScope scope(isolate.GetIsolate()); | 695 HandleScope scope(isolate.GetIsolate()); |
695 LocalContext context; | 696 LocalContext context(isolate.GetIsolate()); |
696 Handle<Object> instance = CreateAccessCheckedObject( | 697 Handle<Object> instance = CreateAccessCheckedObject( |
697 BlockAccessKeys, IndexedAccessAlwaysAllowed); | 698 BlockAccessKeys, IndexedAccessAlwaysAllowed); |
698 CompileRun("var records = null;" | 699 CompileRun("var records = null;" |
699 "var observer = function(r) { records = r };" | 700 "var observer = function(r) { records = r };" |
700 "var blacklist = {__block_access_keys: true};" | 701 "var blacklist = {__block_access_keys: true};" |
701 "Object.observe(obj, observer);"); | 702 "Object.observe(obj, observer);"); |
702 { | 703 { |
703 LocalContext context2; | 704 LocalContext context2(isolate.GetIsolate()); |
704 context2->Global()->Set(String::New("obj"), instance); | 705 context2->Global()->Set(String::New("obj"), instance); |
705 CompileRun("var records2 = null;" | 706 CompileRun("var records2 = null;" |
706 "var observer2 = function(r) { records2 = r };" | 707 "var observer2 = function(r) { records2 = r };" |
707 "Object.observe(obj, observer2);"); | 708 "Object.observe(obj, observer2);"); |
708 instance->Set(5, String::New("bar")); | 709 instance->Set(5, String::New("bar")); |
709 instance->Set(String::New("foo"), String::New("bar")); | 710 instance->Set(String::New("foo"), String::New("bar")); |
710 CompileRun(""); // trigger delivery | 711 CompileRun(""); // trigger delivery |
711 const RecordExpectation expected_records2[] = { | 712 const RecordExpectation expected_records2[] = { |
712 { instance, "new", "5", Handle<Value>() }, | 713 { instance, "new", "5", Handle<Value>() }, |
713 { instance, "new", "foo", Handle<Value>() } | 714 { instance, "new", "foo", Handle<Value>() } |
714 }; | 715 }; |
715 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 716 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
716 } | 717 } |
717 CHECK(CompileRun("records")->IsNull()); | 718 CHECK(CompileRun("records")->IsNull()); |
718 } | 719 } |
OLD | NEW |