| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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(isolate.GetIsolate()); | 74 LocalContext context2(isolate.GetIsolate()); |
| 75 context2->Global()->Set(String::New("obj"), obj); | 75 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 76 obj); |
| 76 notify_fun2 = CompileRun( | 77 notify_fun2 = CompileRun( |
| 77 "(function() { obj.foo = 'baz'; })"); | 78 "(function() { obj.foo = 'baz'; })"); |
| 78 } | 79 } |
| 79 Handle<Value> notify_fun3; | 80 Handle<Value> notify_fun3; |
| 80 { | 81 { |
| 81 LocalContext context3(isolate.GetIsolate()); | 82 LocalContext context3(isolate.GetIsolate()); |
| 82 context3->Global()->Set(String::New("obj"), obj); | 83 context3->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 84 obj); |
| 83 notify_fun3 = CompileRun( | 85 notify_fun3 = CompileRun( |
| 84 "(function() { obj.foo = 'bat'; })"); | 86 "(function() { obj.foo = 'bat'; })"); |
| 85 } | 87 } |
| 86 { | 88 { |
| 87 LocalContext context4(isolate.GetIsolate()); | 89 LocalContext context4(isolate.GetIsolate()); |
| 88 context4->Global()->Set(String::New("observer"), observer); | 90 context4->Global()->Set( |
| 89 context4->Global()->Set(String::New("fun1"), notify_fun1); | 91 String::NewFromUtf8(isolate.GetIsolate(), "observer"), observer); |
| 90 context4->Global()->Set(String::New("fun2"), notify_fun2); | 92 context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun1"), |
| 91 context4->Global()->Set(String::New("fun3"), notify_fun3); | 93 notify_fun1); |
| 94 context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun2"), |
| 95 notify_fun2); |
| 96 context4->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "fun3"), |
| 97 notify_fun3); |
| 92 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); | 98 CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); |
| 93 } | 99 } |
| 94 CHECK_EQ(1, CompileRun("calls")->Int32Value()); | 100 CHECK_EQ(1, CompileRun("calls")->Int32Value()); |
| 95 CHECK_EQ(3, CompileRun("count")->Int32Value()); | 101 CHECK_EQ(3, CompileRun("count")->Int32Value()); |
| 96 } | 102 } |
| 97 | 103 |
| 98 | 104 |
| 99 TEST(EndOfMicrotaskDelivery) { | 105 TEST(EndOfMicrotaskDelivery) { |
| 100 HarmonyIsolate isolate; | 106 HarmonyIsolate isolate; |
| 101 HandleScope scope(isolate.GetIsolate()); | 107 HandleScope scope(isolate.GetIsolate()); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 204 HandleScope scope(isolate.GetIsolate()); | 210 HandleScope scope(isolate.GetIsolate()); |
| 205 // Initializing this context sets up initial hash tables. | 211 // Initializing this context sets up initial hash tables. |
| 206 LocalContext context(isolate.GetIsolate()); | 212 LocalContext context(isolate.GetIsolate()); |
| 207 Handle<Value> obj = CompileRun("obj = {};"); | 213 Handle<Value> obj = CompileRun("obj = {};"); |
| 208 Handle<Value> observer = CompileRun( | 214 Handle<Value> observer = CompileRun( |
| 209 "var ran = false;" | 215 "var ran = false;" |
| 210 "(function() { ran = true })"); | 216 "(function() { ran = true })"); |
| 211 { | 217 { |
| 212 // As does initializing this context. | 218 // As does initializing this context. |
| 213 LocalContext context2(isolate.GetIsolate()); | 219 LocalContext context2(isolate.GetIsolate()); |
| 214 context2->Global()->Set(String::New("obj"), obj); | 220 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 215 context2->Global()->Set(String::New("observer"), observer); | 221 obj); |
| 222 context2->Global()->Set( |
| 223 String::NewFromUtf8(isolate.GetIsolate(), "observer"), observer); |
| 216 CompileRun( | 224 CompileRun( |
| 217 "var objArr = [];" | 225 "var objArr = [];" |
| 218 // 100 objects should be enough to make the hash table grow | 226 // 100 objects should be enough to make the hash table grow |
| 219 // (and thus relocate). | 227 // (and thus relocate). |
| 220 "for (var i = 0; i < 100; ++i) {" | 228 "for (var i = 0; i < 100; ++i) {" |
| 221 " objArr.push({});" | 229 " objArr.push({});" |
| 222 " Object.observe(objArr[objArr.length-1], function(){});" | 230 " Object.observe(objArr[objArr.length-1], function(){});" |
| 223 "}" | 231 "}" |
| 224 "Object.observe(obj, observer);"); | 232 "Object.observe(obj, observer);"); |
| 225 } | 233 } |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 | 301 |
| 294 struct RecordExpectation { | 302 struct RecordExpectation { |
| 295 Handle<Value> object; | 303 Handle<Value> object; |
| 296 const char* type; | 304 const char* type; |
| 297 const char* name; | 305 const char* name; |
| 298 Handle<Value> old_value; | 306 Handle<Value> old_value; |
| 299 }; | 307 }; |
| 300 | 308 |
| 301 | 309 |
| 302 // TODO(adamk): Use this helper elsewhere in this file. | 310 // TODO(adamk): Use this helper elsewhere in this file. |
| 303 static void ExpectRecords(Handle<Value> records, | 311 static void ExpectRecords(v8::Isolate* isolate, |
| 312 Handle<Value> records, |
| 304 const RecordExpectation expectations[], | 313 const RecordExpectation expectations[], |
| 305 int num) { | 314 int num) { |
| 306 CHECK(records->IsArray()); | 315 CHECK(records->IsArray()); |
| 307 Handle<Array> recordArray = records.As<Array>(); | 316 Handle<Array> recordArray = records.As<Array>(); |
| 308 CHECK_EQ(num, static_cast<int>(recordArray->Length())); | 317 CHECK_EQ(num, static_cast<int>(recordArray->Length())); |
| 309 for (int i = 0; i < num; ++i) { | 318 for (int i = 0; i < num; ++i) { |
| 310 Handle<Value> record = recordArray->Get(i); | 319 Handle<Value> record = recordArray->Get(i); |
| 311 CHECK(record->IsObject()); | 320 CHECK(record->IsObject()); |
| 312 Handle<Object> recordObj = record.As<Object>(); | 321 Handle<Object> recordObj = record.As<Object>(); |
| 313 CHECK(expectations[i].object->StrictEquals( | 322 CHECK(expectations[i].object->StrictEquals( |
| 314 recordObj->Get(String::New("object")))); | 323 recordObj->Get(String::NewFromUtf8(isolate, "object")))); |
| 315 CHECK(String::New(expectations[i].type)->Equals( | 324 CHECK(String::NewFromUtf8(isolate, expectations[i].type)->Equals( |
| 316 recordObj->Get(String::New("type")))); | 325 recordObj->Get(String::NewFromUtf8(isolate, "type")))); |
| 317 if (strcmp("splice", expectations[i].type) != 0) { | 326 if (strcmp("splice", expectations[i].type) != 0) { |
| 318 CHECK(String::New(expectations[i].name)->Equals( | 327 CHECK(String::NewFromUtf8(isolate, expectations[i].name)->Equals( |
| 319 recordObj->Get(String::New("name")))); | 328 recordObj->Get(String::NewFromUtf8(isolate, "name")))); |
| 320 if (!expectations[i].old_value.IsEmpty()) { | 329 if (!expectations[i].old_value.IsEmpty()) { |
| 321 CHECK(expectations[i].old_value->Equals( | 330 CHECK(expectations[i].old_value->Equals( |
| 322 recordObj->Get(String::New("oldValue")))); | 331 recordObj->Get(String::NewFromUtf8(isolate, "oldValue")))); |
| 323 } | 332 } |
| 324 } | 333 } |
| 325 } | 334 } |
| 326 } | 335 } |
| 327 | 336 |
| 328 #define EXPECT_RECORDS(records, expectations) \ | 337 #define EXPECT_RECORDS(records, expectations) \ |
| 329 ExpectRecords(records, expectations, ARRAY_SIZE(expectations)) | 338 ExpectRecords(isolate.GetIsolate(), records, expectations, \ |
| 339 ARRAY_SIZE(expectations)) |
| 330 | 340 |
| 331 TEST(APITestBasicMutation) { | 341 TEST(APITestBasicMutation) { |
| 332 HarmonyIsolate isolate; | 342 HarmonyIsolate isolate; |
| 333 HandleScope scope(isolate.GetIsolate()); | 343 HandleScope scope(isolate.GetIsolate()); |
| 334 LocalContext context(isolate.GetIsolate()); | 344 LocalContext context(isolate.GetIsolate()); |
| 335 Handle<Object> obj = Handle<Object>::Cast(CompileRun( | 345 Handle<Object> obj = Handle<Object>::Cast(CompileRun( |
| 336 "var records = [];" | 346 "var records = [];" |
| 337 "var obj = {};" | 347 "var obj = {};" |
| 338 "function observer(r) { [].push.apply(records, r); };" | 348 "function observer(r) { [].push.apply(records, r); };" |
| 339 "Object.observe(obj, observer);" | 349 "Object.observe(obj, observer);" |
| 340 "obj")); | 350 "obj")); |
| 341 obj->Set(String::New("foo"), Number::New(7)); | 351 obj->Set(String::NewFromUtf8(isolate.GetIsolate(), "foo"), Number::New(7)); |
| 342 obj->Set(1, Number::New(2)); | 352 obj->Set(1, Number::New(2)); |
| 343 // ForceSet should work just as well as Set | 353 // ForceSet should work just as well as Set |
| 344 obj->ForceSet(String::New("foo"), Number::New(3)); | 354 obj->ForceSet(String::NewFromUtf8(isolate.GetIsolate(), "foo"), |
| 355 Number::New(3)); |
| 345 obj->ForceSet(Number::New(1), Number::New(4)); | 356 obj->ForceSet(Number::New(1), Number::New(4)); |
| 346 // Setting an indexed element via the property setting method | 357 // Setting an indexed element via the property setting method |
| 347 obj->Set(Number::New(1), Number::New(5)); | 358 obj->Set(Number::New(1), Number::New(5)); |
| 348 // Setting with a non-String, non-uint32 key | 359 // Setting with a non-String, non-uint32 key |
| 349 obj->Set(Number::New(1.1), Number::New(6), DontDelete); | 360 obj->Set(Number::New(1.1), Number::New(6), DontDelete); |
| 350 obj->Delete(String::New("foo")); | 361 obj->Delete(String::NewFromUtf8(isolate.GetIsolate(), "foo")); |
| 351 obj->Delete(1); | 362 obj->Delete(1); |
| 352 obj->ForceDelete(Number::New(1.1)); | 363 obj->ForceDelete(Number::New(1.1)); |
| 353 | 364 |
| 354 // Force delivery | 365 // Force delivery |
| 355 // TODO(adamk): Should the above set methods trigger delivery themselves? | 366 // TODO(adamk): Should the above set methods trigger delivery themselves? |
| 356 CompileRun("void 0"); | 367 CompileRun("void 0"); |
| 357 CHECK_EQ(9, CompileRun("records.length")->Int32Value()); | 368 CHECK_EQ(9, CompileRun("records.length")->Int32Value()); |
| 358 const RecordExpectation expected_records[] = { | 369 const RecordExpectation expected_records[] = { |
| 359 { obj, "add", "foo", Handle<Value>() }, | 370 { obj, "add", "foo", Handle<Value>() }, |
| 360 { obj, "add", "1", Handle<Value>() }, | 371 { obj, "add", "1", Handle<Value>() }, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 371 EXPECT_RECORDS(CompileRun("records"), expected_records); | 382 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 372 } | 383 } |
| 373 | 384 |
| 374 | 385 |
| 375 TEST(HiddenPrototypeObservation) { | 386 TEST(HiddenPrototypeObservation) { |
| 376 HarmonyIsolate isolate; | 387 HarmonyIsolate isolate; |
| 377 HandleScope scope(isolate.GetIsolate()); | 388 HandleScope scope(isolate.GetIsolate()); |
| 378 LocalContext context(isolate.GetIsolate()); | 389 LocalContext context(isolate.GetIsolate()); |
| 379 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); | 390 Handle<FunctionTemplate> tmpl = FunctionTemplate::New(); |
| 380 tmpl->SetHiddenPrototype(true); | 391 tmpl->SetHiddenPrototype(true); |
| 381 tmpl->InstanceTemplate()->Set(String::New("foo"), Number::New(75)); | 392 tmpl->InstanceTemplate()->Set( |
| 393 String::NewFromUtf8(isolate.GetIsolate(), "foo"), Number::New(75)); |
| 382 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); | 394 Handle<Object> proto = tmpl->GetFunction()->NewInstance(); |
| 383 Handle<Object> obj = Object::New(); | 395 Handle<Object> obj = Object::New(); |
| 384 obj->SetPrototype(proto); | 396 obj->SetPrototype(proto); |
| 385 context->Global()->Set(String::New("obj"), obj); | 397 context->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), obj); |
| 386 context->Global()->Set(String::New("proto"), proto); | 398 context->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "proto"), |
| 399 proto); |
| 387 CompileRun( | 400 CompileRun( |
| 388 "var records;" | 401 "var records;" |
| 389 "function observer(r) { records = r; };" | 402 "function observer(r) { records = r; };" |
| 390 "Object.observe(obj, observer);" | 403 "Object.observe(obj, observer);" |
| 391 "obj.foo = 41;" // triggers a notification | 404 "obj.foo = 41;" // triggers a notification |
| 392 "proto.foo = 42;"); // does not trigger a notification | 405 "proto.foo = 42;"); // does not trigger a notification |
| 393 const RecordExpectation expected_records[] = { | 406 const RecordExpectation expected_records[] = { |
| 394 { obj, "update", "foo", Number::New(75) } | 407 { obj, "update", "foo", Number::New(75) } |
| 395 }; | 408 }; |
| 396 EXPECT_RECORDS(CompileRun("records"), expected_records); | 409 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 static bool BlockAccessKeys(Local<Object> host, Local<Value> key, | 510 static bool BlockAccessKeys(Local<Object> host, Local<Value> key, |
| 498 AccessType type, Local<Value>) { | 511 AccessType type, Local<Value>) { |
| 499 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( | 512 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>( |
| 500 Utils::OpenHandle(*host)->GetIsolate()); | 513 Utils::OpenHandle(*host)->GetIsolate()); |
| 501 Handle<Object> global = isolate->GetCurrentContext()->Global(); | 514 Handle<Object> global = isolate->GetCurrentContext()->Global(); |
| 502 return type != ACCESS_KEYS || !global->Has(kBlockedContextIndex); | 515 return type != ACCESS_KEYS || !global->Has(kBlockedContextIndex); |
| 503 } | 516 } |
| 504 | 517 |
| 505 | 518 |
| 506 static Handle<Object> CreateAccessCheckedObject( | 519 static Handle<Object> CreateAccessCheckedObject( |
| 520 v8::Isolate* isolate, |
| 507 NamedSecurityCallback namedCallback, | 521 NamedSecurityCallback namedCallback, |
| 508 IndexedSecurityCallback indexedCallback, | 522 IndexedSecurityCallback indexedCallback, |
| 509 Handle<Value> data = Handle<Value>()) { | 523 Handle<Value> data = Handle<Value>()) { |
| 510 Handle<ObjectTemplate> tmpl = ObjectTemplate::New(); | 524 Handle<ObjectTemplate> tmpl = ObjectTemplate::New(); |
| 511 tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback, data); | 525 tmpl->SetAccessCheckCallbacks(namedCallback, indexedCallback, data); |
| 512 Handle<Object> instance = tmpl->NewInstance(); | 526 Handle<Object> instance = tmpl->NewInstance(); |
| 513 Handle<Object> global = instance->CreationContext()->Global(); | 527 Handle<Object> global = instance->CreationContext()->Global(); |
| 514 global->Set(String::New("obj"), instance); | 528 global->Set(String::NewFromUtf8(isolate, "obj"), instance); |
| 515 global->Set(kBlockedContextIndex, v8::True()); | 529 global->Set(kBlockedContextIndex, v8::True()); |
| 516 return instance; | 530 return instance; |
| 517 } | 531 } |
| 518 | 532 |
| 519 | 533 |
| 520 TEST(NamedAccessCheck) { | 534 TEST(NamedAccessCheck) { |
| 521 HarmonyIsolate isolate; | 535 HarmonyIsolate isolate; |
| 522 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 536 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
| 523 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 537 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
| 524 HandleScope scope(isolate.GetIsolate()); | 538 HandleScope scope(isolate.GetIsolate()); |
| 525 LocalContext context(isolate.GetIsolate()); | 539 LocalContext context(isolate.GetIsolate()); |
| 526 g_access_block_type = types[i]; | 540 g_access_block_type = types[i]; |
| 527 Handle<Object> instance = CreateAccessCheckedObject( | 541 Handle<Object> instance = CreateAccessCheckedObject( |
| 542 isolate.GetIsolate(), |
| 528 NamedAccessAllowUnlessBlocked, | 543 NamedAccessAllowUnlessBlocked, |
| 529 IndexedAccessAlwaysAllowed, | 544 IndexedAccessAlwaysAllowed, |
| 530 String::New("foo")); | 545 String::NewFromUtf8(isolate.GetIsolate(), "foo")); |
| 531 CompileRun("var records = null;" | 546 CompileRun("var records = null;" |
| 532 "var objNoCheck = {};" | 547 "var objNoCheck = {};" |
| 533 "var observer = function(r) { records = r };" | 548 "var observer = function(r) { records = r };" |
| 534 "Object.observe(obj, observer);" | 549 "Object.observe(obj, observer);" |
| 535 "Object.observe(objNoCheck, observer);"); | 550 "Object.observe(objNoCheck, observer);"); |
| 536 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 551 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
| 537 { | 552 { |
| 538 LocalContext context2(isolate.GetIsolate()); | 553 LocalContext context2(isolate.GetIsolate()); |
| 539 context2->Global()->Set(String::New("obj"), instance); | 554 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 540 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 555 instance); |
| 556 context2->Global()->Set( |
| 557 String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), |
| 558 obj_no_check); |
| 541 CompileRun("var records2 = null;" | 559 CompileRun("var records2 = null;" |
| 542 "var observer2 = function(r) { records2 = r };" | 560 "var observer2 = function(r) { records2 = r };" |
| 543 "Object.observe(obj, observer2);" | 561 "Object.observe(obj, observer2);" |
| 544 "Object.observe(objNoCheck, observer2);" | 562 "Object.observe(objNoCheck, observer2);" |
| 545 "obj.foo = 'bar';" | 563 "obj.foo = 'bar';" |
| 546 "Object.defineProperty(obj, 'foo', {value: 5});" | 564 "Object.defineProperty(obj, 'foo', {value: 5});" |
| 547 "Object.defineProperty(obj, 'foo', {get: function(){}});" | 565 "Object.defineProperty(obj, 'foo', {get: function(){}});" |
| 548 "obj.bar = 'baz';" | 566 "obj.bar = 'baz';" |
| 549 "objNoCheck.baz = 'quux'"); | 567 "objNoCheck.baz = 'quux'"); |
| 550 const RecordExpectation expected_records2[] = { | 568 const RecordExpectation expected_records2[] = { |
| 551 { instance, "add", "foo", Handle<Value>() }, | 569 { instance, "add", "foo", Handle<Value>() }, |
| 552 { instance, "update", "foo", String::New("bar") }, | 570 { instance, "update", "foo", |
| 571 String::NewFromUtf8(isolate.GetIsolate(), "bar") }, |
| 553 { instance, "reconfigure", "foo", Number::New(5) }, | 572 { instance, "reconfigure", "foo", Number::New(5) }, |
| 554 { instance, "add", "bar", Handle<Value>() }, | 573 { instance, "add", "bar", Handle<Value>() }, |
| 555 { obj_no_check, "add", "baz", Handle<Value>() }, | 574 { obj_no_check, "add", "baz", Handle<Value>() }, |
| 556 }; | 575 }; |
| 557 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 576 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
| 558 } | 577 } |
| 559 const RecordExpectation expected_records[] = { | 578 const RecordExpectation expected_records[] = { |
| 560 { instance, "add", "bar", Handle<Value>() }, | 579 { instance, "add", "bar", Handle<Value>() }, |
| 561 { obj_no_check, "add", "baz", Handle<Value>() } | 580 { obj_no_check, "add", "baz", Handle<Value>() } |
| 562 }; | 581 }; |
| 563 EXPECT_RECORDS(CompileRun("records"), expected_records); | 582 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 564 } | 583 } |
| 565 } | 584 } |
| 566 | 585 |
| 567 | 586 |
| 568 TEST(IndexedAccessCheck) { | 587 TEST(IndexedAccessCheck) { |
| 569 HarmonyIsolate isolate; | 588 HarmonyIsolate isolate; |
| 570 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; | 589 const AccessType types[] = { ACCESS_GET, ACCESS_HAS }; |
| 571 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { | 590 for (size_t i = 0; i < ARRAY_SIZE(types); ++i) { |
| 572 HandleScope scope(isolate.GetIsolate()); | 591 HandleScope scope(isolate.GetIsolate()); |
| 573 LocalContext context(isolate.GetIsolate()); | 592 LocalContext context(isolate.GetIsolate()); |
| 574 g_access_block_type = types[i]; | 593 g_access_block_type = types[i]; |
| 575 Handle<Object> instance = CreateAccessCheckedObject( | 594 Handle<Object> instance = CreateAccessCheckedObject( |
| 576 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, | 595 isolate.GetIsolate(), NamedAccessAlwaysAllowed, |
| 577 Number::New(7)); | 596 IndexedAccessAllowUnlessBlocked, Number::New(7)); |
| 578 CompileRun("var records = null;" | 597 CompileRun("var records = null;" |
| 579 "var objNoCheck = {};" | 598 "var objNoCheck = {};" |
| 580 "var observer = function(r) { records = r };" | 599 "var observer = function(r) { records = r };" |
| 581 "Object.observe(obj, observer);" | 600 "Object.observe(obj, observer);" |
| 582 "Object.observe(objNoCheck, observer);"); | 601 "Object.observe(objNoCheck, observer);"); |
| 583 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 602 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
| 584 { | 603 { |
| 585 LocalContext context2(isolate.GetIsolate()); | 604 LocalContext context2(isolate.GetIsolate()); |
| 586 context2->Global()->Set(String::New("obj"), instance); | 605 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 587 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 606 instance); |
| 607 context2->Global()->Set( |
| 608 String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), |
| 609 obj_no_check); |
| 588 CompileRun("var records2 = null;" | 610 CompileRun("var records2 = null;" |
| 589 "var observer2 = function(r) { records2 = r };" | 611 "var observer2 = function(r) { records2 = r };" |
| 590 "Object.observe(obj, observer2);" | 612 "Object.observe(obj, observer2);" |
| 591 "Object.observe(objNoCheck, observer2);" | 613 "Object.observe(objNoCheck, observer2);" |
| 592 "obj[7] = 'foo';" | 614 "obj[7] = 'foo';" |
| 593 "Object.defineProperty(obj, '7', {value: 5});" | 615 "Object.defineProperty(obj, '7', {value: 5});" |
| 594 "Object.defineProperty(obj, '7', {get: function(){}});" | 616 "Object.defineProperty(obj, '7', {get: function(){}});" |
| 595 "obj[8] = 'bar';" | 617 "obj[8] = 'bar';" |
| 596 "objNoCheck[42] = 'quux'"); | 618 "objNoCheck[42] = 'quux'"); |
| 597 const RecordExpectation expected_records2[] = { | 619 const RecordExpectation expected_records2[] = { |
| 598 { instance, "add", "7", Handle<Value>() }, | 620 { instance, "add", "7", Handle<Value>() }, |
| 599 { instance, "update", "7", String::New("foo") }, | 621 { instance, "update", "7", |
| 622 String::NewFromUtf8(isolate.GetIsolate(), "foo") }, |
| 600 { instance, "reconfigure", "7", Number::New(5) }, | 623 { instance, "reconfigure", "7", Number::New(5) }, |
| 601 { instance, "add", "8", Handle<Value>() }, | 624 { instance, "add", "8", Handle<Value>() }, |
| 602 { obj_no_check, "add", "42", Handle<Value>() } | 625 { obj_no_check, "add", "42", Handle<Value>() } |
| 603 }; | 626 }; |
| 604 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 627 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
| 605 } | 628 } |
| 606 const RecordExpectation expected_records[] = { | 629 const RecordExpectation expected_records[] = { |
| 607 { instance, "add", "8", Handle<Value>() }, | 630 { instance, "add", "8", Handle<Value>() }, |
| 608 { obj_no_check, "add", "42", Handle<Value>() } | 631 { obj_no_check, "add", "42", Handle<Value>() } |
| 609 }; | 632 }; |
| 610 EXPECT_RECORDS(CompileRun("records"), expected_records); | 633 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 611 } | 634 } |
| 612 } | 635 } |
| 613 | 636 |
| 614 | 637 |
| 615 TEST(SpliceAccessCheck) { | 638 TEST(SpliceAccessCheck) { |
| 616 HarmonyIsolate isolate; | 639 HarmonyIsolate isolate; |
| 617 HandleScope scope(isolate.GetIsolate()); | 640 HandleScope scope(isolate.GetIsolate()); |
| 618 LocalContext context(isolate.GetIsolate()); | 641 LocalContext context(isolate.GetIsolate()); |
| 619 g_access_block_type = ACCESS_GET; | 642 g_access_block_type = ACCESS_GET; |
| 620 Handle<Object> instance = CreateAccessCheckedObject( | 643 Handle<Object> instance = CreateAccessCheckedObject( |
| 621 NamedAccessAlwaysAllowed, IndexedAccessAllowUnlessBlocked, | 644 isolate.GetIsolate(), NamedAccessAlwaysAllowed, |
| 622 Number::New(1)); | 645 IndexedAccessAllowUnlessBlocked, Number::New(1)); |
| 623 CompileRun("var records = null;" | 646 CompileRun("var records = null;" |
| 624 "obj[1] = 'foo';" | 647 "obj[1] = 'foo';" |
| 625 "obj.length = 2;" | 648 "obj.length = 2;" |
| 626 "var objNoCheck = {1: 'bar', length: 2};" | 649 "var objNoCheck = {1: 'bar', length: 2};" |
| 627 "observer = function(r) { records = r };" | 650 "observer = function(r) { records = r };" |
| 628 "Array.observe(obj, observer);" | 651 "Array.observe(obj, observer);" |
| 629 "Array.observe(objNoCheck, observer);"); | 652 "Array.observe(objNoCheck, observer);"); |
| 630 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 653 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
| 631 { | 654 { |
| 632 LocalContext context2(isolate.GetIsolate()); | 655 LocalContext context2(isolate.GetIsolate()); |
| 633 context2->Global()->Set(String::New("obj"), instance); | 656 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 634 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 657 instance); |
| 658 context2->Global()->Set( |
| 659 String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), obj_no_check); |
| 635 CompileRun("var records2 = null;" | 660 CompileRun("var records2 = null;" |
| 636 "var observer2 = function(r) { records2 = r };" | 661 "var observer2 = function(r) { records2 = r };" |
| 637 "Array.observe(obj, observer2);" | 662 "Array.observe(obj, observer2);" |
| 638 "Array.observe(objNoCheck, observer2);" | 663 "Array.observe(objNoCheck, observer2);" |
| 639 // No one should hear about this: no splice records are emitted | 664 // No one should hear about this: no splice records are emitted |
| 640 // for access-checked objects | 665 // for access-checked objects |
| 641 "[].push.call(obj, 5);" | 666 "[].push.call(obj, 5);" |
| 642 "[].splice.call(obj, 1, 1);" | 667 "[].splice.call(obj, 1, 1);" |
| 643 "[].pop.call(obj);" | 668 "[].pop.call(obj);" |
| 644 "[].pop.call(objNoCheck);"); | 669 "[].pop.call(objNoCheck);"); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 655 }; | 680 }; |
| 656 EXPECT_RECORDS(CompileRun("records"), expected_records); | 681 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 657 } | 682 } |
| 658 | 683 |
| 659 | 684 |
| 660 TEST(DisallowAllForAccessKeys) { | 685 TEST(DisallowAllForAccessKeys) { |
| 661 HarmonyIsolate isolate; | 686 HarmonyIsolate isolate; |
| 662 HandleScope scope(isolate.GetIsolate()); | 687 HandleScope scope(isolate.GetIsolate()); |
| 663 LocalContext context(isolate.GetIsolate()); | 688 LocalContext context(isolate.GetIsolate()); |
| 664 Handle<Object> instance = CreateAccessCheckedObject( | 689 Handle<Object> instance = CreateAccessCheckedObject( |
| 665 BlockAccessKeys, IndexedAccessAlwaysAllowed); | 690 isolate.GetIsolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed); |
| 666 CompileRun("var records = null;" | 691 CompileRun("var records = null;" |
| 667 "var objNoCheck = {};" | 692 "var objNoCheck = {};" |
| 668 "var observer = function(r) { records = r };" | 693 "var observer = function(r) { records = r };" |
| 669 "Object.observe(obj, observer);" | 694 "Object.observe(obj, observer);" |
| 670 "Object.observe(objNoCheck, observer);"); | 695 "Object.observe(objNoCheck, observer);"); |
| 671 Handle<Value> obj_no_check = CompileRun("objNoCheck"); | 696 Handle<Value> obj_no_check = CompileRun("objNoCheck"); |
| 672 { | 697 { |
| 673 LocalContext context2(isolate.GetIsolate()); | 698 LocalContext context2(isolate.GetIsolate()); |
| 674 context2->Global()->Set(String::New("obj"), instance); | 699 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 675 context2->Global()->Set(String::New("objNoCheck"), obj_no_check); | 700 instance); |
| 701 context2->Global()->Set( |
| 702 String::NewFromUtf8(isolate.GetIsolate(), "objNoCheck"), obj_no_check); |
| 676 CompileRun("var records2 = null;" | 703 CompileRun("var records2 = null;" |
| 677 "var observer2 = function(r) { records2 = r };" | 704 "var observer2 = function(r) { records2 = r };" |
| 678 "Object.observe(obj, observer2);" | 705 "Object.observe(obj, observer2);" |
| 679 "Object.observe(objNoCheck, observer2);" | 706 "Object.observe(objNoCheck, observer2);" |
| 680 "obj.foo = 'bar';" | 707 "obj.foo = 'bar';" |
| 681 "obj[5] = 'baz';" | 708 "obj[5] = 'baz';" |
| 682 "objNoCheck.baz = 'quux'"); | 709 "objNoCheck.baz = 'quux'"); |
| 683 const RecordExpectation expected_records2[] = { | 710 const RecordExpectation expected_records2[] = { |
| 684 { instance, "add", "foo", Handle<Value>() }, | 711 { instance, "add", "foo", Handle<Value>() }, |
| 685 { instance, "add", "5", Handle<Value>() }, | 712 { instance, "add", "5", Handle<Value>() }, |
| 686 { obj_no_check, "add", "baz", Handle<Value>() }, | 713 { obj_no_check, "add", "baz", Handle<Value>() }, |
| 687 }; | 714 }; |
| 688 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 715 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
| 689 } | 716 } |
| 690 const RecordExpectation expected_records[] = { | 717 const RecordExpectation expected_records[] = { |
| 691 { obj_no_check, "add", "baz", Handle<Value>() } | 718 { obj_no_check, "add", "baz", Handle<Value>() } |
| 692 }; | 719 }; |
| 693 EXPECT_RECORDS(CompileRun("records"), expected_records); | 720 EXPECT_RECORDS(CompileRun("records"), expected_records); |
| 694 } | 721 } |
| 695 | 722 |
| 696 | 723 |
| 697 TEST(AccessCheckDisallowApiModifications) { | 724 TEST(AccessCheckDisallowApiModifications) { |
| 698 HarmonyIsolate isolate; | 725 HarmonyIsolate isolate; |
| 699 HandleScope scope(isolate.GetIsolate()); | 726 HandleScope scope(isolate.GetIsolate()); |
| 700 LocalContext context(isolate.GetIsolate()); | 727 LocalContext context(isolate.GetIsolate()); |
| 701 Handle<Object> instance = CreateAccessCheckedObject( | 728 Handle<Object> instance = CreateAccessCheckedObject( |
| 702 BlockAccessKeys, IndexedAccessAlwaysAllowed); | 729 isolate.GetIsolate(), BlockAccessKeys, IndexedAccessAlwaysAllowed); |
| 703 CompileRun("var records = null;" | 730 CompileRun("var records = null;" |
| 704 "var observer = function(r) { records = r };" | 731 "var observer = function(r) { records = r };" |
| 705 "Object.observe(obj, observer);"); | 732 "Object.observe(obj, observer);"); |
| 706 { | 733 { |
| 707 LocalContext context2(isolate.GetIsolate()); | 734 LocalContext context2(isolate.GetIsolate()); |
| 708 context2->Global()->Set(String::New("obj"), instance); | 735 context2->Global()->Set(String::NewFromUtf8(isolate.GetIsolate(), "obj"), |
| 736 instance); |
| 709 CompileRun("var records2 = null;" | 737 CompileRun("var records2 = null;" |
| 710 "var observer2 = function(r) { records2 = r };" | 738 "var observer2 = function(r) { records2 = r };" |
| 711 "Object.observe(obj, observer2);"); | 739 "Object.observe(obj, observer2);"); |
| 712 instance->Set(5, String::New("bar")); | 740 instance->Set(5, String::NewFromUtf8(isolate.GetIsolate(), "bar")); |
| 713 instance->Set(String::New("foo"), String::New("bar")); | 741 instance->Set(String::NewFromUtf8(isolate.GetIsolate(), "foo"), |
| 742 String::NewFromUtf8(isolate.GetIsolate(), "bar")); |
| 714 CompileRun(""); // trigger delivery | 743 CompileRun(""); // trigger delivery |
| 715 const RecordExpectation expected_records2[] = { | 744 const RecordExpectation expected_records2[] = { |
| 716 { instance, "add", "5", Handle<Value>() }, | 745 { instance, "add", "5", Handle<Value>() }, |
| 717 { instance, "add", "foo", Handle<Value>() } | 746 { instance, "add", "foo", Handle<Value>() } |
| 718 }; | 747 }; |
| 719 EXPECT_RECORDS(CompileRun("records2"), expected_records2); | 748 EXPECT_RECORDS(CompileRun("records2"), expected_records2); |
| 720 } | 749 } |
| 721 CHECK(CompileRun("records")->IsNull()); | 750 CHECK(CompileRun("records")->IsNull()); |
| 722 } | 751 } |
| 723 | 752 |
| 724 | 753 |
| 725 TEST(HiddenPropertiesLeakage) { | 754 TEST(HiddenPropertiesLeakage) { |
| 726 HarmonyIsolate isolate; | 755 HarmonyIsolate isolate; |
| 727 HandleScope scope(isolate.GetIsolate()); | 756 HandleScope scope(isolate.GetIsolate()); |
| 728 LocalContext context(isolate.GetIsolate()); | 757 LocalContext context(isolate.GetIsolate()); |
| 729 CompileRun("var obj = {};" | 758 CompileRun("var obj = {};" |
| 730 "var records = null;" | 759 "var records = null;" |
| 731 "var observer = function(r) { records = r };" | 760 "var observer = function(r) { records = r };" |
| 732 "Object.observe(obj, observer);"); | 761 "Object.observe(obj, observer);"); |
| 733 Handle<Value> obj = context->Global()->Get(String::New("obj")); | 762 Handle<Value> obj = |
| 734 Handle<Object>::Cast(obj)->SetHiddenValue(String::New("foo"), Null()); | 763 context->Global()->Get(String::NewFromUtf8(isolate.GetIsolate(), "obj")); |
| 764 Handle<Object>::Cast(obj)->SetHiddenValue( |
| 765 String::NewFromUtf8(isolate.GetIsolate(), "foo"), Null()); |
| 735 CompileRun(""); // trigger delivery | 766 CompileRun(""); // trigger delivery |
| 736 CHECK(CompileRun("records")->IsNull()); | 767 CHECK(CompileRun("records")->IsNull()); |
| 737 } | 768 } |
| OLD | NEW |