bbb74c0a71ada861c959c3fdd9049d3cdb9995a9
[platform/upstream/nodejs.git] / deps / v8 / test / cctest / test-accessors.cc
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #include <stdlib.h>
29
30 #include "src/v8.h"
31
32 #include "src/api.h"
33 #include "src/frames-inl.h"
34 #include "src/string-stream.h"
35 #include "test/cctest/cctest.h"
36
37 using ::v8::ObjectTemplate;
38 using ::v8::Value;
39 using ::v8::Context;
40 using ::v8::Local;
41 using ::v8::Name;
42 using ::v8::String;
43 using ::v8::Script;
44 using ::v8::Function;
45 using ::v8::Extension;
46
47 static void handle_property(Local<String> name,
48                             const v8::PropertyCallbackInfo<v8::Value>& info) {
49   ApiTestFuzzer::Fuzz();
50   info.GetReturnValue().Set(v8_num(900));
51 }
52
53 static void handle_property_2(Local<String> name,
54                               const v8::PropertyCallbackInfo<v8::Value>& info) {
55   ApiTestFuzzer::Fuzz();
56   info.GetReturnValue().Set(v8_num(902));
57 }
58
59
60 static void handle_property(const v8::FunctionCallbackInfo<v8::Value>& info) {
61   ApiTestFuzzer::Fuzz();
62   CHECK_EQ(0, info.Length());
63   info.GetReturnValue().Set(v8_num(907));
64 }
65
66
67 THREADED_TEST(PropertyHandler) {
68   LocalContext env;
69   v8::Isolate* isolate = env->GetIsolate();
70   v8::HandleScope scope(isolate);
71   Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
72   fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property);
73   Local<v8::FunctionTemplate> getter_templ =
74       v8::FunctionTemplate::New(isolate, handle_property);
75   getter_templ->SetLength(0);
76   fun_templ->
77       InstanceTemplate()->SetAccessorProperty(v8_str("bar"), getter_templ);
78   fun_templ->InstanceTemplate()->
79       SetNativeDataProperty(v8_str("instance_foo"), handle_property);
80   fun_templ->SetNativeDataProperty(v8_str("object_foo"), handle_property_2);
81   Local<Function> fun = fun_templ->GetFunction();
82   env->Global()->Set(v8_str("Fun"), fun);
83   Local<Script> getter;
84   Local<Script> setter;
85   // check function instance accessors
86   getter = v8_compile("var obj = new Fun(); obj.instance_foo;");
87   CHECK_EQ(900, getter->Run()->Int32Value());
88   setter = v8_compile("obj.instance_foo = 901;");
89   CHECK_EQ(901, setter->Run()->Int32Value());
90   getter = v8_compile("obj.bar;");
91   CHECK_EQ(907, getter->Run()->Int32Value());
92   setter = v8_compile("obj.bar = 908;");
93   CHECK_EQ(908, setter->Run()->Int32Value());
94   // check function static accessors
95   getter = v8_compile("Fun.object_foo;");
96   CHECK_EQ(902, getter->Run()->Int32Value());
97   setter = v8_compile("Fun.object_foo = 903;");
98   CHECK_EQ(903, setter->Run()->Int32Value());
99 }
100
101
102 static void GetIntValue(Local<String> property,
103                         const v8::PropertyCallbackInfo<v8::Value>& info) {
104   ApiTestFuzzer::Fuzz();
105   int* value =
106       static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
107   info.GetReturnValue().Set(v8_num(*value));
108 }
109
110
111 static void SetIntValue(Local<String> property,
112                         Local<Value> value,
113                         const v8::PropertyCallbackInfo<void>& info) {
114   int* field =
115       static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
116   *field = value->Int32Value();
117 }
118
119 int foo, bar, baz;
120
121 THREADED_TEST(GlobalVariableAccess) {
122   foo = 0;
123   bar = -4;
124   baz = 10;
125   v8::Isolate* isolate = CcTest::isolate();
126   v8::HandleScope scope(isolate);
127   v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
128   templ->InstanceTemplate()->SetAccessor(
129       v8_str("foo"), GetIntValue, SetIntValue,
130       v8::External::New(isolate, &foo));
131   templ->InstanceTemplate()->SetAccessor(
132       v8_str("bar"), GetIntValue, SetIntValue,
133       v8::External::New(isolate, &bar));
134   templ->InstanceTemplate()->SetAccessor(
135       v8_str("baz"), GetIntValue, SetIntValue,
136       v8::External::New(isolate, &baz));
137   LocalContext env(0, templ->InstanceTemplate());
138   v8_compile("foo = (++bar) + baz")->Run();
139   CHECK_EQ(bar, -3);
140   CHECK_EQ(foo, 7);
141 }
142
143
144 static int x_register[2] = {0, 0};
145 static v8::Handle<v8::Object> x_receiver;
146 static v8::Handle<v8::Object> x_holder;
147
148 template<class Info>
149 static void XGetter(const Info& info, int offset) {
150   ApiTestFuzzer::Fuzz();
151   v8::Isolate* isolate = CcTest::isolate();
152   CHECK_EQ(isolate, info.GetIsolate());
153   CHECK(x_receiver->Equals(info.This()));
154   info.GetReturnValue().Set(v8_num(x_register[offset]));
155 }
156
157
158 static void XGetter(Local<String> name,
159                     const v8::PropertyCallbackInfo<v8::Value>& info) {
160   CHECK(x_holder->Equals(info.Holder()));
161   XGetter(info, 0);
162 }
163
164
165 static void XGetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
166   CHECK(x_receiver->Equals(info.Holder()));
167   XGetter(info, 1);
168 }
169
170
171 template<class Info>
172 static void XSetter(Local<Value> value, const Info& info, int offset) {
173   v8::Isolate* isolate = CcTest::isolate();
174   CHECK_EQ(isolate, info.GetIsolate());
175   CHECK(x_holder->Equals(info.This()));
176   CHECK(x_holder->Equals(info.Holder()));
177   x_register[offset] = value->Int32Value();
178   info.GetReturnValue().Set(v8_num(-1));
179 }
180
181
182 static void XSetter(Local<String> name,
183                     Local<Value> value,
184                     const v8::PropertyCallbackInfo<void>& info) {
185   XSetter(value, info, 0);
186 }
187
188
189 static void XSetter(const v8::FunctionCallbackInfo<v8::Value>& info) {
190   CHECK_EQ(1, info.Length());
191   XSetter(info[0], info, 1);
192 }
193
194
195 THREADED_TEST(AccessorIC) {
196   LocalContext context;
197   v8::Isolate* isolate = context->GetIsolate();
198   v8::HandleScope scope(isolate);
199   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
200   obj->SetAccessor(v8_str("x0"), XGetter, XSetter);
201   obj->SetAccessorProperty(v8_str("x1"),
202                            v8::FunctionTemplate::New(isolate, XGetter),
203                            v8::FunctionTemplate::New(isolate, XSetter));
204   x_holder = obj->NewInstance();
205   context->Global()->Set(v8_str("holder"), x_holder);
206   x_receiver = v8::Object::New(isolate);
207   context->Global()->Set(v8_str("obj"), x_receiver);
208   v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun(
209     "obj.__proto__ = holder;"
210     "var result = [];"
211     "var key_0 = 'x0';"
212     "var key_1 = 'x1';"
213     "for (var j = 0; j < 10; j++) {"
214     "  var i = 4*j;"
215     "  result.push(holder.x0 = i);"
216     "  result.push(obj.x0);"
217     "  result.push(holder.x1 = i + 1);"
218     "  result.push(obj.x1);"
219     "  result.push(holder[key_0] = i + 2);"
220     "  result.push(obj[key_0]);"
221     "  result.push(holder[key_1] = i + 3);"
222     "  result.push(obj[key_1]);"
223     "}"
224     "result"));
225   CHECK_EQ(80u, array->Length());
226   for (int i = 0; i < 80; i++) {
227     v8::Handle<Value> entry = array->Get(v8::Integer::New(isolate, i));
228     CHECK(v8::Integer::New(isolate, i / 2)->Equals(entry));
229   }
230 }
231
232
233 template <int C>
234 static void HandleAllocatingGetter(
235     Local<String> name,
236     const v8::PropertyCallbackInfo<v8::Value>& info) {
237   ApiTestFuzzer::Fuzz();
238   for (int i = 0; i < C; i++)
239     v8::String::NewFromUtf8(info.GetIsolate(), "foo");
240   info.GetReturnValue().Set(v8::String::NewFromUtf8(info.GetIsolate(), "foo"));
241 }
242
243
244 THREADED_TEST(HandleScopePop) {
245   LocalContext context;
246   v8::Isolate* isolate = context->GetIsolate();
247   v8::HandleScope scope(isolate);
248   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
249   obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>);
250   obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>);
251   v8::Handle<v8::Object> inst = obj->NewInstance();
252   context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst);
253   int count_before =
254       i::HandleScope::NumberOfHandles(reinterpret_cast<i::Isolate*>(isolate));
255   {
256     v8::HandleScope scope(isolate);
257     CompileRun(
258         "for (var i = 0; i < 1000; i++) {"
259         "  obj.one;"
260         "  obj.many;"
261         "}");
262   }
263   int count_after =
264       i::HandleScope::NumberOfHandles(reinterpret_cast<i::Isolate*>(isolate));
265   CHECK_EQ(count_before, count_after);
266 }
267
268 static void CheckAccessorArgsCorrect(
269     Local<String> name,
270     const v8::PropertyCallbackInfo<v8::Value>& info) {
271   CHECK(info.GetIsolate() == CcTest::isolate());
272   CHECK(info.This() == info.Holder());
273   CHECK(
274       info.Data()->Equals(v8::String::NewFromUtf8(CcTest::isolate(), "data")));
275   ApiTestFuzzer::Fuzz();
276   CHECK(info.GetIsolate() == CcTest::isolate());
277   CHECK(info.This() == info.Holder());
278   CHECK(
279       info.Data()->Equals(v8::String::NewFromUtf8(CcTest::isolate(), "data")));
280   CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
281   CHECK(info.GetIsolate() == CcTest::isolate());
282   CHECK(info.This() == info.Holder());
283   CHECK(
284       info.Data()->Equals(v8::String::NewFromUtf8(CcTest::isolate(), "data")));
285   info.GetReturnValue().Set(17);
286 }
287
288
289 THREADED_TEST(DirectCall) {
290   LocalContext context;
291   v8::Isolate* isolate = context->GetIsolate();
292   v8::HandleScope scope(isolate);
293   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
294   obj->SetAccessor(v8_str("xxx"),
295                    CheckAccessorArgsCorrect,
296                    NULL,
297                    v8::String::NewFromUtf8(isolate, "data"));
298   v8::Handle<v8::Object> inst = obj->NewInstance();
299   context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"),
300                          inst);
301   Local<Script> scr = v8::Script::Compile(
302       v8::String::NewFromUtf8(isolate, "obj.xxx"));
303   for (int i = 0; i < 10; i++) {
304     Local<Value> result = scr->Run();
305     CHECK(!result.IsEmpty());
306     CHECK_EQ(17, result->Int32Value());
307   }
308 }
309
310 static void EmptyGetter(Local<String> name,
311                         const v8::PropertyCallbackInfo<v8::Value>& info) {
312   CheckAccessorArgsCorrect(name, info);
313   ApiTestFuzzer::Fuzz();
314   CheckAccessorArgsCorrect(name, info);
315   info.GetReturnValue().Set(v8::Handle<v8::Value>());
316 }
317
318
319 THREADED_TEST(EmptyResult) {
320   LocalContext context;
321   v8::Isolate* isolate = context->GetIsolate();
322   v8::HandleScope scope(isolate);
323   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
324   obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL,
325                    v8::String::NewFromUtf8(isolate, "data"));
326   v8::Handle<v8::Object> inst = obj->NewInstance();
327   context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst);
328   Local<Script> scr =
329       v8::Script::Compile(v8::String::NewFromUtf8(isolate, "obj.xxx"));
330   for (int i = 0; i < 10; i++) {
331     Local<Value> result = scr->Run();
332     CHECK(result == v8::Undefined(isolate));
333   }
334 }
335
336
337 THREADED_TEST(NoReuseRegress) {
338   // Check that the IC generated for the one test doesn't get reused
339   // for the other.
340   v8::Isolate* isolate = CcTest::isolate();
341   v8::HandleScope scope(isolate);
342   {
343     v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
344     obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL,
345                      v8::String::NewFromUtf8(isolate, "data"));
346     LocalContext context;
347     v8::Handle<v8::Object> inst = obj->NewInstance();
348     context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst);
349     Local<Script> scr =
350         v8::Script::Compile(v8::String::NewFromUtf8(isolate, "obj.xxx"));
351     for (int i = 0; i < 2; i++) {
352       Local<Value> result = scr->Run();
353       CHECK(result == v8::Undefined(isolate));
354     }
355   }
356   {
357     v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
358     obj->SetAccessor(v8_str("xxx"),
359                      CheckAccessorArgsCorrect,
360                      NULL,
361                      v8::String::NewFromUtf8(isolate, "data"));
362     LocalContext context;
363     v8::Handle<v8::Object> inst = obj->NewInstance();
364     context->Global()->Set(v8::String::NewFromUtf8(isolate, "obj"), inst);
365     Local<Script> scr =
366         v8::Script::Compile(v8::String::NewFromUtf8(isolate, "obj.xxx"));
367     for (int i = 0; i < 10; i++) {
368       Local<Value> result = scr->Run();
369       CHECK(!result.IsEmpty());
370       CHECK_EQ(17, result->Int32Value());
371     }
372   }
373 }
374
375 static void ThrowingGetAccessor(
376     Local<String> name,
377     const v8::PropertyCallbackInfo<v8::Value>& info) {
378   ApiTestFuzzer::Fuzz();
379   info.GetIsolate()->ThrowException(v8_str("g"));
380 }
381
382
383 static void ThrowingSetAccessor(Local<String> name,
384                                 Local<Value> value,
385                                 const v8::PropertyCallbackInfo<void>& info) {
386   info.GetIsolate()->ThrowException(value);
387 }
388
389
390 THREADED_TEST(Regress1054726) {
391   LocalContext env;
392   v8::Isolate* isolate = env->GetIsolate();
393   v8::HandleScope scope(isolate);
394   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
395   obj->SetAccessor(v8_str("x"),
396                    ThrowingGetAccessor,
397                    ThrowingSetAccessor,
398                    Local<Value>());
399
400   env->Global()->Set(v8_str("obj"), obj->NewInstance());
401
402   // Use the throwing property setter/getter in a loop to force
403   // the accessor ICs to be initialized.
404   v8::Handle<Value> result;
405   result = Script::Compile(v8_str(
406       "var result = '';"
407       "for (var i = 0; i < 5; i++) {"
408       "  try { obj.x; } catch (e) { result += e; }"
409       "}; result"))->Run();
410   CHECK(v8_str("ggggg")->Equals(result));
411
412   result = Script::Compile(String::NewFromUtf8(
413       isolate,
414       "var result = '';"
415       "for (var i = 0; i < 5; i++) {"
416       "  try { obj.x = i; } catch (e) { result += e; }"
417       "}; result"))->Run();
418   CHECK(v8_str("01234")->Equals(result));
419 }
420
421
422 static void AllocGetter(Local<String> name,
423                         const v8::PropertyCallbackInfo<v8::Value>& info) {
424   ApiTestFuzzer::Fuzz();
425   info.GetReturnValue().Set(v8::Array::New(info.GetIsolate(), 1000));
426 }
427
428
429 THREADED_TEST(Gc) {
430   LocalContext env;
431   v8::Isolate* isolate = env->GetIsolate();
432   v8::HandleScope scope(isolate);
433   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
434   obj->SetAccessor(v8_str("xxx"), AllocGetter);
435   env->Global()->Set(v8_str("obj"), obj->NewInstance());
436   Script::Compile(String::NewFromUtf8(
437       isolate,
438       "var last = [];"
439       "for (var i = 0; i < 2048; i++) {"
440       "  var result = obj.xxx;"
441       "  result[0] = last;"
442       "  last = result;"
443       "}"))->Run();
444 }
445
446
447 static void StackCheck(Local<String> name,
448                        const v8::PropertyCallbackInfo<v8::Value>& info) {
449   i::StackFrameIterator iter(reinterpret_cast<i::Isolate*>(info.GetIsolate()));
450   for (int i = 0; !iter.done(); i++) {
451     i::StackFrame* frame = iter.frame();
452     CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT));
453     i::Code* code = frame->LookupCode();
454     CHECK(code->IsCode());
455     i::Address pc = frame->pc();
456     CHECK(code->contains(pc));
457     iter.Advance();
458   }
459 }
460
461
462 THREADED_TEST(StackIteration) {
463   LocalContext env;
464   v8::Isolate* isolate = env->GetIsolate();
465   v8::HandleScope scope(isolate);
466   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
467   i::StringStream::ClearMentionedObjectCache(
468       reinterpret_cast<i::Isolate*>(isolate));
469   obj->SetAccessor(v8_str("xxx"), StackCheck);
470   env->Global()->Set(v8_str("obj"), obj->NewInstance());
471   Script::Compile(String::NewFromUtf8(
472       isolate,
473       "function foo() {"
474       "  return obj.xxx;"
475       "}"
476       "for (var i = 0; i < 100; i++) {"
477       "  foo();"
478       "}"))->Run();
479 }
480
481
482 static void AllocateHandles(Local<String> name,
483                             const v8::PropertyCallbackInfo<v8::Value>& info) {
484   for (int i = 0; i < i::kHandleBlockSize + 1; i++) {
485     v8::Local<v8::Value>::New(info.GetIsolate(), name);
486   }
487   info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 100));
488 }
489
490
491 THREADED_TEST(HandleScopeSegment) {
492   // Check that we can return values past popping of handle scope
493   // segments.
494   LocalContext env;
495   v8::Isolate* isolate = env->GetIsolate();
496   v8::HandleScope scope(isolate);
497   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
498   obj->SetAccessor(v8_str("xxx"), AllocateHandles);
499   env->Global()->Set(v8_str("obj"), obj->NewInstance());
500   v8::Handle<v8::Value> result = Script::Compile(String::NewFromUtf8(
501       isolate,
502       "var result;"
503       "for (var i = 0; i < 4; i++)"
504       "  result = obj.xxx;"
505       "result;"))->Run();
506   CHECK_EQ(100, result->Int32Value());
507 }
508
509
510 void JSONStringifyEnumerator(const v8::PropertyCallbackInfo<v8::Array>& info) {
511   v8::Handle<v8::Array> array = v8::Array::New(info.GetIsolate(), 1);
512   array->Set(0, v8_str("regress"));
513   info.GetReturnValue().Set(array);
514 }
515
516
517 void JSONStringifyGetter(Local<Name> name,
518                          const v8::PropertyCallbackInfo<v8::Value>& info) {
519   info.GetReturnValue().Set(v8_str("crbug-161028"));
520 }
521
522
523 THREADED_TEST(JSONStringifyNamedInterceptorObject) {
524   LocalContext env;
525   v8::Isolate* isolate = env->GetIsolate();
526   v8::HandleScope scope(isolate);
527
528   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
529   obj->SetHandler(v8::NamedPropertyHandlerConfiguration(
530       JSONStringifyGetter, NULL, NULL, NULL, JSONStringifyEnumerator));
531   env->Global()->Set(v8_str("obj"), obj->NewInstance());
532   v8::Handle<v8::String> expected = v8_str("{\"regress\":\"crbug-161028\"}");
533   CHECK(CompileRun("JSON.stringify(obj)")->Equals(expected));
534 }
535
536
537 static v8::Local<v8::Context> expected_current_context;
538 static v8::Local<v8::Context> expected_calling_context;
539
540
541 static void check_contexts(const v8::FunctionCallbackInfo<v8::Value>& info) {
542   ApiTestFuzzer::Fuzz();
543   CHECK(expected_current_context == info.GetIsolate()->GetCurrentContext());
544   CHECK(expected_calling_context == info.GetIsolate()->GetCallingContext());
545 }
546
547
548 THREADED_TEST(AccessorPropertyCrossContext) {
549   LocalContext env;
550   v8::Isolate* isolate = env->GetIsolate();
551   v8::HandleScope scope(isolate);
552   v8::Handle<v8::Function> fun = v8::Function::New(isolate, check_contexts);
553   LocalContext switch_context;
554   switch_context->Global()->Set(v8_str("fun"), fun);
555   v8::TryCatch try_catch;
556   expected_current_context = env.local();
557   expected_calling_context = switch_context.local();
558   CompileRun(
559       "var o = Object.create(null, { n: { get:fun } });"
560       "for (var i = 0; i < 10; i++) o.n;");
561   CHECK(!try_catch.HasCaught());
562 }
563
564
565 THREADED_TEST(GlobalObjectAccessor) {
566   LocalContext env;
567   v8::Isolate* isolate = env->GetIsolate();
568   v8::HandleScope scope(isolate);
569   CompileRun(
570       "var set_value = 1;"
571       "Object.defineProperty(this.__proto__, 'x', {"
572       "    get : function() { return this; },"
573       "    set : function() { set_value = this; }"
574       "});"
575       "function getter() { return x; }"
576       "function setter() { x = 1; }"
577       "for (var i = 0; i < 4; i++) { getter(); setter(); }");
578   CHECK(v8::Utils::OpenHandle(*CompileRun("getter()"))->IsJSGlobalProxy());
579   CHECK(v8::Utils::OpenHandle(*CompileRun("set_value"))->IsJSGlobalProxy());
580 }
581
582
583 static void EmptyGetter(Local<Name> name,
584                         const v8::PropertyCallbackInfo<v8::Value>& info) {
585   ApiTestFuzzer::Fuzz();
586 }
587
588
589 static void OneProperty(Local<String> name,
590                         const v8::PropertyCallbackInfo<v8::Value>& info) {
591   ApiTestFuzzer::Fuzz();
592   info.GetReturnValue().Set(v8_num(1));
593 }
594
595
596 THREADED_TEST(Regress433458) {
597   LocalContext env;
598   v8::Isolate* isolate = env->GetIsolate();
599   v8::HandleScope scope(isolate);
600   v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
601   obj->SetHandler(v8::NamedPropertyHandlerConfiguration(EmptyGetter));
602   obj->SetNativeDataProperty(v8_str("prop"), OneProperty);
603   env->Global()->Set(v8_str("obj"), obj->NewInstance());
604   CompileRun(
605       "Object.defineProperty(obj, 'prop', { writable: false });"
606       "Object.defineProperty(obj, 'prop', { writable: true });");
607 }