OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 using ::v8::Value; | 74 using ::v8::Value; |
75 | 75 |
76 | 76 |
77 static void ExpectString(const char* code, const char* expected) { | 77 static void ExpectString(const char* code, const char* expected) { |
78 Local<Value> result = CompileRun(code); | 78 Local<Value> result = CompileRun(code); |
79 CHECK(result->IsString()); | 79 CHECK(result->IsString()); |
80 String::AsciiValue ascii(result); | 80 String::AsciiValue ascii(result); |
81 CHECK_EQ(expected, *ascii); | 81 CHECK_EQ(expected, *ascii); |
82 } | 82 } |
83 | 83 |
| 84 static void ExpectInt32(const char* code, int expected) { |
| 85 Local<Value> result = CompileRun(code); |
| 86 CHECK(result->IsInt32()); |
| 87 CHECK_EQ(expected, result->Int32Value()); |
| 88 } |
84 | 89 |
85 static void ExpectBoolean(const char* code, bool expected) { | 90 static void ExpectBoolean(const char* code, bool expected) { |
86 Local<Value> result = CompileRun(code); | 91 Local<Value> result = CompileRun(code); |
87 CHECK(result->IsBoolean()); | 92 CHECK(result->IsBoolean()); |
88 CHECK_EQ(expected, result->BooleanValue()); | 93 CHECK_EQ(expected, result->BooleanValue()); |
89 } | 94 } |
90 | 95 |
91 | 96 |
92 static void ExpectTrue(const char* code) { | 97 static void ExpectTrue(const char* code) { |
93 ExpectBoolean(code, true); | 98 ExpectBoolean(code, true); |
(...skipping 1196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 | 1295 |
1291 | 1296 |
1292 static v8::Handle<Value> EchoNamedProperty(Local<String> name, | 1297 static v8::Handle<Value> EchoNamedProperty(Local<String> name, |
1293 const AccessorInfo& info) { | 1298 const AccessorInfo& info) { |
1294 ApiTestFuzzer::Fuzz(); | 1299 ApiTestFuzzer::Fuzz(); |
1295 CHECK_EQ(v8_str("data"), info.Data()); | 1300 CHECK_EQ(v8_str("data"), info.Data()); |
1296 echo_named_call_count++; | 1301 echo_named_call_count++; |
1297 return name; | 1302 return name; |
1298 } | 1303 } |
1299 | 1304 |
| 1305 // Helper functions for Interceptor/Accessor interaction tests |
| 1306 |
| 1307 Handle<Value> SimpleAccessorGetter(Local<String> name, |
| 1308 const AccessorInfo& info) { |
| 1309 Handle<Object> self = info.This(); |
| 1310 return self->Get(String::Concat(v8_str("accessor_"), name)); |
| 1311 } |
| 1312 |
| 1313 void SimpleAccessorSetter(Local<String> name, Local<Value> value, |
| 1314 const AccessorInfo& info) { |
| 1315 Handle<Object> self = info.This(); |
| 1316 self->Set(String::Concat(v8_str("accessor_"), name), value); |
| 1317 } |
| 1318 |
| 1319 Handle<Value> EmptyInterceptorGetter(Local<String> name, |
| 1320 const AccessorInfo& info) { |
| 1321 return Handle<Value>(); |
| 1322 } |
| 1323 |
| 1324 Handle<Value> EmptyInterceptorSetter(Local<String> name, |
| 1325 Local<Value> value, |
| 1326 const AccessorInfo& info) { |
| 1327 return Handle<Value>(); |
| 1328 } |
| 1329 |
| 1330 Handle<Value> InterceptorGetter(Local<String> name, |
| 1331 const AccessorInfo& info) { |
| 1332 // Intercept names that start with 'interceptor_'. |
| 1333 String::AsciiValue ascii(name); |
| 1334 char* name_str = *ascii; |
| 1335 char prefix[] = "interceptor_"; |
| 1336 int i; |
| 1337 for (i = 0; name_str[i] && prefix[i]; ++i) { |
| 1338 if (name_str[i] != prefix[i]) return Handle<Value>(); |
| 1339 } |
| 1340 Handle<Object> self = info.This(); |
| 1341 return self->GetHiddenValue(v8_str(name_str + i)); |
| 1342 } |
| 1343 |
| 1344 Handle<Value> InterceptorSetter(Local<String> name, |
| 1345 Local<Value> value, |
| 1346 const AccessorInfo& info) { |
| 1347 // Intercept accesses that set certain integer values. |
| 1348 if (value->IsInt32() && value->Int32Value() < 10000) { |
| 1349 Handle<Object> self = info.This(); |
| 1350 self->SetHiddenValue(name, value); |
| 1351 return value; |
| 1352 } |
| 1353 return Handle<Value>(); |
| 1354 } |
| 1355 |
| 1356 void AddAccessor(Handle<FunctionTemplate> templ, |
| 1357 Handle<String> name, |
| 1358 v8::AccessorGetter getter, |
| 1359 v8::AccessorSetter setter) { |
| 1360 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); |
| 1361 } |
| 1362 |
| 1363 void AddInterceptor(Handle<FunctionTemplate> templ, |
| 1364 v8::NamedPropertyGetter getter, |
| 1365 v8::NamedPropertySetter setter) { |
| 1366 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); |
| 1367 } |
| 1368 |
| 1369 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { |
| 1370 v8::HandleScope scope; |
| 1371 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1372 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1373 child->Inherit(parent); |
| 1374 AddAccessor(parent, v8_str("age"), |
| 1375 SimpleAccessorGetter, SimpleAccessorSetter); |
| 1376 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 1377 LocalContext env; |
| 1378 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1379 CompileRun("var child = new Child;" |
| 1380 "child.age = 10;"); |
| 1381 ExpectBoolean("child.hasOwnProperty('age')", false); |
| 1382 ExpectInt32("child.age", 10); |
| 1383 ExpectInt32("child.accessor_age", 10); |
| 1384 } |
| 1385 |
| 1386 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { |
| 1387 v8::HandleScope scope; |
| 1388 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1389 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1390 child->Inherit(parent); |
| 1391 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 1392 LocalContext env; |
| 1393 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1394 CompileRun("var child = new Child;" |
| 1395 "var parent = child.__proto__;" |
| 1396 "Object.defineProperty(parent, 'age', " |
| 1397 " {get: function(){ return this.accessor_age; }, " |
| 1398 " set: function(v){ this.accessor_age = v; }, " |
| 1399 " enumerable: true, configurable: true});" |
| 1400 "child.age = 10;"); |
| 1401 ExpectBoolean("child.hasOwnProperty('age')", false); |
| 1402 ExpectInt32("child.age", 10); |
| 1403 ExpectInt32("child.accessor_age", 10); |
| 1404 } |
| 1405 |
| 1406 THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { |
| 1407 v8::HandleScope scope; |
| 1408 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1409 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1410 child->Inherit(parent); |
| 1411 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
| 1412 LocalContext env; |
| 1413 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1414 CompileRun("var child = new Child;" |
| 1415 "var parent = child.__proto__;" |
| 1416 "parent.name = 'Alice';"); |
| 1417 ExpectBoolean("child.hasOwnProperty('name')", false); |
| 1418 ExpectString("child.name", "Alice"); |
| 1419 CompileRun("child.name = 'Bob';"); |
| 1420 ExpectString("child.name", "Bob"); |
| 1421 ExpectBoolean("child.hasOwnProperty('name')", true); |
| 1422 ExpectString("parent.name", "Alice"); |
| 1423 } |
| 1424 |
| 1425 THREADED_TEST(SwitchFromInterceptorToAccessor) { |
| 1426 v8::HandleScope scope; |
| 1427 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1428 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1429 child->Inherit(parent); |
| 1430 AddAccessor(parent, v8_str("age"), |
| 1431 SimpleAccessorGetter, SimpleAccessorSetter); |
| 1432 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1433 LocalContext env; |
| 1434 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1435 CompileRun("var child = new Child;" |
| 1436 "function setAge(i){ child.age = i; };" |
| 1437 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
| 1438 // All i < 10000 go to the interceptor. |
| 1439 ExpectInt32("child.interceptor_age", 9999); |
| 1440 // The last i goes to the accessor. |
| 1441 ExpectInt32("child.accessor_age", 10000); |
| 1442 } |
| 1443 |
| 1444 THREADED_TEST(SwitchFromAccessorToInterceptor) { |
| 1445 v8::HandleScope scope; |
| 1446 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1447 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1448 child->Inherit(parent); |
| 1449 AddAccessor(parent, v8_str("age"), |
| 1450 SimpleAccessorGetter, SimpleAccessorSetter); |
| 1451 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1452 LocalContext env; |
| 1453 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1454 CompileRun("var child = new Child;" |
| 1455 "function setAge(i){ child.age = i; };" |
| 1456 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
| 1457 // All i >= 10000 go to the accessor. |
| 1458 ExpectInt32("child.accessor_age", 10000); |
| 1459 // The last i goes to the interceptor. |
| 1460 ExpectInt32("child.interceptor_age", 9999); |
| 1461 } |
| 1462 |
| 1463 THREADED_TEST(SwitchFromInterceptorToProperty) { |
| 1464 v8::HandleScope scope; |
| 1465 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1466 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1467 child->Inherit(parent); |
| 1468 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1469 LocalContext env; |
| 1470 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1471 CompileRun("var child = new Child;" |
| 1472 "function setAge(i){ child.age = i; };" |
| 1473 "for(var i = 0; i <= 10000; i++) setAge(i);"); |
| 1474 // All i < 10000 go to the interceptor. |
| 1475 ExpectInt32("child.interceptor_age", 9999); |
| 1476 // The last i goes to child's own property. |
| 1477 ExpectInt32("child.age", 10000); |
| 1478 } |
| 1479 |
| 1480 THREADED_TEST(SwitchFromPropertyToInterceptor) { |
| 1481 v8::HandleScope scope; |
| 1482 Handle<FunctionTemplate> parent = FunctionTemplate::New(); |
| 1483 Handle<FunctionTemplate> child = FunctionTemplate::New(); |
| 1484 child->Inherit(parent); |
| 1485 AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
| 1486 LocalContext env; |
| 1487 env->Global()->Set(v8_str("Child"), child->GetFunction()); |
| 1488 CompileRun("var child = new Child;" |
| 1489 "function setAge(i){ child.age = i; };" |
| 1490 "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
| 1491 // All i >= 10000 go to child's own property. |
| 1492 ExpectInt32("child.age", 10000); |
| 1493 // The last i goes to the interceptor. |
| 1494 ExpectInt32("child.interceptor_age", 9999); |
| 1495 } |
1300 | 1496 |
1301 THREADED_TEST(NamedPropertyHandlerGetter) { | 1497 THREADED_TEST(NamedPropertyHandlerGetter) { |
1302 echo_named_call_count = 0; | 1498 echo_named_call_count = 0; |
1303 v8::HandleScope scope; | 1499 v8::HandleScope scope; |
1304 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1500 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
1305 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, | 1501 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, |
1306 0, 0, 0, 0, | 1502 0, 0, 0, 0, |
1307 v8_str("data")); | 1503 v8_str("data")); |
1308 LocalContext env; | 1504 LocalContext env; |
1309 env->Global()->Set(v8_str("obj"), | 1505 env->Global()->Set(v8_str("obj"), |
(...skipping 14120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15430 heap->UnlockString(*strings[i]); | 15626 heap->UnlockString(*strings[i]); |
15431 for (int j = 0; j < N; j++) { | 15627 for (int j = 0; j < N; j++) { |
15432 if (j <= i || j >= N/ 2) { | 15628 if (j <= i || j >= N/ 2) { |
15433 CHECK(!heap->IsStringLocked(*strings[j])); | 15629 CHECK(!heap->IsStringLocked(*strings[j])); |
15434 } else { | 15630 } else { |
15435 CHECK(heap->IsStringLocked(*strings[j])); | 15631 CHECK(heap->IsStringLocked(*strings[j])); |
15436 } | 15632 } |
15437 } | 15633 } |
15438 } | 15634 } |
15439 } | 15635 } |
OLD | NEW |