Chromium Code Reviews| 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) { | |
|
Rico
2011/09/26 08:45:10
indention
ulan
2011/09/26 09:15:18
Done.
| |
| 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) { | |
|
Rico
2011/09/26 08:45:10
indention and put value on seperate line
ulan
2011/09/26 09:15:18
Done.
| |
| 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) { | |
|
Rico
2011/09/26 08:45:10
indention
ulan
2011/09/26 09:15:18
Done.
| |
| 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_' | |
|
Rico
2011/09/26 08:45:10
Capitalize I at start of comment
Rico
2011/09/26 08:45:10
period at the end of comment
ulan
2011/09/26 09:15:18
Done.
ulan
2011/09/26 09:15:18
Done.
| |
| 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) | |
|
Rico
2011/09/26 08:45:10
Please add {} around body when not on single line
ulan
2011/09/26 09:15:18
Done.
| |
| 1337 if (name_str[i] != prefix[i]) return Handle<Value>(); | |
| 1338 Handle<Object> self = info.This(); | |
| 1339 return self->GetHiddenValue(v8_str(name_str+i)); | |
| 1340 } | |
| 1341 | |
| 1342 Handle<Value> InterceptorSetter(Local<String> name, | |
| 1343 Local<Value> value, | |
| 1344 const AccessorInfo& info) { | |
| 1345 // intercept accesses that set certain integer values | |
|
Rico
2011/09/26 08:45:10
Capital I at start of comment, period at the end
ulan
2011/09/26 09:15:18
Done.
| |
| 1346 if (value->IsInt32() && value->Int32Value() < 10000) { | |
| 1347 Handle<Object> self = info.This(); | |
| 1348 self->SetHiddenValue(name, value); | |
| 1349 return value; | |
| 1350 } | |
| 1351 return Handle<Value>(); | |
| 1352 } | |
| 1353 | |
| 1354 void AddAccessor(Handle<FunctionTemplate> templ, | |
| 1355 Handle<String> name, | |
| 1356 v8::AccessorGetter getter, | |
| 1357 v8::AccessorSetter setter) { | |
| 1358 templ->PrototypeTemplate()->SetAccessor(name, getter, setter); | |
| 1359 } | |
| 1360 | |
| 1361 void AddInterceptor(Handle<FunctionTemplate> templ, | |
| 1362 v8::NamedPropertyGetter getter, | |
|
Rico
2011/09/26 08:45:10
Indention
ulan
2011/09/26 09:15:18
Done.
| |
| 1363 v8::NamedPropertySetter setter) { | |
| 1364 templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); | |
| 1365 } | |
| 1366 | |
| 1367 THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) { | |
| 1368 v8::HandleScope scope; | |
| 1369 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | |
| 1370 Handle<FunctionTemplate> child = FunctionTemplate::New(); | |
| 1371 child->Inherit(parent); | |
| 1372 AddAccessor(parent, v8_str("age"), | |
| 1373 SimpleAccessorGetter, SimpleAccessorSetter); | |
| 1374 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
| 1375 LocalContext env; | |
| 1376 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
| 1377 CompileRun("var child = new Child;" | |
| 1378 "child.age = 10;"); | |
| 1379 ExpectBoolean("child.hasOwnProperty('age')", false); | |
| 1380 ExpectInt32("child.age", 10); | |
| 1381 ExpectInt32("child.accessor_age", 10); | |
| 1382 } | |
| 1383 | |
| 1384 THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { | |
| 1385 v8::HandleScope scope; | |
| 1386 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | |
| 1387 Handle<FunctionTemplate> child = FunctionTemplate::New(); | |
| 1388 child->Inherit(parent); | |
| 1389 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
| 1390 LocalContext env; | |
| 1391 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
| 1392 CompileRun("var child = new Child;" | |
| 1393 "var parent = child.__proto__;" | |
| 1394 "Object.defineProperty(parent, 'age', " | |
| 1395 " {get: function(){ return this.accessor_age; }, " | |
| 1396 " set: function(v){ this.accessor_age = v; }, " | |
| 1397 " enumerable: true, configurable: true});" | |
| 1398 "child.age = 10;"); | |
| 1399 ExpectBoolean("child.hasOwnProperty('age')", false); | |
| 1400 ExpectInt32("child.age", 10); | |
| 1401 ExpectInt32("child.accessor_age", 10); | |
| 1402 } | |
| 1403 | |
| 1404 THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { | |
| 1405 v8::HandleScope scope; | |
| 1406 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | |
| 1407 Handle<FunctionTemplate> child = FunctionTemplate::New(); | |
| 1408 child->Inherit(parent); | |
| 1409 AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); | |
| 1410 LocalContext env; | |
| 1411 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
| 1412 CompileRun("var child = new Child;" | |
| 1413 "var parent = child.__proto__;" | |
| 1414 "parent.name = 'Alice';"); | |
| 1415 ExpectBoolean("child.hasOwnProperty('name')", false); | |
| 1416 ExpectString("child.name", "Alice"); | |
| 1417 CompileRun("child.name = 'Bob';"); | |
| 1418 ExpectString("child.name", "Bob"); | |
| 1419 ExpectBoolean("child.hasOwnProperty('name')", true); | |
| 1420 ExpectString("parent.name", "Alice"); | |
| 1421 } | |
| 1422 | |
| 1423 THREADED_TEST(SwitchFromInterceptorToAccessor) { | |
| 1424 v8::HandleScope scope; | |
| 1425 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | |
| 1426 Handle<FunctionTemplate> child = FunctionTemplate::New(); | |
| 1427 child->Inherit(parent); | |
| 1428 AddAccessor(parent, v8_str("age"), | |
| 1429 SimpleAccessorGetter, SimpleAccessorSetter); | |
| 1430 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
| 1431 LocalContext env; | |
| 1432 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
| 1433 CompileRun("var child = new Child;" | |
| 1434 "function setAge(i){ child.age = i; };" | |
| 1435 "for(var i = 0; i <= 10000; i++) setAge(i);"); | |
| 1436 // all i < 10000 go to interceptor | |
| 1437 ExpectInt32("child.interceptor_age", 9999); | |
| 1438 // the last i goes to accessor | |
| 1439 ExpectInt32("child.accessor_age", 10000); | |
| 1440 } | |
| 1441 | |
| 1442 THREADED_TEST(SwitchFromAccessorToInterceptor) { | |
| 1443 v8::HandleScope scope; | |
| 1444 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | |
| 1445 Handle<FunctionTemplate> child = FunctionTemplate::New(); | |
| 1446 child->Inherit(parent); | |
| 1447 AddAccessor(parent, v8_str("age"), | |
| 1448 SimpleAccessorGetter, SimpleAccessorSetter); | |
| 1449 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
| 1450 LocalContext env; | |
| 1451 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
| 1452 CompileRun("var child = new Child;" | |
| 1453 "function setAge(i){ child.age = i; };" | |
| 1454 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | |
| 1455 // all i >= 10000 go to accessor | |
| 1456 ExpectInt32("child.accessor_age", 10000); | |
| 1457 // the last i goes to interceptor | |
| 1458 ExpectInt32("child.interceptor_age", 9999); | |
| 1459 } | |
| 1460 | |
| 1461 THREADED_TEST(SwitchFromInterceptorToProperty) { | |
| 1462 v8::HandleScope scope; | |
| 1463 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | |
| 1464 Handle<FunctionTemplate> child = FunctionTemplate::New(); | |
| 1465 child->Inherit(parent); | |
| 1466 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
| 1467 LocalContext env; | |
| 1468 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
| 1469 CompileRun("var child = new Child;" | |
| 1470 "function setAge(i){ child.age = i; };" | |
| 1471 "for(var i = 0; i <= 10000; i++) setAge(i);"); | |
| 1472 // all i < 10000 go to interceptor | |
| 1473 ExpectInt32("child.interceptor_age", 9999); | |
| 1474 // the last i goes to child's own property | |
| 1475 ExpectInt32("child.age", 10000); | |
| 1476 } | |
| 1477 | |
| 1478 THREADED_TEST(SwitchFromPropertyToInterceptor) { | |
| 1479 v8::HandleScope scope; | |
| 1480 Handle<FunctionTemplate> parent = FunctionTemplate::New(); | |
| 1481 Handle<FunctionTemplate> child = FunctionTemplate::New(); | |
| 1482 child->Inherit(parent); | |
| 1483 AddInterceptor(child, InterceptorGetter, InterceptorSetter); | |
| 1484 LocalContext env; | |
| 1485 env->Global()->Set(v8_str("Child"), child->GetFunction()); | |
| 1486 CompileRun("var child = new Child;" | |
| 1487 "function setAge(i){ child.age = i; };" | |
| 1488 "for(var i = 20000; i >= 9999; i--) setAge(i);"); | |
| 1489 // all i >= 10000 go to child's own property | |
| 1490 ExpectInt32("child.age", 10000); | |
| 1491 // the last i goes to interceptor | |
| 1492 ExpectInt32("child.interceptor_age", 9999); | |
| 1493 } | |
| 1299 | 1494 |
| 1300 THREADED_TEST(NamedPropertyHandlerGetter) { | 1495 THREADED_TEST(NamedPropertyHandlerGetter) { |
| 1301 echo_named_call_count = 0; | 1496 echo_named_call_count = 0; |
| 1302 v8::HandleScope scope; | 1497 v8::HandleScope scope; |
| 1303 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); | 1498 v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(); |
| 1304 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, | 1499 templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty, |
| 1305 0, 0, 0, 0, | 1500 0, 0, 0, 0, |
| 1306 v8_str("data")); | 1501 v8_str("data")); |
| 1307 LocalContext env; | 1502 LocalContext env; |
| 1308 env->Global()->Set(v8_str("obj"), | 1503 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]"))); | 15404 CHECK(i->Equals(CompileRun("'abcbd'.replace(/b/g,func)[3]"))); |
| 15210 | 15405 |
| 15211 // TODO(1547): Make the following also return "i". | 15406 // TODO(1547): Make the following also return "i". |
| 15212 // Calling with environment record as base. | 15407 // Calling with environment record as base. |
| 15213 TestReceiver(o, context->Global(), "func()"); | 15408 TestReceiver(o, context->Global(), "func()"); |
| 15214 // Calling with no base. | 15409 // Calling with no base. |
| 15215 TestReceiver(o, context->Global(), "(1,func)()"); | 15410 TestReceiver(o, context->Global(), "(1,func)()"); |
| 15216 | 15411 |
| 15217 foreign_context.Dispose(); | 15412 foreign_context.Dispose(); |
| 15218 } | 15413 } |
| OLD | NEW |