Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(149)

Side by Side Diff: test/cctest/test-api.cc

Issue 7991007: Search prototypes for accessor setters if interceptor returns empty value. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« src/objects.cc ('K') | « src/objects.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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 }
OLDNEW
« src/objects.cc ('K') | « src/objects.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698