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

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

Issue 2272383002: [api] Add interceptor for defineProperty(). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@DefineProperty
Patch Set: Add test for intercepting Object.freeze(). Created 4 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
« src/objects.cc ('K') | « src/objects-inl.h ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 6
7 #include "test/cctest/test-api.h" 7 #include "test/cctest/test-api.h"
8 8
9 #include "include/v8-util.h" 9 #include "include/v8-util.h"
10 #include "src/api.h" 10 #include "src/api.h"
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 232
233 void CheckThisNamedPropertyHandler( 233 void CheckThisNamedPropertyHandler(
234 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { 234 Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
235 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler)); 235 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler));
236 ApiTestFuzzer::Fuzz(); 236 ApiTestFuzzer::Fuzz();
237 CHECK(info.This() 237 CHECK(info.This()
238 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) 238 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom)
239 .FromJust()); 239 .FromJust());
240 } 240 }
241 241
242 void CheckThisIndexedPropertyDefiner(
243 uint32_t index, const v8::PropertyDescriptor& desc,
244 const v8::PropertyCallbackInfo<v8::Value>& info) {
245 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyDefiner));
246 ApiTestFuzzer::Fuzz();
247 CHECK(info.This()
248 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom)
249 .FromJust());
250 }
251
252 void CheckThisNamedPropertyDefiner(
253 Local<Name> property, const v8::PropertyDescriptor& desc,
254 const v8::PropertyCallbackInfo<v8::Value>& info) {
255 CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDefiner));
256 ApiTestFuzzer::Fuzz();
257 CHECK(info.This()
258 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom)
259 .FromJust());
260 }
261
242 void CheckThisIndexedPropertySetter( 262 void CheckThisIndexedPropertySetter(
243 uint32_t index, Local<Value> value, 263 uint32_t index, Local<Value> value,
244 const v8::PropertyCallbackInfo<v8::Value>& info) { 264 const v8::PropertyCallbackInfo<v8::Value>& info) {
245 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); 265 CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter));
246 ApiTestFuzzer::Fuzz(); 266 ApiTestFuzzer::Fuzz();
247 CHECK(info.This() 267 CHECK(info.This()
248 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom) 268 ->Equals(info.GetIsolate()->GetCurrentContext(), bottom)
249 .FromJust()); 269 .FromJust());
250 } 270 }
251 271
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 .ToLocalChecked() 1116 .ToLocalChecked()
1097 ->BooleanValue(env.local()) 1117 ->BooleanValue(env.local())
1098 .FromJust()); 1118 .FromJust());
1099 CHECK(v8_compile("delete obj.myProperty") 1119 CHECK(v8_compile("delete obj.myProperty")
1100 ->Run(env.local()) 1120 ->Run(env.local())
1101 .ToLocalChecked() 1121 .ToLocalChecked()
1102 ->BooleanValue(env.local()) 1122 ->BooleanValue(env.local())
1103 .FromJust()); 1123 .FromJust());
1104 } 1124 }
1105 1125
1126 namespace {
1127 void NotInterceptingPropertyDefineCallback(
1128 Local<Name> name, const v8::PropertyDescriptor& desc,
1129 const v8::PropertyCallbackInfo<v8::Value>& info) {
1130 // Do not intercept by not calling info.GetReturnValue().Set()
1131 }
1132
1133 void InterceptingPropertyDefineCallback(
1134 Local<Name> name, const v8::PropertyDescriptor& desc,
1135 const v8::PropertyCallbackInfo<v8::Value>& info) {
1136 // intercept the callback by setting a non-empty handle
1137 info.GetReturnValue().Set(name);
1138 }
1139 } // namespace
1140 THREADED_TEST(PropertyDefinerCallback) {
1141 v8::HandleScope scope(CcTest::isolate());
1142 LocalContext env;
1143
1144 { // Intercept defineProperty()
1145 v8::Local<v8::FunctionTemplate> templ =
1146 v8::FunctionTemplate::New(CcTest::isolate());
1147 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1148 0, 0, 0, 0, 0, NotInterceptingPropertyDefineCallback));
1149 env->Global()
1150 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
1151 .ToLocalChecked()
1152 ->NewInstance(env.local())
1153 .ToLocalChecked())
1154 .FromJust();
1155 const char* code =
1156 "obj.x = 17; "
1157 "Object.defineProperty(obj, 'x', {value: 42});"
1158 "obj.x;";
1159 CHECK_EQ(42, v8_compile(code)
1160 ->Run(env.local())
1161 .ToLocalChecked()
1162 ->Int32Value(env.local())
1163 .FromJust());
1164 }
1165
1166 { // Do not intercept defineProperty()
1167 v8::Local<v8::FunctionTemplate> templ2 =
1168 v8::FunctionTemplate::New(CcTest::isolate());
1169 templ2->InstanceTemplate()->SetHandler(
1170 v8::NamedPropertyHandlerConfiguration(
1171 0, 0, 0, 0, 0, InterceptingPropertyDefineCallback));
1172 env->Global()
1173 ->Set(env.local(), v8_str("obj2"), templ2->GetFunction(env.local())
1174 .ToLocalChecked()
1175 ->NewInstance(env.local())
1176 .ToLocalChecked())
1177 .FromJust();
1178
1179 const char* code =
1180 "obj2.x = 17; "
1181 "Object.defineProperty(obj2, 'x', {value: 42});"
1182 "obj2.x;";
1183 CHECK_EQ(17, v8_compile(code)
1184 ->Run(env.local())
1185 .ToLocalChecked()
1186 ->Int32Value(env.local())
1187 .FromJust());
1188 }
1189 }
1190
1191 // Test that freeze() is intercepted.
1192 THREADED_TEST(PropertyDefinerCallbackForFreeze) {
1193 v8::HandleScope scope(CcTest::isolate());
1194 LocalContext env;
1195 v8::Local<v8::FunctionTemplate> templ =
1196 v8::FunctionTemplate::New(CcTest::isolate());
1197 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1198 0, 0, 0, 0, 0, InterceptingPropertyDefineCallback));
1199 env->Global()
1200 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
1201 .ToLocalChecked()
1202 ->NewInstance(env.local())
1203 .ToLocalChecked())
1204 .FromJust();
1205 const char* code =
1206 "obj.x = 17; "
1207 "Object.freeze(obj.x); "
1208 "Object.isFrozen(obj.x);";
1209
1210 CHECK(v8_compile(code)
1211 ->Run(env.local())
1212 .ToLocalChecked()
1213 ->BooleanValue(env.local())
1214 .FromJust());
1215 }
1216
1217 // Check that the descriptor passed to the callback is enumerable.
1218 namespace {
1219 void CheckEnumerablePropertyDefineCallback(
1220 Local<Name> name, const v8::PropertyDescriptor& desc,
1221 const v8::PropertyCallbackInfo<v8::Value>& info) {
1222 CHECK(desc.has_value());
1223 CHECK_EQ(42, desc.value()
1224 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1225 .FromJust());
1226 CHECK(desc.has_enumerable());
1227 CHECK(desc.enumerable());
1228 CHECK(!desc.has_writable());
1229
1230 // intercept the callback by setting a non-empty handle
1231 info.GetReturnValue().Set(name);
1232 }
1233 } // namespace
1234 THREADED_TEST(PropertyDefinerCallbackEnumerable) {
1235 v8::HandleScope scope(CcTest::isolate());
1236 LocalContext env;
1237 v8::Local<v8::FunctionTemplate> templ =
1238 v8::FunctionTemplate::New(CcTest::isolate());
1239 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1240 0, 0, 0, 0, 0, CheckEnumerablePropertyDefineCallback));
1241 env->Global()
1242 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
1243 .ToLocalChecked()
1244 ->NewInstance(env.local())
1245 .ToLocalChecked())
1246 .FromJust();
1247 const char* code =
1248 "obj.x = 17; "
1249 "Object.defineProperty(obj, 'x', {value: 42, enumerable: true});"
1250 "obj.x;";
1251 CHECK_EQ(17, v8_compile(code)
1252 ->Run(env.local())
1253 .ToLocalChecked()
1254 ->Int32Value(env.local())
1255 .FromJust());
1256 }
1257
1258 // Check that the descriptor passed to the callback is configurable.
1259 namespace {
1260 void CheckConfigurablePropertyDefineCallback(
1261 Local<Name> name, const v8::PropertyDescriptor& desc,
1262 const v8::PropertyCallbackInfo<v8::Value>& info) {
1263 CHECK(desc.has_value());
1264 CHECK_EQ(42, desc.value()
1265 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1266 .FromJust());
1267 CHECK(desc.has_configurable());
1268 CHECK(desc.configurable());
1269
1270 // intercept the callback by setting a non-empty handle
1271 info.GetReturnValue().Set(name);
1272 }
1273 } // namespace
1274 THREADED_TEST(PropertyDefinerCallbackConfigurable) {
1275 v8::HandleScope scope(CcTest::isolate());
1276 LocalContext env;
1277 v8::Local<v8::FunctionTemplate> templ =
1278 v8::FunctionTemplate::New(CcTest::isolate());
1279 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1280 0, 0, 0, 0, 0, CheckConfigurablePropertyDefineCallback));
1281 env->Global()
1282 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
1283 .ToLocalChecked()
1284 ->NewInstance(env.local())
1285 .ToLocalChecked())
1286 .FromJust();
1287 const char* code =
1288 "obj.x = 17; "
1289 "Object.defineProperty(obj, 'x', {value: 42, configurable: true});"
1290 "obj.x;";
1291 CHECK_EQ(17, v8_compile(code)
1292 ->Run(env.local())
1293 .ToLocalChecked()
1294 ->Int32Value(env.local())
1295 .FromJust());
1296 }
1297
1298 // Check that the descriptor passed to the callback is writable.
1299 namespace {
1300 void CheckWritablePropertyDefineCallback(
1301 Local<Name> name, const v8::PropertyDescriptor& desc,
1302 const v8::PropertyCallbackInfo<v8::Value>& info) {
1303 CHECK(desc.has_writable());
1304 CHECK(desc.writable());
1305
1306 // intercept the callback by setting a non-empty handle
1307 info.GetReturnValue().Set(name);
1308 }
1309 } // namespace
1310 THREADED_TEST(PropertyDefinerCallbackWritable) {
1311 v8::HandleScope scope(CcTest::isolate());
1312 LocalContext env;
1313 v8::Local<v8::FunctionTemplate> templ =
1314 v8::FunctionTemplate::New(CcTest::isolate());
1315 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1316 0, 0, 0, 0, 0, CheckWritablePropertyDefineCallback));
1317 env->Global()
1318 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
1319 .ToLocalChecked()
1320 ->NewInstance(env.local())
1321 .ToLocalChecked())
1322 .FromJust();
1323 const char* code =
1324 "obj.x = 17; "
1325 "Object.defineProperty(obj, 'x', {value: 42, writable: true});"
1326 "obj.x;";
1327 CHECK_EQ(17, v8_compile(code)
1328 ->Run(env.local())
1329 .ToLocalChecked()
1330 ->Int32Value(env.local())
1331 .FromJust());
1332 }
1333
1334 // Check that the descriptor passed to the callback has a getter.
1335 namespace {
1336 void CheckGetterPropertyDefineCallback(
1337 Local<Name> name, const v8::PropertyDescriptor& desc,
1338 const v8::PropertyCallbackInfo<v8::Value>& info) {
1339 CHECK(desc.has_get());
1340 CHECK(!desc.has_set());
1341 // intercept the callback by setting a non-empty handle
1342 info.GetReturnValue().Set(name);
1343 }
1344 } // namespace
1345 THREADED_TEST(PropertyDefinerCallbackWithGetter) {
1346 v8::HandleScope scope(CcTest::isolate());
1347 LocalContext env;
1348 v8::Local<v8::FunctionTemplate> templ =
1349 v8::FunctionTemplate::New(CcTest::isolate());
1350 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1351 0, 0, 0, 0, 0, CheckGetterPropertyDefineCallback));
1352 env->Global()
1353 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
1354 .ToLocalChecked()
1355 ->NewInstance(env.local())
1356 .ToLocalChecked())
1357 .FromJust();
1358 const char* code =
1359 "obj.x = 17;"
1360 "Object.defineProperty(obj, 'x', {get: function() {return 42;}});"
1361 "obj.x;";
1362 CHECK_EQ(17, v8_compile(code)
1363 ->Run(env.local())
1364 .ToLocalChecked()
1365 ->Int32Value(env.local())
1366 .FromJust());
1367 }
1368
1369 // Check that the descriptor passed to the callback has a setter.
1370 namespace {
1371 void CheckSetterPropertyDefineCallback(
1372 Local<Name> name, const v8::PropertyDescriptor& desc,
1373 const v8::PropertyCallbackInfo<v8::Value>& info) {
1374 CHECK(desc.has_set());
1375 CHECK(!desc.has_get());
1376 // intercept the callback by setting a non-empty handle
1377 info.GetReturnValue().Set(name);
1378 }
1379 } // namespace
1380 THREADED_TEST(PropertyDefinerCallbackWithSetter) {
1381 v8::HandleScope scope(CcTest::isolate());
1382 LocalContext env;
1383 v8::Local<v8::FunctionTemplate> templ =
1384 v8::FunctionTemplate::New(CcTest::isolate());
1385 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1386 0, 0, 0, 0, 0, CheckSetterPropertyDefineCallback));
1387 env->Global()
1388 ->Set(env.local(), v8_str("obj"), templ->GetFunction(env.local())
1389 .ToLocalChecked()
1390 ->NewInstance(env.local())
1391 .ToLocalChecked())
1392 .FromJust();
1393 const char* code =
1394 "Object.defineProperty(obj, 'x', {set: function() {return 42;}});"
1395 "obj.x = 17;";
1396 CHECK_EQ(17, v8_compile(code)
1397 ->Run(env.local())
1398 .ToLocalChecked()
1399 ->Int32Value(env.local())
1400 .FromJust());
1401 }
1106 1402
1107 int echo_indexed_call_count = 0; 1403 int echo_indexed_call_count = 0;
1108 1404
1109 1405
1110 static void EchoIndexedProperty( 1406 static void EchoIndexedProperty(
1111 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) { 1407 uint32_t index, const v8::PropertyCallbackInfo<v8::Value>& info) {
1112 ApiTestFuzzer::Fuzz(); 1408 ApiTestFuzzer::Fuzz();
1113 CHECK(v8_num(637) 1409 CHECK(v8_num(637)
1114 ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data()) 1410 ->Equals(info.GetIsolate()->GetCurrentContext(), info.Data())
1115 .FromJust()); 1411 .FromJust());
(...skipping 27 matching lines...) Expand all
1143 THREADED_TEST(PropertyHandlerInPrototype) { 1439 THREADED_TEST(PropertyHandlerInPrototype) {
1144 LocalContext env; 1440 LocalContext env;
1145 v8::Isolate* isolate = env->GetIsolate(); 1441 v8::Isolate* isolate = env->GetIsolate();
1146 v8::HandleScope scope(isolate); 1442 v8::HandleScope scope(isolate);
1147 1443
1148 // Set up a prototype chain with three interceptors. 1444 // Set up a prototype chain with three interceptors.
1149 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); 1445 v8::Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
1150 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( 1446 templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration(
1151 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, 1447 CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter,
1152 CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, 1448 CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter,
1153 CheckThisIndexedPropertyEnumerator)); 1449 CheckThisIndexedPropertyEnumerator, CheckThisIndexedPropertyDefiner));
1154 1450
1155 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( 1451 templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
1156 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, 1452 CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter,
1157 CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, 1453 CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter,
1158 CheckThisNamedPropertyEnumerator)); 1454 CheckThisNamedPropertyEnumerator, CheckThisNamedPropertyDefiner));
1159 1455
1160 bottom = templ->GetFunction(env.local()) 1456 bottom = templ->GetFunction(env.local())
1161 .ToLocalChecked() 1457 .ToLocalChecked()
1162 ->NewInstance(env.local()) 1458 ->NewInstance(env.local())
1163 .ToLocalChecked(); 1459 .ToLocalChecked();
1164 Local<v8::Object> top = templ->GetFunction(env.local()) 1460 Local<v8::Object> top = templ->GetFunction(env.local())
1165 .ToLocalChecked() 1461 .ToLocalChecked()
1166 ->NewInstance(env.local()) 1462 ->NewInstance(env.local())
1167 .ToLocalChecked(); 1463 .ToLocalChecked();
1168 Local<v8::Object> middle = templ->GetFunction(env.local()) 1464 Local<v8::Object> middle = templ->GetFunction(env.local())
(...skipping 16 matching lines...) Expand all
1185 // Indexed and named query. 1481 // Indexed and named query.
1186 CompileRun("0 in obj"); 1482 CompileRun("0 in obj");
1187 CompileRun("'x' in obj"); 1483 CompileRun("'x' in obj");
1188 1484
1189 // Indexed and named deleter. 1485 // Indexed and named deleter.
1190 CompileRun("delete obj[0]"); 1486 CompileRun("delete obj[0]");
1191 CompileRun("delete obj.x"); 1487 CompileRun("delete obj.x");
1192 1488
1193 // Enumerators. 1489 // Enumerators.
1194 CompileRun("for (var p in obj) ;"); 1490 CompileRun("for (var p in obj) ;");
1491
1492 // Indexed and named definer.
1493 CompileRun("Object.defineProperty(obj, 2, {});");
1494 CompileRun("Object.defineProperty(obj, 'z', {});");
1195 } 1495 }
1196 1496
1197 1497
1198 bool is_bootstrapping = false; 1498 bool is_bootstrapping = false;
1199 static void PrePropertyHandlerGet( 1499 static void PrePropertyHandlerGet(
1200 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { 1500 Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
1201 ApiTestFuzzer::Fuzz(); 1501 ApiTestFuzzer::Fuzz();
1202 if (!is_bootstrapping && 1502 if (!is_bootstrapping &&
1203 v8_str("pre") 1503 v8_str("pre")
1204 ->Equals(info.GetIsolate()->GetCurrentContext(), key) 1504 ->Equals(info.GetIsolate()->GetCurrentContext(), key)
(...skipping 2780 matching lines...) Expand 10 before | Expand all | Expand 10 after
3985 ->Set(env.local(), v8_str("Fun"), 4285 ->Set(env.local(), v8_str("Fun"),
3986 fun_templ->GetFunction(env.local()).ToLocalChecked()) 4286 fun_templ->GetFunction(env.local()).ToLocalChecked())
3987 .FromJust()); 4287 .FromJust());
3988 4288
3989 CompileRun( 4289 CompileRun(
3990 "var f = new Fun();" 4290 "var f = new Fun();"
3991 "Number.prototype.__proto__ = f;" 4291 "Number.prototype.__proto__ = f;"
3992 "var a = 42;" 4292 "var a = 42;"
3993 "for (var i = 0; i<3; i++) { a.foo; }"); 4293 "for (var i = 0; i<3; i++) { a.foo; }");
3994 } 4294 }
OLDNEW
« src/objects.cc ('K') | « src/objects-inl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698