| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 26 matching lines...) Expand all Loading... |
| 37 using ::v8::ObjectTemplate; | 37 using ::v8::ObjectTemplate; |
| 38 using ::v8::Value; | 38 using ::v8::Value; |
| 39 using ::v8::Context; | 39 using ::v8::Context; |
| 40 using ::v8::Local; | 40 using ::v8::Local; |
| 41 using ::v8::String; | 41 using ::v8::String; |
| 42 using ::v8::Script; | 42 using ::v8::Script; |
| 43 using ::v8::Function; | 43 using ::v8::Function; |
| 44 using ::v8::AccessorInfo; | 44 using ::v8::AccessorInfo; |
| 45 using ::v8::Extension; | 45 using ::v8::Extension; |
| 46 | 46 |
| 47 static v8::Handle<Value> handle_property(Local<String> name, | 47 static void handle_property(Local<String> name, |
| 48 const AccessorInfo&) { | 48 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 49 ApiTestFuzzer::Fuzz(); | 49 ApiTestFuzzer::Fuzz(); |
| 50 return v8_num(900); | 50 info.GetReturnValue().Set(v8_num(900)); |
| 51 } | 51 } |
| 52 | 52 |
| 53 | 53 |
| 54 THREADED_TEST(PropertyHandler) { | 54 THREADED_TEST(PropertyHandler) { |
| 55 LocalContext env; | 55 LocalContext env; |
| 56 v8::HandleScope scope(env->GetIsolate()); | 56 v8::HandleScope scope(env->GetIsolate()); |
| 57 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 57 Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
| 58 fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property); | 58 fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property); |
| 59 Local<Function> fun = fun_templ->GetFunction(); | 59 Local<Function> fun = fun_templ->GetFunction(); |
| 60 env->Global()->Set(v8_str("Fun"), fun); | 60 env->Global()->Set(v8_str("Fun"), fun); |
| 61 Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;"); | 61 Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;"); |
| 62 CHECK_EQ(900, getter->Run()->Int32Value()); | 62 CHECK_EQ(900, getter->Run()->Int32Value()); |
| 63 Local<Script> setter = v8_compile("obj.foo = 901;"); | 63 Local<Script> setter = v8_compile("obj.foo = 901;"); |
| 64 CHECK_EQ(901, setter->Run()->Int32Value()); | 64 CHECK_EQ(901, setter->Run()->Int32Value()); |
| 65 } | 65 } |
| 66 | 66 |
| 67 | 67 |
| 68 static v8::Handle<Value> GetIntValue(Local<String> property, | 68 static void GetIntValue(Local<String> property, |
| 69 const AccessorInfo& info) { | 69 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 70 ApiTestFuzzer::Fuzz(); | 70 ApiTestFuzzer::Fuzz(); |
| 71 int* value = | 71 int* value = |
| 72 static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); | 72 static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); |
| 73 return v8_num(*value); | 73 info.GetReturnValue().Set(v8_num(*value)); |
| 74 } | 74 } |
| 75 | 75 |
| 76 | 76 |
| 77 static void SetIntValue(Local<String> property, | 77 static void SetIntValue(Local<String> property, |
| 78 Local<Value> value, | 78 Local<Value> value, |
| 79 const AccessorInfo& info) { | 79 const v8::PropertyCallbackInfo<void>& info) { |
| 80 int* field = | 80 int* field = |
| 81 static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); | 81 static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value()); |
| 82 *field = value->Int32Value(); | 82 *field = value->Int32Value(); |
| 83 } | 83 } |
| 84 | 84 |
| 85 int foo, bar, baz; | 85 int foo, bar, baz; |
| 86 | 86 |
| 87 THREADED_TEST(GlobalVariableAccess) { | 87 THREADED_TEST(GlobalVariableAccess) { |
| 88 foo = 0; | 88 foo = 0; |
| 89 bar = -4; | 89 bar = -4; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 107 CHECK_EQ(bar, -3); | 107 CHECK_EQ(bar, -3); |
| 108 CHECK_EQ(foo, 7); | 108 CHECK_EQ(foo, 7); |
| 109 } | 109 } |
| 110 | 110 |
| 111 | 111 |
| 112 static int x_register = 0; | 112 static int x_register = 0; |
| 113 static v8::Handle<v8::Object> x_receiver; | 113 static v8::Handle<v8::Object> x_receiver; |
| 114 static v8::Handle<v8::Object> x_holder; | 114 static v8::Handle<v8::Object> x_holder; |
| 115 | 115 |
| 116 | 116 |
| 117 static v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) { | 117 static void XGetter(Local<String> name, |
| 118 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 118 ApiTestFuzzer::Fuzz(); | 119 ApiTestFuzzer::Fuzz(); |
| 119 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 120 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 120 CHECK_EQ(isolate, info.GetIsolate()); | 121 CHECK_EQ(isolate, info.GetIsolate()); |
| 121 CHECK_EQ(x_receiver, info.This()); | 122 CHECK_EQ(x_receiver, info.This()); |
| 122 CHECK_EQ(x_holder, info.Holder()); | 123 CHECK_EQ(x_holder, info.Holder()); |
| 123 return v8_num(x_register); | 124 info.GetReturnValue().Set(v8_num(x_register)); |
| 124 } | 125 } |
| 125 | 126 |
| 126 | 127 |
| 127 static void XSetter(Local<String> name, | 128 static void XSetter(Local<String> name, |
| 128 Local<Value> value, | 129 Local<Value> value, |
| 129 const AccessorInfo& info) { | 130 const v8::PropertyCallbackInfo<void>& info) { |
| 130 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 131 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
| 131 CHECK_EQ(isolate, info.GetIsolate()); | 132 CHECK_EQ(isolate, info.GetIsolate()); |
| 132 CHECK_EQ(x_holder, info.This()); | 133 CHECK_EQ(x_holder, info.This()); |
| 133 CHECK_EQ(x_holder, info.Holder()); | 134 CHECK_EQ(x_holder, info.Holder()); |
| 134 x_register = value->Int32Value(); | 135 x_register = value->Int32Value(); |
| 135 } | 136 } |
| 136 | 137 |
| 137 | 138 |
| 138 THREADED_TEST(AccessorIC) { | 139 THREADED_TEST(AccessorIC) { |
| 139 LocalContext context; | 140 LocalContext context; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 153 "}" | 154 "}" |
| 154 "result")); | 155 "result")); |
| 155 CHECK_EQ(10, array->Length()); | 156 CHECK_EQ(10, array->Length()); |
| 156 for (int i = 0; i < 10; i++) { | 157 for (int i = 0; i < 10; i++) { |
| 157 v8::Handle<Value> entry = array->Get(v8::Integer::New(i)); | 158 v8::Handle<Value> entry = array->Get(v8::Integer::New(i)); |
| 158 CHECK_EQ(v8::Integer::New(i), entry); | 159 CHECK_EQ(v8::Integer::New(i), entry); |
| 159 } | 160 } |
| 160 } | 161 } |
| 161 | 162 |
| 162 | 163 |
| 163 static v8::Handle<Value> AccessorProhibitsOverwritingGetter( | 164 static void AccessorProhibitsOverwritingGetter( |
| 164 Local<String> name, | 165 Local<String> name, |
| 165 const AccessorInfo& info) { | 166 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 166 ApiTestFuzzer::Fuzz(); | 167 ApiTestFuzzer::Fuzz(); |
| 167 return v8::True(); | 168 info.GetReturnValue().Set(true); |
| 168 } | 169 } |
| 169 | 170 |
| 170 | 171 |
| 171 THREADED_TEST(AccessorProhibitsOverwriting) { | 172 THREADED_TEST(AccessorProhibitsOverwriting) { |
| 172 LocalContext context; | 173 LocalContext context; |
| 173 v8::HandleScope scope(context->GetIsolate()); | 174 v8::HandleScope scope(context->GetIsolate()); |
| 174 Local<ObjectTemplate> templ = ObjectTemplate::New(); | 175 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
| 175 templ->SetAccessor(v8_str("x"), | 176 templ->SetAccessor(v8_str("x"), |
| 176 AccessorProhibitsOverwritingGetter, | 177 AccessorProhibitsOverwritingGetter, |
| 177 0, | 178 0, |
| (...skipping 23 matching lines...) Expand all Loading... |
| 201 "obj2 = {};" | 202 "obj2 = {};" |
| 202 "obj2.__proto__ = obj;" | 203 "obj2.__proto__ = obj;" |
| 203 "obj2.__defineSetter__('x', function() { setter_called = true; });" | 204 "obj2.__defineSetter__('x', function() { setter_called = true; });" |
| 204 "obj2.x = 42;" | 205 "obj2.x = 42;" |
| 205 "setter_called"); | 206 "setter_called"); |
| 206 CHECK(!value->BooleanValue()); | 207 CHECK(!value->BooleanValue()); |
| 207 } | 208 } |
| 208 | 209 |
| 209 | 210 |
| 210 template <int C> | 211 template <int C> |
| 211 static v8::Handle<Value> HandleAllocatingGetter(Local<String> name, | 212 static void HandleAllocatingGetter( |
| 212 const AccessorInfo& info) { | 213 Local<String> name, |
| 214 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 213 ApiTestFuzzer::Fuzz(); | 215 ApiTestFuzzer::Fuzz(); |
| 214 for (int i = 0; i < C; i++) | 216 for (int i = 0; i < C; i++) |
| 215 v8::String::New("foo"); | 217 v8::String::New("foo"); |
| 216 return v8::String::New("foo"); | 218 info.GetReturnValue().Set(v8::String::New("foo")); |
| 217 } | 219 } |
| 218 | 220 |
| 219 | 221 |
| 220 THREADED_TEST(HandleScopePop) { | 222 THREADED_TEST(HandleScopePop) { |
| 221 LocalContext context; | 223 LocalContext context; |
| 222 v8::HandleScope scope(context->GetIsolate()); | 224 v8::HandleScope scope(context->GetIsolate()); |
| 223 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 225 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 224 obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>); | 226 obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>); |
| 225 obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>); | 227 obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>); |
| 226 v8::Handle<v8::Object> inst = obj->NewInstance(); | 228 v8::Handle<v8::Object> inst = obj->NewInstance(); |
| 227 context->Global()->Set(v8::String::New("obj"), inst); | 229 context->Global()->Set(v8::String::New("obj"), inst); |
| 228 i::Isolate* isolate = i::Isolate::Current(); | 230 i::Isolate* isolate = i::Isolate::Current(); |
| 229 int count_before = i::HandleScope::NumberOfHandles(isolate); | 231 int count_before = i::HandleScope::NumberOfHandles(isolate); |
| 230 { | 232 { |
| 231 v8::HandleScope scope(context->GetIsolate()); | 233 v8::HandleScope scope(context->GetIsolate()); |
| 232 CompileRun( | 234 CompileRun( |
| 233 "for (var i = 0; i < 1000; i++) {" | 235 "for (var i = 0; i < 1000; i++) {" |
| 234 " obj.one;" | 236 " obj.one;" |
| 235 " obj.many;" | 237 " obj.many;" |
| 236 "}"); | 238 "}"); |
| 237 } | 239 } |
| 238 int count_after = i::HandleScope::NumberOfHandles(isolate); | 240 int count_after = i::HandleScope::NumberOfHandles(isolate); |
| 239 CHECK_EQ(count_before, count_after); | 241 CHECK_EQ(count_before, count_after); |
| 240 } | 242 } |
| 241 | 243 |
| 242 static v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name, | 244 static void CheckAccessorArgsCorrect( |
| 243 const AccessorInfo& info) { | 245 Local<String> name, |
| 246 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 244 CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); | 247 CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); |
| 245 CHECK(info.This() == info.Holder()); | 248 CHECK(info.This() == info.Holder()); |
| 246 CHECK(info.Data()->Equals(v8::String::New("data"))); | 249 CHECK(info.Data()->Equals(v8::String::New("data"))); |
| 247 ApiTestFuzzer::Fuzz(); | 250 ApiTestFuzzer::Fuzz(); |
| 248 CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); | 251 CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); |
| 249 CHECK(info.This() == info.Holder()); | 252 CHECK(info.This() == info.Holder()); |
| 250 CHECK(info.Data()->Equals(v8::String::New("data"))); | 253 CHECK(info.Data()->Equals(v8::String::New("data"))); |
| 251 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); | 254 HEAP->CollectAllGarbage(i::Heap::kNoGCFlags); |
| 252 CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); | 255 CHECK(info.GetIsolate() == v8::Isolate::GetCurrent()); |
| 253 CHECK(info.This() == info.Holder()); | 256 CHECK(info.This() == info.Holder()); |
| 254 CHECK(info.Data()->Equals(v8::String::New("data"))); | 257 CHECK(info.Data()->Equals(v8::String::New("data"))); |
| 255 return v8::Integer::New(17); | 258 info.GetReturnValue().Set(17); |
| 256 } | 259 } |
| 257 | 260 |
| 258 THREADED_TEST(DirectCall) { | 261 THREADED_TEST(DirectCall) { |
| 259 LocalContext context; | 262 LocalContext context; |
| 260 v8::HandleScope scope(context->GetIsolate()); | 263 v8::HandleScope scope(context->GetIsolate()); |
| 261 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 264 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 262 obj->SetAccessor(v8_str("xxx"), | 265 obj->SetAccessor(v8_str("xxx"), |
| 263 CheckAccessorArgsCorrect, | 266 CheckAccessorArgsCorrect, |
| 264 NULL, | 267 NULL, |
| 265 v8::String::New("data")); | 268 v8::String::New("data")); |
| 266 v8::Handle<v8::Object> inst = obj->NewInstance(); | 269 v8::Handle<v8::Object> inst = obj->NewInstance(); |
| 267 context->Global()->Set(v8::String::New("obj"), inst); | 270 context->Global()->Set(v8::String::New("obj"), inst); |
| 268 Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); | 271 Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); |
| 269 for (int i = 0; i < 10; i++) { | 272 for (int i = 0; i < 10; i++) { |
| 270 Local<Value> result = scr->Run(); | 273 Local<Value> result = scr->Run(); |
| 271 CHECK(!result.IsEmpty()); | 274 CHECK(!result.IsEmpty()); |
| 272 CHECK_EQ(17, result->Int32Value()); | 275 CHECK_EQ(17, result->Int32Value()); |
| 273 } | 276 } |
| 274 } | 277 } |
| 275 | 278 |
| 276 static v8::Handle<Value> EmptyGetter(Local<String> name, | 279 static void EmptyGetter(Local<String> name, |
| 277 const AccessorInfo& info) { | 280 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 278 CheckAccessorArgsCorrect(name, info); | 281 CheckAccessorArgsCorrect(name, info); |
| 279 ApiTestFuzzer::Fuzz(); | 282 ApiTestFuzzer::Fuzz(); |
| 280 CheckAccessorArgsCorrect(name, info); | 283 CheckAccessorArgsCorrect(name, info); |
| 281 return v8::Handle<v8::Value>(); | 284 info.GetReturnValue().Set(v8::Handle<v8::Value>()); |
| 282 } | 285 } |
| 283 | 286 |
| 284 THREADED_TEST(EmptyResult) { | 287 THREADED_TEST(EmptyResult) { |
| 285 LocalContext context; | 288 LocalContext context; |
| 286 v8::HandleScope scope(context->GetIsolate()); | 289 v8::HandleScope scope(context->GetIsolate()); |
| 287 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 290 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 288 obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data")); | 291 obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data")); |
| 289 v8::Handle<v8::Object> inst = obj->NewInstance(); | 292 v8::Handle<v8::Object> inst = obj->NewInstance(); |
| 290 context->Global()->Set(v8::String::New("obj"), inst); | 293 context->Global()->Set(v8::String::New("obj"), inst); |
| 291 Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); | 294 Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 context->Global()->Set(v8::String::New("obj"), inst); | 326 context->Global()->Set(v8::String::New("obj"), inst); |
| 324 Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); | 327 Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx")); |
| 325 for (int i = 0; i < 10; i++) { | 328 for (int i = 0; i < 10; i++) { |
| 326 Local<Value> result = scr->Run(); | 329 Local<Value> result = scr->Run(); |
| 327 CHECK(!result.IsEmpty()); | 330 CHECK(!result.IsEmpty()); |
| 328 CHECK_EQ(17, result->Int32Value()); | 331 CHECK_EQ(17, result->Int32Value()); |
| 329 } | 332 } |
| 330 } | 333 } |
| 331 } | 334 } |
| 332 | 335 |
| 333 static v8::Handle<Value> ThrowingGetAccessor(Local<String> name, | 336 static void ThrowingGetAccessor( |
| 334 const AccessorInfo& info) { | 337 Local<String> name, |
| 338 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 335 ApiTestFuzzer::Fuzz(); | 339 ApiTestFuzzer::Fuzz(); |
| 336 return v8::ThrowException(v8_str("g")); | 340 v8::ThrowException(v8_str("g")); |
| 337 } | 341 } |
| 338 | 342 |
| 339 | 343 |
| 340 static void ThrowingSetAccessor(Local<String> name, | 344 static void ThrowingSetAccessor(Local<String> name, |
| 341 Local<Value> value, | 345 Local<Value> value, |
| 342 const AccessorInfo& info) { | 346 const v8::PropertyCallbackInfo<void>& info) { |
| 343 v8::ThrowException(value); | 347 v8::ThrowException(value); |
| 344 } | 348 } |
| 345 | 349 |
| 346 | 350 |
| 347 THREADED_TEST(Regress1054726) { | 351 THREADED_TEST(Regress1054726) { |
| 348 LocalContext env; | 352 LocalContext env; |
| 349 v8::HandleScope scope(env->GetIsolate()); | 353 v8::HandleScope scope(env->GetIsolate()); |
| 350 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 354 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 351 obj->SetAccessor(v8_str("x"), | 355 obj->SetAccessor(v8_str("x"), |
| 352 ThrowingGetAccessor, | 356 ThrowingGetAccessor, |
| (...skipping 14 matching lines...) Expand all Loading... |
| 367 | 371 |
| 368 result = Script::Compile(String::New( | 372 result = Script::Compile(String::New( |
| 369 "var result = '';" | 373 "var result = '';" |
| 370 "for (var i = 0; i < 5; i++) {" | 374 "for (var i = 0; i < 5; i++) {" |
| 371 " try { obj.x = i; } catch (e) { result += e; }" | 375 " try { obj.x = i; } catch (e) { result += e; }" |
| 372 "}; result"))->Run(); | 376 "}; result"))->Run(); |
| 373 CHECK_EQ(v8_str("01234"), result); | 377 CHECK_EQ(v8_str("01234"), result); |
| 374 } | 378 } |
| 375 | 379 |
| 376 | 380 |
| 377 static v8::Handle<Value> AllocGetter(Local<String> name, | 381 static void AllocGetter(Local<String> name, |
| 378 const AccessorInfo& info) { | 382 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 379 ApiTestFuzzer::Fuzz(); | 383 ApiTestFuzzer::Fuzz(); |
| 380 return v8::Array::New(1000); | 384 info.GetReturnValue().Set(v8::Array::New(1000)); |
| 381 } | 385 } |
| 382 | 386 |
| 383 | 387 |
| 384 THREADED_TEST(Gc) { | 388 THREADED_TEST(Gc) { |
| 385 LocalContext env; | 389 LocalContext env; |
| 386 v8::HandleScope scope(env->GetIsolate()); | 390 v8::HandleScope scope(env->GetIsolate()); |
| 387 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 391 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 388 obj->SetAccessor(v8_str("xxx"), AllocGetter); | 392 obj->SetAccessor(v8_str("xxx"), AllocGetter); |
| 389 env->Global()->Set(v8_str("obj"), obj->NewInstance()); | 393 env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
| 390 Script::Compile(String::New( | 394 Script::Compile(String::New( |
| 391 "var last = [];" | 395 "var last = [];" |
| 392 "for (var i = 0; i < 2048; i++) {" | 396 "for (var i = 0; i < 2048; i++) {" |
| 393 " var result = obj.xxx;" | 397 " var result = obj.xxx;" |
| 394 " result[0] = last;" | 398 " result[0] = last;" |
| 395 " last = result;" | 399 " last = result;" |
| 396 "}"))->Run(); | 400 "}"))->Run(); |
| 397 } | 401 } |
| 398 | 402 |
| 399 | 403 |
| 400 static v8::Handle<Value> StackCheck(Local<String> name, | 404 static void StackCheck(Local<String> name, |
| 401 const AccessorInfo& info) { | 405 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 402 i::StackFrameIterator iter(reinterpret_cast<i::Isolate*>(info.GetIsolate())); | 406 i::StackFrameIterator iter(reinterpret_cast<i::Isolate*>(info.GetIsolate())); |
| 403 for (int i = 0; !iter.done(); i++) { | 407 for (int i = 0; !iter.done(); i++) { |
| 404 i::StackFrame* frame = iter.frame(); | 408 i::StackFrame* frame = iter.frame(); |
| 405 CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT)); | 409 CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT)); |
| 406 i::Code* code = frame->LookupCode(); | 410 i::Code* code = frame->LookupCode(); |
| 407 CHECK(code->IsCode()); | 411 CHECK(code->IsCode()); |
| 408 i::Address pc = frame->pc(); | 412 i::Address pc = frame->pc(); |
| 409 CHECK(code->contains(pc)); | 413 CHECK(code->contains(pc)); |
| 410 iter.Advance(); | 414 iter.Advance(); |
| 411 } | 415 } |
| 412 return v8::Undefined(); | |
| 413 } | 416 } |
| 414 | 417 |
| 415 | 418 |
| 416 THREADED_TEST(StackIteration) { | 419 THREADED_TEST(StackIteration) { |
| 417 LocalContext env; | 420 LocalContext env; |
| 418 v8::HandleScope scope(env->GetIsolate()); | 421 v8::HandleScope scope(env->GetIsolate()); |
| 419 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 422 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 420 i::StringStream::ClearMentionedObjectCache(); | 423 i::StringStream::ClearMentionedObjectCache(); |
| 421 obj->SetAccessor(v8_str("xxx"), StackCheck); | 424 obj->SetAccessor(v8_str("xxx"), StackCheck); |
| 422 env->Global()->Set(v8_str("obj"), obj->NewInstance()); | 425 env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
| 423 Script::Compile(String::New( | 426 Script::Compile(String::New( |
| 424 "function foo() {" | 427 "function foo() {" |
| 425 " return obj.xxx;" | 428 " return obj.xxx;" |
| 426 "}" | 429 "}" |
| 427 "for (var i = 0; i < 100; i++) {" | 430 "for (var i = 0; i < 100; i++) {" |
| 428 " foo();" | 431 " foo();" |
| 429 "}"))->Run(); | 432 "}"))->Run(); |
| 430 } | 433 } |
| 431 | 434 |
| 432 | 435 |
| 433 static v8::Handle<Value> AllocateHandles(Local<String> name, | 436 static void AllocateHandles(Local<String> name, |
| 434 const AccessorInfo& info) { | 437 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 435 for (int i = 0; i < i::kHandleBlockSize + 1; i++) { | 438 for (int i = 0; i < i::kHandleBlockSize + 1; i++) { |
| 436 v8::Local<v8::Value>::New(name); | 439 v8::Local<v8::Value>::New(name); |
| 437 } | 440 } |
| 438 return v8::Integer::New(100); | 441 info.GetReturnValue().Set(v8::Integer::New(100)); |
| 439 } | 442 } |
| 440 | 443 |
| 441 | 444 |
| 442 THREADED_TEST(HandleScopeSegment) { | 445 THREADED_TEST(HandleScopeSegment) { |
| 443 // Check that we can return values past popping of handle scope | 446 // Check that we can return values past popping of handle scope |
| 444 // segments. | 447 // segments. |
| 445 LocalContext env; | 448 LocalContext env; |
| 446 v8::HandleScope scope(env->GetIsolate()); | 449 v8::HandleScope scope(env->GetIsolate()); |
| 447 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 450 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 448 obj->SetAccessor(v8_str("xxx"), AllocateHandles); | 451 obj->SetAccessor(v8_str("xxx"), AllocateHandles); |
| 449 env->Global()->Set(v8_str("obj"), obj->NewInstance()); | 452 env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
| 450 v8::Handle<v8::Value> result = Script::Compile(String::New( | 453 v8::Handle<v8::Value> result = Script::Compile(String::New( |
| 451 "var result;" | 454 "var result;" |
| 452 "for (var i = 0; i < 4; i++)" | 455 "for (var i = 0; i < 4; i++)" |
| 453 " result = obj.xxx;" | 456 " result = obj.xxx;" |
| 454 "result;"))->Run(); | 457 "result;"))->Run(); |
| 455 CHECK_EQ(100, result->Int32Value()); | 458 CHECK_EQ(100, result->Int32Value()); |
| 456 } | 459 } |
| 457 | 460 |
| 458 | 461 |
| 459 v8::Handle<v8::Array> JSONStringifyEnumerator(const AccessorInfo& info) { | 462 void JSONStringifyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) { |
| 460 v8::Handle<v8::Array> array = v8::Array::New(1); | 463 v8::Handle<v8::Array> array = v8::Array::New(1); |
| 461 array->Set(0, v8_str("regress")); | 464 array->Set(0, v8_str("regress")); |
| 462 return array; | 465 info.GetReturnValue().Set(array); |
| 463 } | 466 } |
| 464 | 467 |
| 465 | 468 |
| 466 v8::Handle<v8::Value> JSONStringifyGetter(Local<String> name, | 469 void JSONStringifyGetter(Local<String> name, |
| 467 const AccessorInfo& info) { | 470 const v8::PropertyCallbackInfo<v8::Value>& info) { |
| 468 return v8_str("crbug-161028"); | 471 info.GetReturnValue().Set(v8_str("crbug-161028")); |
| 469 } | 472 } |
| 470 | 473 |
| 471 | 474 |
| 472 THREADED_TEST(JSONStringifyNamedInterceptorObject) { | 475 THREADED_TEST(JSONStringifyNamedInterceptorObject) { |
| 473 LocalContext env; | 476 LocalContext env; |
| 474 v8::HandleScope scope(env->GetIsolate()); | 477 v8::HandleScope scope(env->GetIsolate()); |
| 475 | 478 |
| 476 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); | 479 v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(); |
| 477 obj->SetNamedPropertyHandler( | 480 obj->SetNamedPropertyHandler( |
| 478 JSONStringifyGetter, NULL, NULL, NULL, JSONStringifyEnumerator); | 481 JSONStringifyGetter, NULL, NULL, NULL, JSONStringifyEnumerator); |
| 479 env->Global()->Set(v8_str("obj"), obj->NewInstance()); | 482 env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
| 480 v8::Handle<v8::String> expected = v8_str("{\"regress\":\"crbug-161028\"}"); | 483 v8::Handle<v8::String> expected = v8_str("{\"regress\":\"crbug-161028\"}"); |
| 481 CHECK(CompileRun("JSON.stringify(obj)")->Equals(expected)); | 484 CHECK(CompileRun("JSON.stringify(obj)")->Equals(expected)); |
| 482 } | 485 } |
| OLD | NEW |