1d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Copyright 2009 the V8 project authors. All rights reserved.
2d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Redistribution and use in source and binary forms, with or without
3d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// modification, are permitted provided that the following conditions are
4d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// met:
5d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//
6d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//     * Redistributions of source code must retain the above copyright
7d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       notice, this list of conditions and the following disclaimer.
8d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//     * Redistributions in binary form must reproduce the above
9d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       copyright notice, this list of conditions and the following
10d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       disclaimer in the documentation and/or other materials provided
11d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       with the distribution.
12d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//     * Neither the name of Google Inc. nor the names of its
13d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       contributors may be used to endorse or promote products derived
14d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//       from this software without specific prior written permission.
15d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//
16d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
28d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include <stdlib.h>
29d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
30d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "v8.h"
31d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
32d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "api.h"
33d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "cctest.h"
34d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "frames-inl.h"
35d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "string-stream.h"
36d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
37d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::ObjectTemplate;
38d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::Value;
39d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::Context;
40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::Local;
41d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::String;
42d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::Script;
43d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::Function;
44d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::AccessorInfo;
45d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockusing ::v8::Extension;
46d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
47d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> handle_property(Local<String> name,
48d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         const AccessorInfo&) {
49d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
50d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8_num(900);
51d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
52d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
53d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
54d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(PropertyHandler) {
55d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
56d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
57d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property);
58d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
59d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Function> fun = fun_templ->GetFunction();
60d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("Fun"), fun);
61d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;");
62d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(900, getter->Run()->Int32Value());
63d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> setter = v8_compile("obj.foo = 901;");
64d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(901, setter->Run()->Int32Value());
65d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
66d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
67d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
68d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> GetIntValue(Local<String> property,
69d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                     const AccessorInfo& info) {
70d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
71d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int* value =
72d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
73d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8_num(*value);
74d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
75d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
76d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
77d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void SetIntValue(Local<String> property,
78d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                        Local<Value> value,
79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                        const AccessorInfo& info) {
80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int* field =
81d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
82d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  *field = value->Int32Value();
83d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
84d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
85d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockint foo, bar, baz;
86d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
87d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(GlobalVariableAccess) {
88d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  foo = 0;
89d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bar = -4;
90d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  baz = 10;
91d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
92d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
93d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->InstanceTemplate()->SetAccessor(v8_str("foo"),
94d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         GetIntValue,
95d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         SetIntValue,
96d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         v8::External::New(&foo));
97d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->InstanceTemplate()->SetAccessor(v8_str("bar"),
98d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         GetIntValue,
99d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         SetIntValue,
100d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         v8::External::New(&bar));
101d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->InstanceTemplate()->SetAccessor(v8_str("baz"),
102d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         GetIntValue,
103d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         SetIntValue,
104d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         v8::External::New(&baz));
105d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env(0, templ->InstanceTemplate());
106d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8_compile("foo = (++bar) + baz")->Run();
107d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(bar, -3);
108d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(foo, 7);
109d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic int x_register = 0;
113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<v8::Object> x_receiver;
114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<v8::Object> x_holder;
115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) {
118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
119d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_receiver, info.This());
120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_holder, info.Holder());
121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8_num(x_register);
122d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
123d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
124d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
125d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void XSetter(Local<String> name,
126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                    Local<Value> value,
127d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                    const AccessorInfo& info) {
128d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_holder, info.This());
129d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_holder, info.Holder());
130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  x_register = value->Int32Value();
131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
134d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(AccessorIC) {
135d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
136d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
137d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("x"), XGetter, XSetter);
138d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
139d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  x_holder = obj->NewInstance();
140d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8_str("holder"), x_holder);
141d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  x_receiver = v8::Object::New();
142d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8_str("obj"), x_receiver);
143d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun(
144d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "obj.__proto__ = holder;"
145d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "var result = [];"
146d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "for (var i = 0; i < 10; i++) {"
147d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "  holder.x = i;"
148d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "  result.push(obj.x);"
149d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "}"
150d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "result"));
151d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(10, array->Length());
152d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < 10; i++) {
153d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<Value> entry = array->Get(v8::Integer::New(i));
154d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK_EQ(v8::Integer::New(i), entry);
155d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
156d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
157d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
158d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
159d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> AccessorProhibitsOverwritingGetter(
160d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<String> name,
161d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    const AccessorInfo& info) {
162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
163d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::True();
164d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
167d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(AccessorProhibitsOverwriting) {
168d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
169d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
170d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<ObjectTemplate> templ = ObjectTemplate::New();
171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->SetAccessor(v8_str("x"),
172d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     AccessorProhibitsOverwritingGetter,
173d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     0,
174d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::Handle<Value>(),
175d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::PROHIBITS_OVERWRITING,
176d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::ReadOnly);
177d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<v8::Object> instance = templ->NewInstance();
178d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8_str("obj"), instance);
179d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Value> value = CompileRun(
180d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.__defineGetter__('x', function() { return false; });"
181d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.x");
182d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(value->BooleanValue());
183d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  value = CompileRun(
184d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var setter_called = false;"
185d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.__defineSetter__('x', function() { setter_called = true; });"
186d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.x = 42;"
187d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "setter_called");
188d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(!value->BooleanValue());
189d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  value = CompileRun(
190d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2 = {};"
191d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__proto__ = obj;"
192d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__defineGetter__('x', function() { return false; });"
193d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.x");
194d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(value->BooleanValue());
195d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  value = CompileRun(
196d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var setter_called = false;"
197d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2 = {};"
198d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__proto__ = obj;"
199d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__defineSetter__('x', function() { setter_called = true; });"
200d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.x = 42;"
201d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "setter_called");
202d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(!value->BooleanValue());
203d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
204d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
205d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
206d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blocktemplate <int C>
207d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> HandleAllocatingGetter(Local<String> name,
208d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                const AccessorInfo& info) {
209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
210d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < C; i++)
211d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::String::New("foo");
212d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::String::New("foo");
213d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
214d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
215d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
216d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(HandleScopePop) {
217d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
218d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
219d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>);
220d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>);
221d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
222d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Object> inst = obj->NewInstance();
223d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8::String::New("obj"), inst);
224d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int count_before = i::HandleScope::NumberOfHandles();
225d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  {
226d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::HandleScope scope;
227d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CompileRun(
228d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "for (var i = 0; i < 1000; i++) {"
229d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "  obj.one;"
230d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "  obj.many;"
231d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "}");
232d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
233d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int count_after = i::HandleScope::NumberOfHandles();
234d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(count_before, count_after);
235d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
236d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
237d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name,
238d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                  const AccessorInfo& info) {
239d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.This() == info.Holder());
240d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.Data()->Equals(v8::String::New("data")));
241d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
242d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.This() == info.Holder());
243d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.Data()->Equals(v8::String::New("data")));
2443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
245d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.This() == info.Holder());
246d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.Data()->Equals(v8::String::New("data")));
247d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Integer::New(17);
248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
249d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
250d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(DirectCall) {
251d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
252d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"),
254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   CheckAccessorArgsCorrect,
255d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   NULL,
256d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   v8::String::New("data"));
257d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Object> inst = obj->NewInstance();
259d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8::String::New("obj"), inst);
260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
261d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < 10; i++) {
262d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Value> result = scr->Run();
263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(!result.IsEmpty());
264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK_EQ(17, result->Int32Value());
265d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
266d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
267d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
268d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> EmptyGetter(Local<String> name,
269d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                     const AccessorInfo& info) {
270d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CheckAccessorArgsCorrect(name, info);
271d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CheckAccessorArgsCorrect(name, info);
273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Handle<v8::Value>();
274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
275d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
276d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(EmptyResult) {
277d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
278d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
279d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data"));
280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
281d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Object> inst = obj->NewInstance();
282d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8::String::New("obj"), inst);
283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < 10; i++) {
285d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Value> result = scr->Run();
286d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(result == v8::Undefined());
287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
288d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
291d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(NoReuseRegress) {
292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Check that the IC generated for the one test doesn't get reused
293d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // for the other.
294d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
295d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  {
296d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
297d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data"));
298d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    LocalContext context;
299d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::Object> inst = obj->NewInstance();
300d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    context->Global()->Set(v8::String::New("obj"), inst);
301d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
302d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    for (int i = 0; i < 2; i++) {
303d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Local<Value> result = scr->Run();
304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CHECK(result == v8::Undefined());
305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
306d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
307d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  {
308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
309d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    obj->SetAccessor(v8_str("xxx"),
310d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     CheckAccessorArgsCorrect,
311d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     NULL,
312d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::String::New("data"));
313d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    LocalContext context;
314d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::Object> inst = obj->NewInstance();
315d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    context->Global()->Set(v8::String::New("obj"), inst);
316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
317d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    for (int i = 0; i < 10; i++) {
318d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Local<Value> result = scr->Run();
319d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CHECK(!result.IsEmpty());
320d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CHECK_EQ(17, result->Int32Value());
321d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
322d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
323d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
324d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
325d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> ThrowingGetAccessor(Local<String> name,
326d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                             const AccessorInfo& info) {
327d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
328d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::ThrowException(v8_str("g"));
329d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
330d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
331d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
332d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void ThrowingSetAccessor(Local<String> name,
333d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                Local<Value> value,
334d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                const AccessorInfo& info) {
335d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::ThrowException(value);
336d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
337d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
339d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(Regress1054726) {
340d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
341d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
342d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("x"),
343d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   ThrowingGetAccessor,
344d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   ThrowingSetAccessor,
345d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   Local<Value>());
346d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
347d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
348d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
349d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
350d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Use the throwing property setter/getter in a loop to force
351d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // the accessor ICs to be initialized.
352d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<Value> result;
353d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  result = Script::Compile(v8_str(
354d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var result = '';"
355d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 5; i++) {"
356d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  try { obj.x; } catch (e) { result += e; }"
357d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}; result"))->Run();
358d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(v8_str("ggggg"), result);
359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  result = Script::Compile(String::New(
361d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var result = '';"
362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 5; i++) {"
363d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  try { obj.x = i; } catch (e) { result += e; }"
364d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}; result"))->Run();
365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(v8_str("01234"), result);
366d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
367d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
368d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
369d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> AllocGetter(Local<String> name,
370d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                     const AccessorInfo& info) {
371d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
372d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Array::New(1000);
373d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
374d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
375d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
376d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(Gc) {
377d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
378d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), AllocGetter);
380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Script::Compile(String::New(
383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var last = [];"
384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 2048; i++) {"
385d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  var result = obj.xxx;"
386d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  result[0] = last;"
387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  last = result;"
388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}"))->Run();
389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
390d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
392d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> StackCheck(Local<String> name,
393d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                    const AccessorInfo& info) {
394d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  i::StackFrameIterator iter;
395d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; !iter.done(); i++) {
396d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    i::StackFrame* frame = iter.frame();
397d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT));
3988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch    i::Code* code = frame->LookupCode();
39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    CHECK(code->IsCode());
400d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    i::Address pc = frame->pc();
401d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(code->contains(pc));
402d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    iter.Advance();
403d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
404d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Undefined();
405d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
406d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
407d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
408d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(StackIteration) {
409d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
410d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
411d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  i::StringStream::ClearMentionedObjectCache();
412d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), StackCheck);
413d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
414d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
415d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Script::Compile(String::New(
416d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "function foo() {"
417d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  return obj.xxx;"
418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}"
419d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 100; i++) {"
420d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  foo();"
421d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}"))->Run();
422d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
423d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
425d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> AllocateHandles(Local<String> name,
426d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         const AccessorInfo& info) {
427d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < i::kHandleBlockSize + 1; i++) {
428d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Local<v8::Value>::New(name);
429d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
430d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Integer::New(100);
431d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
432d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
433d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
434d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(HandleScopeSegment) {
435d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Check that we can return values past popping of handle scope
436d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // segments.
437d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
438d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
439d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), AllocateHandles);
440d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
441d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
442d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Value> result = Script::Compile(String::New(
443d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var result;"
444d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 4; i++)"
445d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  result = obj.xxx;"
446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "result;"))->Run();
447d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(100, result->Int32Value());
448d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
449