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