execution.cc revision 3fb3ca8c7ca439d408449a395897395c0faae8d1
18b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch// Copyright 2011 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 <stdlib.h> 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8.h" 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h" 33e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke#include "bootstrapper.h" 348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch#include "codegen.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 36b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "runtime-profiler.h" 37d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "simulator.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8threads.h" 39b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h" 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4544f0eee88ff00398ff7f715fab053374d808c90dSteve BlockStackGuard::StackGuard() 4644f0eee88ff00398ff7f715fab053374d808c90dSteve Block : isolate_(NULL) { 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 4844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid StackGuard::set_interrupt_limits(const ExecutionAccess& lock) { 5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate_ != NULL); 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Ignore attempts to interrupt when interrupts are postponed. 5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (should_postpone_interrupts(lock)) return; 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block thread_local_.jslimit_ = kInterruptLimit; 5544f0eee88ff00398ff7f715fab053374d808c90dSteve Block thread_local_.climit_ = kInterruptLimit; 5644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->SetStackLimits(); 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid StackGuard::reset_limits(const ExecutionAccess& lock) { 6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate_ != NULL); 6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block thread_local_.jslimit_ = thread_local_.real_jslimit_; 6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block thread_local_.climit_ = thread_local_.real_climit_; 6444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->SetStackLimits(); 6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 6644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<Object> Invoke(bool construct, 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> func, 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* has_pending_exception) { 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = func->GetIsolate(); 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Entering JavaScript. 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block VMState state(isolate, JS); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Placeholder for return value. 805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* value = reinterpret_cast<Object*>(kZapValue); 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef Object* (*JSEntryFunction)( 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* entry, 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* function, 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* receiver, 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code; 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (construct) { 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSConstructEntryStub stub; 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code = stub.GetCode(); 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSEntryStub stub; 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code = stub.GetCode(); 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convert calls on global objects to be calls on the global 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // receiver instead to avoid having a 'this' pointer which refers 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // directly to a global object. 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (receiver->IsGlobalObject()) { 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block receiver = Handle<JSObject>(global->global_receiver()); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 106e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Make sure that the global object of the context we're about to 107e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // make the current one is indeed a global object. 108e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(func->context()->global()->IsGlobalObject()); 109e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save and restore context around invocation and block the 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // allocation of handles without explicit handle scopes. 11344f0eee88ff00398ff7f715fab053374d808c90dSteve Block SaveContext save(isolate); 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NoHandleAllocation na; 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSEntryFunction entry = FUNCTION_CAST<JSEntryFunction>(code->entry()); 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call the function through the right JS entry stub. 118402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu byte* entry_address = func->code()->entry(); 1193ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block JSFunction* function = *func; 1203ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Object* receiver_pointer = *receiver; 1213ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block value = CALL_GENERATED_CODE(entry, entry_address, function, 1223ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block receiver_pointer, argc, args); 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value->Verify(); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the pending exception flag and return the value. 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *has_pending_exception = value->IsException(); 13144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(*has_pending_exception == Isolate::Current()->has_pending_exception()); 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*has_pending_exception) { 13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->ReportPendingMessages(); 13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->pending_exception() == Failure::OutOfMemoryException()) { 135257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!isolate->handle_scope_implementer()->ignore_out_of_memory()) { 136e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch V8::FatalProcessOutOfMemory("JS", true); 137e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 138e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch } 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Object>(); 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->clear_pending_message(); 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Handle<Object>(value->ToObjectUnchecked(), isolate); 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 148257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Object> Execution::Call(Handle<Object> callable, 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* pending_exception) { 153257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (!callable->IsJSFunction()) { 154257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch callable = TryGetFunctionDelegate(callable, pending_exception); 155257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (*pending_exception) return callable; 156257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 157257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<JSFunction> func = Handle<JSFunction>::cast(callable); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Invoke(false, func, receiver, argc, args, pending_exception); 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::New(Handle<JSFunction> func, int argc, 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, bool* pending_exception) { 16444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Invoke(true, func, Isolate::Current()->global(), argc, args, 16544f0eee88ff00398ff7f715fab053374d808c90dSteve Block pending_exception); 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::TryCall(Handle<JSFunction> func, 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter a try-block while executing the JavaScript code. To avoid 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // duplicate error printing it must be non-verbose. Also, to avoid 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // creating message objects during stack overflow we shouldn't 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // capture messages. 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch catcher; 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block catcher.SetVerbose(false); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block catcher.SetCaptureMessage(false); 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = Invoke(false, func, receiver, argc, args, 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught_exception); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*caught_exception) { 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(catcher.HasCaught()); 18744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 18844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate->has_pending_exception()); 18944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate->external_caught_exception()); 19044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->pending_exception() == 19144f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->heap()->termination_exception()) { 19244f0eee88ff00398ff7f715fab053374d808c90dSteve Block result = isolate->factory()->termination_exception(); 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = v8::Utils::OpenHandle(*catcher.Exception()); 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->OptionalRescheduleException(true); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!Isolate::Current()->has_pending_exception()); 20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!Isolate::Current()->external_caught_exception()); 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!object->IsJSFunction()); 2078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 2088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = isolate->factory(); 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If you return a function from here, it will be called when an 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // attempt is made to call the given object as a function. 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Objects created through the API can have an instance-call handler 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that should be used when calling the object as a function. 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsHeapObject() && 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject::cast(*object)->map()->has_instance_call_handler()) { 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>( 2188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->global_context()->call_as_function_delegate()); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2218b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return factory->undefined_value(); 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 225257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object, 226257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool* has_pending_exception) { 227257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(!object->IsJSFunction()); 228257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Isolate* isolate = Isolate::Current(); 229257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 230257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Objects created through the API can have an instance-call handler 231257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // that should be used when calling the object as a function. 232257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (object->IsHeapObject() && 233257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HeapObject::cast(*object)->map()->has_instance_call_handler()) { 234257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return Handle<JSFunction>( 235257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->global_context()->call_as_function_delegate()); 236257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 237257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 238257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If the Object doesn't have an instance-call handler we should 239257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // throw a non-callable exception. 240257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( 241257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "called_non_callable", i::HandleVector<i::Object>(&object, 1)); 242257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->Throw(*error_obj); 243257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch *has_pending_exception = true; 244257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 245257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return isolate->factory()->undefined_value(); 246257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 247257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!object->IsJSFunction()); 2518b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If you return a function from here, it will be called when an 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // attempt is made to call the given object as a constructor. 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Objects created through the API can have an instance-call handler 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that should be used when calling the object as a function. 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsHeapObject() && 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject::cast(*object)->map()->has_instance_call_handler()) { 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>( 2618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->global_context()->call_as_constructor_delegate()); 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 2648b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return isolate->factory()->undefined_value(); 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochHandle<Object> Execution::TryGetConstructorDelegate( 269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Handle<Object> object, 270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch bool* has_pending_exception) { 271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch ASSERT(!object->IsJSFunction()); 272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Isolate* isolate = Isolate::Current(); 273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If you return a function from here, it will be called when an 275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // attempt is made to call the given object as a constructor. 276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // Objects created through the API can have an instance-call handler 278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // that should be used when calling the object as a function. 279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (object->IsHeapObject() && 280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch HeapObject::cast(*object)->map()->has_instance_call_handler()) { 281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return Handle<JSFunction>( 282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->global_context()->call_as_constructor_delegate()); 283257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch } 284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 285257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // If the Object doesn't have an instance-call handler we should 286257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch // throw a non-callable exception. 287257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch i::Handle<i::Object> error_obj = isolate->factory()->NewTypeError( 288257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch "called_non_callable", i::HandleVector<i::Object>(&object, 1)); 289257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate->Throw(*error_obj); 290257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch *has_pending_exception = true; 291257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 292257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch return isolate->factory()->undefined_value(); 293257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch} 294257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 295257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsStackOverflow() { 29744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (thread_local_.jslimit_ != kInterruptLimit && 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.climit_ != kInterruptLimit); 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::EnableInterrupts() { 30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 3056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (has_pending_interrupts(access)) { 3066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::SetStackLimit(uintptr_t limit) { 31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the current limits are special (eg due to a pending interrupt) then 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // leave them alone. 315257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(isolate_, limit); 316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (thread_local_.jslimit_ == thread_local_.real_jslimit_) { 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.jslimit_ = jslimit; 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 319d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (thread_local_.climit_ == thread_local_.real_climit_) { 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.climit_ = limit; 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 322d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block thread_local_.real_climit_ = limit; 323d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block thread_local_.real_jslimit_ = jslimit; 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DisableInterrupts() { 32844f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reset_limits(access); 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsInterrupted() { 33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & INTERRUPT; 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Interrupt() { 34044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= INTERRUPT; 3426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsPreempted() { 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & PREEMPT; 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Preempt() { 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= PREEMPT; 3556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsTerminateExecution() { 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & TERMINATE; 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::TerminateExecution() { 36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= TERMINATE; 3686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 372b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochbool StackGuard::IsRuntimeProfilerTick() { 37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 374b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch return thread_local_.interrupt_flags_ & RUNTIME_PROFILER_TICK; 375b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 376b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 377b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 378b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid StackGuard::RequestRuntimeProfilerTick() { 379b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch // Ignore calls if we're not optimizing or if we can't get the lock. 38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (FLAG_opt && ExecutionAccess::TryLock(isolate_)) { 381b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch thread_local_.interrupt_flags_ |= RUNTIME_PROFILER_TICK; 382b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch if (thread_local_.postpone_interrupts_nesting_ == 0) { 383b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch thread_local_.jslimit_ = thread_local_.climit_ = kInterruptLimit; 38444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->SetStackLimits(); 385b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess::Unlock(isolate_); 387b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 388b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch} 389b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 390b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugBreak() { 39344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & DEBUGBREAK; 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugBreak() { 39944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= DEBUGBREAK; 4016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugCommand() { 40644f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & DEBUGCOMMAND; 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugCommand() { 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_debugger_auto_break) { 41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= DEBUGCOMMAND; 4156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Continue(InterruptFlag after_what) { 42144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); 4236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reset_limits(access); 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::ArchiveStackGuard(char* to) { 43044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocal blank; 43344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 43444f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Set the stack limits using the old thread_local_. 43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // TODO(isolates): This was the old semantics of constructing a ThreadLocal 43644f0eee88ff00398ff7f715fab053374d808c90dSteve Block // (as the ctor called SetStackLimits, which looked at the 43744f0eee88ff00398ff7f715fab053374d808c90dSteve Block // current thread_local_ from StackGuard)-- but is this 43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // really what was intended? 43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->SetStackLimits(); 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_ = blank; 44144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return to + sizeof(ThreadLocal); 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::RestoreStackGuard(char* from) { 44744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ExecutionAccess access(isolate_); 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 44944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->SetStackLimits(); 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return from + sizeof(ThreadLocal); 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::FreeThreadResources() { 4553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch Isolate::PerIsolateThreadData* per_thread = 4563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch isolate_->FindOrAllocatePerThreadDataForThisThread(); 4573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch per_thread->set_stack_limit(thread_local_.real_climit_); 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ThreadLocal::Clear() { 462d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block real_jslimit_ = kIllegalLimit; 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jslimit_ = kIllegalLimit; 464d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block real_climit_ = kIllegalLimit; 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block climit_ = kIllegalLimit; 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nesting_ = 0; 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block postpone_interrupts_nesting_ = 0; 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block interrupt_flags_ = 0; 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool StackGuard::ThreadLocal::Initialize(Isolate* isolate) { 47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block bool should_set_stack_limits = false; 474d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (real_climit_ == kIllegalLimit) { 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Takes the address of the limit variable in order to find out where 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top of stack is right now. 4771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block const uintptr_t kLimitSize = FLAG_stack_size * KB; 4783ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; 4793ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); 480257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch real_jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); 481257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch jslimit_ = SimulatorStack::JsLimitFromCLimit(isolate, limit); 482d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block real_climit_ = limit; 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block climit_ = limit; 48444f0eee88ff00398ff7f715fab053374d808c90dSteve Block should_set_stack_limits = true; 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nesting_ = 0; 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block postpone_interrupts_nesting_ = 0; 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block interrupt_flags_ = 0; 48944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return should_set_stack_limits; 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ClearThread(const ExecutionAccess& lock) { 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.Clear(); 49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->heap()->SetStackLimits(); 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::InitThread(const ExecutionAccess& lock) { 500257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch if (thread_local_.Initialize(isolate_)) isolate_->heap()->SetStackLimits(); 501257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch Isolate::PerIsolateThreadData* per_thread = 502257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch isolate_->FindOrAllocatePerThreadDataForThisThread(); 503257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch uintptr_t stored_limit = per_thread->stack_limit(); 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // You should hold the ExecutionAccess lock when you call this. 50544f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (stored_limit != 0) { 5063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch SetStackLimit(stored_limit); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- C a l l s t o n a t i v e s --- 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51344f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \ 51444f0eee88ff00398ff7f715fab053374d808c90dSteve Block do { \ 5158b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); \ 51644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object** args[argc] = argv; \ 51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(has_pending_exception != NULL); \ 5188b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return Call(isolate->name##_fun(), \ 5198b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->js_builtins_object(), argc, args, \ 52044f0eee88ff00398ff7f715fab053374d808c90dSteve Block has_pending_exception); \ 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (false) 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToBoolean(Handle<Object> obj) { 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // See the similar code in runtime.js:ToBoolean. 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsBoolean()) return obj; 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool result = true; 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsString()) { 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Handle<String>::cast(obj)->length() != 0; 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (obj->IsNull() || obj->IsUndefined()) { 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = false; 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (obj->IsNumber()) { 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double value = obj->Number(); 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = !((value == 0) || isnan(value)); 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 53644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Handle<Object>(HEAP->ToBoolean(result)); 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) { 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_number, 1, { obj.location() }, exc); 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToString(Handle<Object> obj, bool* exc) { 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_string, 1, { obj.location() }, exc); 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) { 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_detail_string, 1, { obj.location() }, exc); 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsJSObject()) return obj; 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc); 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) { 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_integer, 1, { obj.location() }, exc); 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) { 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_uint32, 1, { obj.location() }, exc); 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) { 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_int32, 1, { obj.location() }, exc); 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::NewDate(double time, bool* exc) { 57744f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> time_obj = FACTORY->NewNumber(time); 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(create_date, 1, { time_obj.location() }, exc); 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef RETURN_NATIVE_CALL 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 585f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, 586f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<String> flags, 587f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool* exc) { 58844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<JSFunction> function = Handle<JSFunction>( 58944f0eee88ff00398ff7f715fab053374d808c90dSteve Block pattern->GetIsolate()->global_context()->regexp_function()); 590f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral( 59144f0eee88ff00398ff7f715fab053374d808c90dSteve Block function, pattern, flags, exc); 592f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (*exc) return Handle<JSRegExp>(); 593f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return Handle<JSRegExp>::cast(re_obj); 594f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 595f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 596f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { 5988b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = string->GetIsolate(); 5998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Factory* factory = isolate->factory(); 6008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int int_index = static_cast<int>(index); 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (int_index < 0 || int_index >= string->length()) { 6038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return factory->undefined_value(); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> char_at = 6078b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch GetProperty(isolate->js_builtins_object(), 6088b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch factory->char_at_symbol()); 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!char_at->IsJSFunction()) { 6108b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return factory->undefined_value(); 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception; 6148b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Handle<Object> index_object = factory->NewNumberFromInt(int_index); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** index_arg[] = { index_object.location() }; 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block string, 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ARRAY_SIZE(index_arg), 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index_arg, 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 6228b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return factory->undefined_value(); 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSFunction> Execution::InstantiateFunction( 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo> data, bool* exc) { 6308b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = data->GetIsolate(); 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fast case: see if the function has already been instantiated 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int serial_number = Smi::cast(data->serial_number())->value(); 63344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Object* elm = 6348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->global_context()->function_cache()-> 63544f0eee88ff00398ff7f715fab053374d808c90dSteve Block GetElementNoExceptionThrown(serial_number); 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm)); 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The function has not yet been instantiated in this context; do it. 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[1] = { Handle<Object>::cast(data).location() }; 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = 6408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Call(isolate->instantiate_fun(), 6418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->js_builtins_object(), 1, args, exc); 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSFunction>::null(); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>::cast(result); 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data, 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc) { 6498b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = data->GetIsolate(); 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (data->property_list()->IsUndefined() && 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !data->constructor()->IsUndefined()) { 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialization to make gcc happy. 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 6558b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HandleScope scope(isolate); 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo> cons_template = 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo>( 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplateInfo::cast(data->constructor())); 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> cons = InstantiateFunction(cons_template, exc); 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value = New(cons, 0, NULL, exc); 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = *value; 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!*exc); 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSObject>(JSObject::cast(result)); 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[1] = { Handle<Object>::cast(data).location() }; 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = 6708b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Call(isolate->instantiate_fun(), 6718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->js_builtins_object(), 1, args, exc); 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSObject>::cast(result); 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Execution::ConfigureInstance(Handle<Object> instance, 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> instance_template, 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc) { 6818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[2] = { instance.location(), instance_template.location() }; 6838b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Execution::Call(isolate->configure_instance_fun(), 6848b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->js_builtins_object(), 2, args, exc); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> Execution::GetStackTraceLine(Handle<Object> recv, 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> fun, 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> pos, 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> is_global) { 6928b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = fun->GetIsolate(); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 4; 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[argc] = { recv.location(), 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>::cast(fun).location(), 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos.location(), 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_global.location() }; 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 69944f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<Object> result = 7008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch TryCall(isolate->get_stack_trace_line_fun(), 7018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->js_builtins_object(), argc, args, 70244f0eee88ff00398ff7f715fab053374d808c90dSteve Block &caught_exception); 7038b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch if (caught_exception || !result->IsString()) { 7048b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch return isolate->factory()->empty_symbol(); 7058b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch } 7068b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<String>::cast(result); 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Object* RuntimePreempt() { 71244f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 71344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the preempt request flag. 71544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stack_guard()->Continue(PREEMPT); 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextSwitcher::PreemptionReceived(); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->debug()->InDebugger()) { 721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If currently in the debugger don't do any actual preemption but record 722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that preemption occoured while in the debugger. 72344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->debug()->PreemptionWhileInDebugger(); 724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform preemption. 726257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate)); 727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Thread::YieldCPU(); 728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 73044f0eee88ff00398ff7f715fab053374d808c90dSteve Block { // NOLINT 73144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Perform preemption. 732257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch v8::Unlocker unlocker(reinterpret_cast<v8::Isolate*>(isolate)); 73344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Thread::YieldCPU(); 73444f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 73744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->undefined_value(); 738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* Execution::DebugBreakHelper() { 74344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 74444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just continue if breaks are disabled. 74644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->debug()->disable_break()) { 74744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->undefined_value(); 748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 750e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Ignore debug break during bootstrapping. 75144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->bootstrapper()->IsActive()) { 75244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->undefined_value(); 753e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 754e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 7568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch JavaScriptFrameIterator it(isolate); 757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!it.done()); 758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* fun = it.frame()->function(); 759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (fun && fun->IsJSFunction()) { 760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in builtin functions. 761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (JSFunction::cast(fun)->IsBuiltin()) { 76244f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->undefined_value(); 763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GlobalObject* global = JSFunction::cast(fun)->context()->global(); 765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in debugger functions. 76644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (isolate->debug()->IsDebugGlobal(global)) { 76744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->undefined_value(); 768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Collect the break state before clearing the flags. 773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool debug_command_only = 77444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stack_guard()->IsDebugCommand() && 77544f0eee88ff00398ff7f715fab053374d808c90dSteve Block !isolate->stack_guard()->IsDebugBreak(); 776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 777e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Clear the debug break request flag. 77844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->stack_guard()->Continue(DEBUGBREAK); 779e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 780e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ProcessDebugMesssages(debug_command_only); 781e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 782e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Return to continue execution. 78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->undefined_value(); 784e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 785e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 786e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Execution::ProcessDebugMesssages(bool debug_command_only) { 7878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch Isolate* isolate = Isolate::Current(); 788e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Clear the debug command request flag. 7898b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->stack_guard()->Continue(DEBUGCOMMAND); 790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7918b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch HandleScope scope(isolate); 792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. Just continue if we fail to enter the debugger. 793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) { 795e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return; 796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify the debug event listeners. Indicate auto continue if the break was 799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a debug command break. 8008b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(), 8018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch debug_command_only); 802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 803e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 804e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 8075913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Execution::HandleStackGuardInterrupt() { 80844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 80944f0eee88ff00398ff7f715fab053374d808c90dSteve Block StackGuard* stack_guard = isolate->stack_guard(); 81044f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->stack_interrupts()->Increment(); 81144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (stack_guard->IsRuntimeProfilerTick()) { 81244f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->counters()->runtime_profiler_ticks()->Increment(); 81344f0eee88ff00398ff7f715fab053374d808c90dSteve Block stack_guard->Continue(RUNTIME_PROFILER_TICK); 81444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->runtime_profiler()->OptimizeNow(); 815b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 81744f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (stack_guard->IsDebugBreak() || stack_guard->IsDebugCommand()) { 818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugBreakHelper(); 819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 82144f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (stack_guard->IsPreempted()) RuntimePreempt(); 82244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (stack_guard->IsTerminateExecution()) { 82344f0eee88ff00398ff7f715fab053374d808c90dSteve Block stack_guard->Continue(TERMINATE); 82444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->TerminateExecution(); 825a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 82644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (stack_guard->IsInterrupted()) { 82744f0eee88ff00398ff7f715fab053374d808c90dSteve Block stack_guard->Continue(INTERRUPT); 82844f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->StackOverflow(); 829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 83044f0eee88ff00398ff7f715fab053374d808c90dSteve Block return isolate->heap()->undefined_value(); 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 834