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