13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h"
2985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch#include "accessors.h"
303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "contexts.h"
32b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "deoptimizer.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "execution.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "factory.h"
353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "frames-inl.h"
363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "isolate.h"
37257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#include "list-inl.h"
383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include "property-details.h"
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class C>
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic C* FindInPrototypeChain(Object* obj, bool* found_it) {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!*found_it);
4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = HEAP;
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (!Is<C>(obj)) {
4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (obj == heap->null_value()) return NULL;
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    obj = obj->GetPrototype();
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  *found_it = true;
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return C::cast(obj);
54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Entry point that never should be called.
585913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NULL;
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* Accessors::IllegalGetAccessor(Object* object, void*) {
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  UNREACHABLE();
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return object;
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
705913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ReadOnlySetAccessor(JSObject*, Object* value, void*) {
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // According to ECMA-262, section 8.6.2.2, page 28, setting
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // read-only properties must be silently ignored.
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return value;
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ArrayLength
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
825913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Traverse the prototype chain until we reach an array.
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool found_it = false;
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSArray* holder = FindInPrototypeChain<JSArray>(object, &found_it);
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!found_it) return Smi::FromInt(0);
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return holder->length();
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The helper function will 'flatten' Number objects.
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* Accessors::FlattenNumber(Object* value) {
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (value->IsNumber() || !value->IsJSValue()) return value;
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSValue* wrapper = JSValue::cast(value);
9544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(Isolate::Current()->context()->global_context()->number_function()->
9644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      has_initial_map());
9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Map* number_map = Isolate::Current()->context()->global_context()->
9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      number_function()->initial_map();
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (wrapper->map() == number_map) return wrapper->value();
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return value;
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1045913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) {
10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = object->GetIsolate();
1067d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch
1077d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  // This means one of the object's prototypes is a JSArray and the
1087d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  // object does not have a 'length' property.  Calling SetProperty
1097d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  // causes an infinite loop.
1107d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  if (!object->IsJSArray()) {
1117d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch    return object->SetLocalPropertyIgnoreAttributes(
1127d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch        isolate->heap()->length_symbol(), value, NONE);
1137d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch  }
1147d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  value = FlattenNumber(value);
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Need to call methods that may trigger GC.
11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Protect raw pointers.
12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSObject> object_handle(object, isolate);
12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<Object> value_handle(value, isolate);
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool has_exception;
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> uint32_v = Execution::ToUint32(value_handle, &has_exception);
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (has_exception) return Failure::Exception();
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> number_v = Execution::ToNumber(value_handle, &has_exception);
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (has_exception) return Failure::Exception();
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (uint32_v->Number() == number_v->Number()) {
1317d3e7fc4b65010eabe860313ee0c64f50843f6e3Ben Murdoch    return Handle<JSArray>::cast(object_handle)->SetElementsLength(*uint32_v);
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->Throw(
13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      *isolate->factory()->NewRangeError("invalid_array_length",
13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                         HandleVector<Object>(NULL, 0)));
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ArrayLength = {
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ArrayGetLength,
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ArraySetLength,
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::StringLength
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1515913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::StringGetLength(Object* object, void*) {
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* value = object;
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (object->IsJSValue()) value = JSValue::cast(object)->value();
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (value->IsString()) return Smi::FromInt(String::cast(value)->length());
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If object is not a string we return 0 to be compatible with WebKit.
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note: Firefox returns the length of ToString(object).
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Smi::FromInt(0);
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::StringLength = {
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  StringGetLength,
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptSource
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1735913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetSource(Object* object, void*) {
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->source();
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptSource = {
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetSource,
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptName
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1915913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetName(Object* object, void*) {
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->name();
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptName = {
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetName,
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptId
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2095913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetId(Object* object, void*) {
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->id();
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptId = {
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetId,
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptLineOffset
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2275913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetLineOffset(Object* object, void*) {
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->line_offset();
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptLineOffset = {
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetLineOffset,
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptColumnOffset
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2455913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetColumnOffset(Object* object, void*) {
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->column_offset();
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptColumnOffset = {
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetColumnOffset,
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptData
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2635913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetData(Object* object, void*) {
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->data();
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptData = {
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetData,
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptType
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2815913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetType(Object* object, void*) {
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->type();
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptType = {
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetType,
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptCompilationType
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2995913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetCompilationType(Object* object, void*) {
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->compilation_type();
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptCompilationType = {
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetCompilationType,
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptGetLineEnds
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3175913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) {
31844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  JSValue* wrapper = JSValue::cast(object);
31944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = wrapper->GetIsolate();
32044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
32144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<Script> script(Script::cast(wrapper->value()), isolate);
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitScriptLineEnds(script);
323d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASSERT(script->line_ends()->IsFixedArray());
324d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
3258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // We do not want anyone to modify this array from JS.
32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(*line_ends == isolate->heap()->empty_fixed_array() ||
32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block         line_ends->map() == isolate->heap()->fixed_cow_array_map());
32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSArray> js_array =
32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewJSArrayWithElements(line_ends);
330d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return *js_array;
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptLineEnds = {
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetLineEnds,
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ScriptGetContextData
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3465913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetContextData(Object* object, void*) {
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Script::cast(script)->context_data();
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ScriptContextData = {
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ScriptGetContextData,
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Accessors::ScriptGetEvalFromScript
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3645913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetEvalFromScript(Object* object, void*) {
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* script = JSValue::cast(object)->value();
366d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (!Script::cast(script)->eval_from_shared()->IsUndefined()) {
367d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    Handle<SharedFunctionInfo> eval_from_shared(
368d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared()));
369d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
370d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (eval_from_shared->script()->IsScript()) {
371d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
372d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      return *GetScriptWrapper(eval_from_script);
373d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
374d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return HEAP->undefined_value();
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockconst AccessorDescriptor Accessors::ScriptEvalFromScript = {
380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ScriptGetEvalFromScript,
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Accessors::ScriptGetEvalFromScriptPosition
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3915913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) {
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Script> script(Script::cast(JSValue::cast(object)->value()));
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If this is not a script compiled through eval there is no eval position.
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int compilation_type = Smi::cast(script->compilation_type())->value();
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (compilation_type != Script::COMPILATION_TYPE_EVAL) {
39844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return HEAP->undefined_value();
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Get the function from where eval was called and find the source position
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // from the instruction offset.
403d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Handle<Code> code(SharedFunctionInfo::cast(
404d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      script->eval_from_shared())->code());
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Smi::FromInt(code->SourcePosition(code->instruction_start() +
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      script->eval_from_instructions_offset()->value()));
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
410d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockconst AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
411d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ScriptGetEvalFromScriptPosition,
412d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  IllegalSetter,
413d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  0
414d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block};
415d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
416d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
417d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//
418d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block// Accessors::ScriptGetEvalFromFunctionName
419d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block//
420d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
421d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
4225913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ScriptGetEvalFromFunctionName(Object* object, void*) {
423d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Object* script = JSValue::cast(object)->value();
424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(
425d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Script::cast(script)->eval_from_shared()));
426d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
427d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
428d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Find the name of the function calling eval.
429d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (!shared->name()->IsUndefined()) {
430d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return shared->name();
431d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  } else {
432d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    return shared->inferred_name();
433d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
434d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
435d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
436d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
437d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockconst AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
438d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ScriptGetEvalFromFunctionName,
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IllegalSetter,
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::FunctionPrototype
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4495913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = Isolate::Current()->heap();
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool found_it = false;
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!found_it) return heap->undefined_value();
454e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  while (!function->should_have_prototype()) {
455e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    found_it = false;
456e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    function = FindInPrototypeChain<JSFunction>(object->GetPrototype(),
457e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                &found_it);
458e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // There has to be one because we hit the getter.
459e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    ASSERT(found_it);
460e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
461e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!function->has_prototype()) {
4635913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* prototype;
46444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    { MaybeObject* maybe_prototype = heap->AllocateFunctionPrototype(function);
4655913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
4665913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
4675913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    Object* result;
4685913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    { MaybeObject* maybe_result = function->SetPrototype(prototype);
4695913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck      if (!maybe_result->ToObject(&result)) return maybe_result;
4705913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    }
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return function->prototype();
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4765913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::FunctionSetPrototype(JSObject* object,
4775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                             Object* value,
4785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                             void*) {
47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Heap* heap = object->GetHeap();
480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool found_it = false;
481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!found_it) return heap->undefined_value();
483e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  if (!function->should_have_prototype()) {
484e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    // Since we hit this accessor, object will have no prototype property.
48544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return object->SetLocalPropertyIgnoreAttributes(heap->prototype_symbol(),
486e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                    value,
487e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                    NONE);
488e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  }
489e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
4905913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  Object* prototype;
4915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  { MaybeObject* maybe_prototype = function->SetPrototype(value);
4925913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck    if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
4935913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  }
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(function->prototype() == value);
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return function;
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::FunctionPrototype = {
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FunctionGetPrototype,
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FunctionSetPrototype,
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::FunctionLength
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5115913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool found_it = false;
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!found_it) return Smi::FromInt(0);
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if already compiled.
516756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (!function->shared()->is_compiled()) {
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the function isn't compiled yet, the length is not computed
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // correctly yet. Compile it now and return the right length.
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    HandleScope scope;
520b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Handle<JSFunction> handle(function);
5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
5223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return Failure::Exception();
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
524b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return Smi::FromInt(handle->shared()->length());
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Smi::FromInt(function->shared()->length());
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::FunctionLength = {
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FunctionGetLength,
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ReadOnlySetAccessor,
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::FunctionName
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5435913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::FunctionGetName(Object* object, void*) {
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool found_it = false;
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
54644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!found_it) return HEAP->undefined_value();
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return holder->shared()->name();
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::FunctionName = {
552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FunctionGetName,
553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ReadOnlySetAccessor,
554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::FunctionArguments
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
563b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic MaybeObject* ConstructArgumentsObjectForInlinedFunction(
564b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    JavaScriptFrame* frame,
565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Handle<JSFunction> inlined_function,
566b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int inlined_frame_index) {
56744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Factory* factory = Isolate::Current()->factory();
5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Vector<SlotRef> args_slots =
5693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      SlotRef::ComputeSlotMappingForArguments(
5703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          frame,
5713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          inlined_frame_index,
5723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          inlined_function->shared()->formal_parameter_count());
5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int args_count = args_slots.length();
574b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<JSObject> arguments =
57544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      factory->NewArgumentsObject(inlined_function, args_count);
57644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<FixedArray> array = factory->NewFixedArray(args_count);
577b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (int i = 0; i < args_count; ++i) {
578b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Handle<Object> value = args_slots[i].GetValue();
579b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    array->set(i, *value);
580b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
581b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  arguments->set_elements(*array);
5823ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  args_slots.Dispose();
583b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
584b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Return the freshly allocated arguments object.
585b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return *arguments;
586b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
587b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5895913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
59044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool found_it = false;
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
59444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!found_it) return isolate->heap()->undefined_value();
59544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSFunction> function(holder, isolate);
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
597589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (function->shared()->native()) return isolate->heap()->null_value();
598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find the top invocation of the function by traversing frames.
599b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  List<JSFunction*> functions(2);
6008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    JavaScriptFrame* frame = it.frame();
602b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    frame->GetFunctions(&functions);
603b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    for (int i = functions.length() - 1; i >= 0; i--) {
604b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      // Skip all frames that aren't invocations of the given function.
605b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (functions[i] != *function) continue;
606b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
607b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      if (i > 0) {
6081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        // The function in question was inlined.  Inlined functions have the
6091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        // correct number of arguments and no allocated arguments object, so
6101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        // we can construct a fresh one by interpreting the function's
6111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        // deoptimization input data.
612b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
6131e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      }
6141e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6151e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      if (!frame->is_optimized()) {
616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        // If there is an arguments variable in the stack, we return that.
6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        Handle<ScopeInfo> scope_info(function->shared()->scope_info());
6183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        int index = scope_info->StackSlotIndex(
6193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            isolate->heap()->arguments_symbol());
620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        if (index >= 0) {
62144f0eee88ff00398ff7f715fab053374d808c90dSteve Block          Handle<Object> arguments(frame->GetExpression(index), isolate);
622086aeeaae12517475c22695a200be45495516549Ben Murdoch          if (!arguments->IsArgumentsMarker()) return *arguments;
623b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        }
624b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      }
6251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // If there is no arguments variable in the stack or we have an
6271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // optimized frame, we find the frame that holds the actual arguments
6281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // passed to the function.
6291e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      it.AdvanceToArgumentsFrame();
6301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      frame = it.frame();
6311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // Get the number of arguments and construct an arguments object
6331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // mirror for the right frame.
63444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      const int length = frame->ComputeParametersCount();
63544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
63644f0eee88ff00398ff7f715fab053374d808c90dSteve Block          function, length);
63744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
6381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // Copy the parameters to the arguments object.
6401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      ASSERT(array->length() == length);
6411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
6421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      arguments->set_elements(*array);
6431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
6441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      // Return the freshly allocated arguments object.
6451e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      return *arguments;
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
647b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    functions.Rewind(0);
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // No frame corresponding to the given function found. Return null.
65144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->heap()->null_value();
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::FunctionArguments = {
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FunctionGetArguments,
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ReadOnlySetAccessor,
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::FunctionCaller
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66744f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic MaybeObject* CheckNonStrictCallerOrThrow(
66844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Isolate* isolate,
66944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    JSFunction* caller) {
67044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  DisableAssertNoAllocation enable_allocation;
6713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!caller->shared()->is_classic_mode()) {
67244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->Throw(
67344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        *isolate->factory()->NewTypeError("strict_caller",
67444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                          HandleVector<Object>(NULL, 0)));
67544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
67644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return caller;
67744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
67844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
67944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
680257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochclass FrameFunctionIterator {
681257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch public:
682257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  FrameFunctionIterator(Isolate* isolate, const AssertNoAllocation& promise)
683257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      : frame_iterator_(isolate),
684257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        functions_(2),
685257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        index_(0) {
686257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    GetFunctions();
687257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
688257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JSFunction* next() {
689257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (functions_.length() == 0) return NULL;
690257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JSFunction* next_function = functions_[index_];
691257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    index_--;
692257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (index_ < 0) {
693257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      GetFunctions();
694257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
695257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return next_function;
696257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
697257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
698257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Iterate through functions until the first occurence of 'function'.
699257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Returns true if 'function' is found, and false if the iterator ends
700257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // without finding it.
701257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  bool Find(JSFunction* function) {
702257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JSFunction* next_function;
703257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    do {
704257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      next_function = next();
705257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (next_function == function) return true;
706257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    } while (next_function != NULL);
707257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return false;
708257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
709589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
710257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch private:
711257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  void GetFunctions() {
712257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    functions_.Rewind(0);
713257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (frame_iterator_.done()) return;
714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    JavaScriptFrame* frame = frame_iterator_.frame();
715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    frame->GetFunctions(&functions_);
716257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    ASSERT(functions_.length() > 0);
717257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    frame_iterator_.Advance();
718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    index_ = functions_.length() - 1;
719257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JavaScriptFrameIterator frame_iterator_;
721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  List<JSFunction*> functions_;
722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  int index_;
723257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
724257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
725257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
7265913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
72744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
72844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScope scope(isolate);
7295913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  AssertNoAllocation no_alloc;
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool found_it = false;
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
73244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!found_it) return isolate->heap()->undefined_value();
733589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (holder->shared()->native()) return isolate->heap()->null_value();
73444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSFunction> function(holder, isolate);
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
736257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  FrameFunctionIterator it(isolate, no_alloc);
737257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
738257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Find the function from the frames.
739257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!it.Find(*function)) {
740257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    // No frame corresponding to the given function found. Return null.
741257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return isolate->heap()->null_value();
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
744257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // Find previously called non-toplevel function.
745257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JSFunction* caller;
746257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  do {
747257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    caller = it.next();
748257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    if (caller == NULL) return isolate->heap()->null_value();
749257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } while (caller->shared()->is_toplevel());
750257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
751257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // If caller is a built-in function and caller's caller is also built-in,
752257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  // use that instead.
753257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  JSFunction* potential_caller = caller;
754257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  while (potential_caller != NULL && potential_caller->IsBuiltin()) {
755257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    caller = potential_caller;
756257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    potential_caller = it.next();
757257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
7583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // If caller is bound, return null. This is compatible with JSC, and
7593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // allows us to make bound functions use the strict function map
7603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // and its associated throwing caller and arguments.
7613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (caller->shared()->bound()) {
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return isolate->heap()->null_value();
7633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
764257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return CheckNonStrictCallerOrThrow(isolate, caller);
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::FunctionCaller = {
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  FunctionGetCaller,
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ReadOnlySetAccessor,
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Accessors::ObjectPrototype
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7805913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object* current = receiver->GetPrototype();
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (current->IsJSObject() &&
783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block         JSObject::cast(current)->map()->is_hidden_prototype()) {
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    current = current->GetPrototype();
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return current;
787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7905913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver,
7915913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           Object* value,
7925913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                           void*) {
793402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  const bool skip_hidden_prototypes = true;
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // To be consistent with other Set functions, return the value.
795402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return receiver->SetPrototype(value, skip_hidden_prototypes);
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst AccessorDescriptor Accessors::ObjectPrototype = {
800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ObjectGetPrototype,
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ObjectSetPrototype,
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  0
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
806