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