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 Blocknamespace i = ::v8::internal;
48d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
49d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> handle_property(Local<String> name,
50d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         const AccessorInfo&) {
51d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
52d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8_num(900);
53d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
54d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
55d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
56d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(PropertyHandler) {
57d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
58d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
59d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  fun_templ->InstanceTemplate()->SetAccessor(v8_str("foo"), handle_property);
60d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
61d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Function> fun = fun_templ->GetFunction();
62d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("Fun"), fun);
63d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> getter = v8_compile("var obj = new Fun(); obj.foo;");
64d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(900, getter->Run()->Int32Value());
65d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> setter = v8_compile("obj.foo = 901;");
66d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(901, setter->Run()->Int32Value());
67d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
68d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
69d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
70d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> GetIntValue(Local<String> property,
71d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                     const AccessorInfo& info) {
72d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
73d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int* value =
74d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
75d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8_num(*value);
76d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
77d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
78d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
79d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void SetIntValue(Local<String> property,
80d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                        Local<Value> value,
81d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                        const AccessorInfo& info) {
82d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int* field =
83d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      static_cast<int*>(v8::Handle<v8::External>::Cast(info.Data())->Value());
84d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  *field = value->Int32Value();
85d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
86d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
87d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockint foo, bar, baz;
88d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
89d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(GlobalVariableAccess) {
90d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  foo = 0;
91d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  bar = -4;
92d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  baz = 10;
93d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
94d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
95d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->InstanceTemplate()->SetAccessor(v8_str("foo"),
96d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         GetIntValue,
97d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         SetIntValue,
98d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         v8::External::New(&foo));
99d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->InstanceTemplate()->SetAccessor(v8_str("bar"),
100d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         GetIntValue,
101d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         SetIntValue,
102d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         v8::External::New(&bar));
103d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->InstanceTemplate()->SetAccessor(v8_str("baz"),
104d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         GetIntValue,
105d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         SetIntValue,
106d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         v8::External::New(&baz));
107d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env(0, templ->InstanceTemplate());
108d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8_compile("foo = (++bar) + baz")->Run();
109d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(bar, -3);
110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(foo, 7);
111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic int x_register = 0;
115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<v8::Object> x_receiver;
116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<v8::Object> x_holder;
117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
119d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> XGetter(Local<String> name, const AccessorInfo& info) {
120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_receiver, info.This());
122d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_holder, info.Holder());
123d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8_num(x_register);
124d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
125d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
127d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void XSetter(Local<String> name,
128d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                    Local<Value> value,
129d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                    const AccessorInfo& info) {
130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_holder, info.This());
131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(x_holder, info.Holder());
132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  x_register = value->Int32Value();
133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
135d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
136d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(AccessorIC) {
137d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
138d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
139d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("x"), XGetter, XSetter);
140d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
141d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  x_holder = obj->NewInstance();
142d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8_str("holder"), x_holder);
143d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  x_receiver = v8::Object::New();
144d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8_str("obj"), x_receiver);
145d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(CompileRun(
146d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "obj.__proto__ = holder;"
147d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "var result = [];"
148d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "for (var i = 0; i < 10; i++) {"
149d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "  holder.x = i;"
150d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "  result.push(obj.x);"
151d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "}"
152d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    "result"));
153d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(10, array->Length());
154d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < 10; i++) {
155d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<Value> entry = array->Get(v8::Integer::New(i));
156d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK_EQ(v8::Integer::New(i), entry);
157d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
158d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
159d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
160d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
161d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> AccessorProhibitsOverwritingGetter(
162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<String> name,
163d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    const AccessorInfo& info) {
164d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
165d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::True();
166d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
167d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
168d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
169d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(AccessorProhibitsOverwriting) {
170d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
171d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
172d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<ObjectTemplate> templ = ObjectTemplate::New();
173d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  templ->SetAccessor(v8_str("x"),
174d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     AccessorProhibitsOverwritingGetter,
175d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     0,
176d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::Handle<Value>(),
177d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::PROHIBITS_OVERWRITING,
178d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::ReadOnly);
179d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<v8::Object> instance = templ->NewInstance();
180d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8_str("obj"), instance);
181d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Value> value = CompileRun(
182d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.__defineGetter__('x', function() { return false; });"
183d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.x");
184d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(value->BooleanValue());
185d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  value = CompileRun(
186d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var setter_called = false;"
187d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.__defineSetter__('x', function() { setter_called = true; });"
188d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj.x = 42;"
189d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "setter_called");
190d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(!value->BooleanValue());
191d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  value = CompileRun(
192d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2 = {};"
193d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__proto__ = obj;"
194d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__defineGetter__('x', function() { return false; });"
195d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.x");
196d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(value->BooleanValue());
197d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  value = CompileRun(
198d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var setter_called = false;"
199d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2 = {};"
200d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__proto__ = obj;"
201d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.__defineSetter__('x', function() { setter_called = true; });"
202d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "obj2.x = 42;"
203d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "setter_called");
204d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(!value->BooleanValue());
205d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
206d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
207d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
208d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blocktemplate <int C>
209d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> HandleAllocatingGetter(Local<String> name,
210d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                const AccessorInfo& info) {
211d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
212d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < C; i++)
213d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::String::New("foo");
214d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::String::New("foo");
215d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
216d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
217d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
218d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(HandleScopePop) {
219d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
220d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
221d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("one"), HandleAllocatingGetter<1>);
222d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("many"), HandleAllocatingGetter<1024>);
223d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
224d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Object> inst = obj->NewInstance();
225d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8::String::New("obj"), inst);
226d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int count_before = i::HandleScope::NumberOfHandles();
227d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  {
228d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::HandleScope scope;
229d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CompileRun(
230d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "for (var i = 0; i < 1000; i++) {"
231d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "  obj.one;"
232d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "  obj.many;"
233d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        "}");
234d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
235d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int count_after = i::HandleScope::NumberOfHandles();
236d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(count_before, count_after);
237d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
238d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
239d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> CheckAccessorArgsCorrect(Local<String> name,
240d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                                  const AccessorInfo& info) {
241d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.This() == info.Holder());
242d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.Data()->Equals(v8::String::New("data")));
243d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
244d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.This() == info.Holder());
245d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.Data()->Equals(v8::String::New("data")));
246d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  i::Heap::CollectAllGarbage(true);
247d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.This() == info.Holder());
248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK(info.Data()->Equals(v8::String::New("data")));
249d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Integer::New(17);
250d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
251d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
252d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(DirectCall) {
253d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
254d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
255d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"),
256d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   CheckAccessorArgsCorrect,
257d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   NULL,
258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   v8::String::New("data"));
259d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Object> inst = obj->NewInstance();
261d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8::String::New("obj"), inst);
262d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
263d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < 10; i++) {
264d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Value> result = scr->Run();
265d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(!result.IsEmpty());
266d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK_EQ(17, result->Int32Value());
267d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
268d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
269d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
270d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> EmptyGetter(Local<String> name,
271d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                     const AccessorInfo& info) {
272d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CheckAccessorArgsCorrect(name, info);
273d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
274d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CheckAccessorArgsCorrect(name, info);
275d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Handle<v8::Value>();
276d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
277d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
278d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(EmptyResult) {
279d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
280d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
281d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data"));
282d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext context;
283d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Object> inst = obj->NewInstance();
284d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  context->Global()->Set(v8::String::New("obj"), inst);
285d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
286d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < 10; i++) {
287d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Value> result = scr->Run();
288d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(result == v8::Undefined());
289d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
290d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
291d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
292d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
293d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(NoReuseRegress) {
294d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Check that the IC generated for the one test doesn't get reused
295d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // for the other.
296d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
297d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  {
298d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
299d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    obj->SetAccessor(v8_str("xxx"), EmptyGetter, NULL, v8::String::New("data"));
300d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    LocalContext context;
301d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::Object> inst = obj->NewInstance();
302d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    context->Global()->Set(v8::String::New("obj"), inst);
303d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    for (int i = 0; i < 2; i++) {
305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Local<Value> result = scr->Run();
306d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CHECK(result == v8::Undefined());
307d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
308d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
309d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  {
310d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
311d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    obj->SetAccessor(v8_str("xxx"),
312d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     CheckAccessorArgsCorrect,
313d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     NULL,
314d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                     v8::String::New("data"));
315d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    LocalContext context;
316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Handle<v8::Object> inst = obj->NewInstance();
317d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    context->Global()->Set(v8::String::New("obj"), inst);
318d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Local<Script> scr = v8::Script::Compile(v8::String::New("obj.xxx"));
319d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    for (int i = 0; i < 10; i++) {
320d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Local<Value> result = scr->Run();
321d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CHECK(!result.IsEmpty());
322d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CHECK_EQ(17, result->Int32Value());
323d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
324d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
325d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
326d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
327d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> ThrowingGetAccessor(Local<String> name,
328d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                             const AccessorInfo& info) {
329d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
330d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::ThrowException(v8_str("g"));
331d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
332d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
333d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
334d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic void ThrowingSetAccessor(Local<String> name,
335d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                Local<Value> value,
336d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                const AccessorInfo& info) {
337d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::ThrowException(value);
338d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
339d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
340d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
341d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(Regress1054726) {
342d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
343d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
344d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("x"),
345d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   ThrowingGetAccessor,
346d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   ThrowingSetAccessor,
347d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                   Local<Value>());
348d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
349d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
350d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
351d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
352d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Use the throwing property setter/getter in a loop to force
353d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // the accessor ICs to be initialized.
354d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<Value> result;
355d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  result = Script::Compile(v8_str(
356d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var result = '';"
357d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 5; i++) {"
358d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  try { obj.x; } catch (e) { result += e; }"
359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}; result"))->Run();
360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(v8_str("ggggg"), result);
361d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  result = Script::Compile(String::New(
363d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var result = '';"
364d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 5; i++) {"
365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  try { obj.x = i; } catch (e) { result += e; }"
366d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}; result"))->Run();
367d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(v8_str("01234"), result);
368d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
369d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
370d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
371d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> AllocGetter(Local<String> name,
372d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                     const AccessorInfo& info) {
373d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ApiTestFuzzer::Fuzz();
374d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Array::New(1000);
375d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
376d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
377d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
378d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(Gc) {
379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), AllocGetter);
382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Script::Compile(String::New(
385d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var last = [];"
386d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 2048; i++) {"
387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  var result = obj.xxx;"
388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  result[0] = last;"
389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  last = result;"
390d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}"))->Run();
391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
392d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
393d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
394d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> StackCheck(Local<String> name,
395d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                    const AccessorInfo& info) {
396d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  i::StackFrameIterator iter;
397d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; !iter.done(); i++) {
398d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    i::StackFrame* frame = iter.frame();
399d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(i != 0 || (frame->type() == i::StackFrame::EXIT));
400d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(frame->code()->IsCode());
401d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    i::Address pc = frame->pc();
402d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    i::Code* code = frame->code();
403d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    CHECK(code->contains(pc));
404d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    iter.Advance();
405d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
406d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Undefined();
407d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
408d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
409d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
410d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(StackIteration) {
411d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
412d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
413d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  i::StringStream::ClearMentionedObjectCache();
414d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), StackCheck);
415d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
416d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
417d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Script::Compile(String::New(
418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "function foo() {"
419d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  return obj.xxx;"
420d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}"
421d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 100; i++) {"
422d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  foo();"
423d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "}"))->Run();
424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
425d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
426d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
427d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockstatic v8::Handle<Value> AllocateHandles(Local<String> name,
428d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                         const AccessorInfo& info) {
429d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  for (int i = 0; i < i::kHandleBlockSize + 1; i++) {
430d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    v8::Local<v8::Value>::New(name);
431d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
432d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return v8::Integer::New(100);
433d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
434d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
435d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
436d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockTHREADED_TEST(HandleScopeSegment) {
437d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Check that we can return values past popping of handle scope
438d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // segments.
439d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::HandleScope scope;
440d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New();
441d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj->SetAccessor(v8_str("xxx"), AllocateHandles);
442d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  LocalContext env;
443d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  env->Global()->Set(v8_str("obj"), obj->NewInstance());
444d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  v8::Handle<v8::Value> result = Script::Compile(String::New(
445d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "var result;"
446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "for (var i = 0; i < 4; i++)"
447d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "  result = obj.xxx;"
448d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      "result;"))->Run();
449d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CHECK_EQ(100, result->Int32Value());
450d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
451