execution.cc revision 5913587db4c6bab03d97bfe44b06289fd6d7270d
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2006-2008 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" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "codegen-inl.h" 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 36d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "simulator.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8threads.h" 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<Object> Invoke(bool construct, 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> func, 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* has_pending_exception) { 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Entering JavaScript. 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VMState state(JS); 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Placeholder for return value. 535913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck MaybeObject* value = reinterpret_cast<Object*>(kZapValue); 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef Object* (*JSEntryFunction)( 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* entry, 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* function, 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* receiver, 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args); 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code; 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (construct) { 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSConstructEntryStub stub; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code = stub.GetCode(); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSEntryStub stub; 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code = stub.GetCode(); 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convert calls on global objects to be calls on the global 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // receiver instead to avoid having a 'this' pointer which refers 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // directly to a global object. 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (receiver->IsGlobalObject()) { 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block receiver = Handle<JSObject>(global->global_receiver()); 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Make sure that the global object of the context we're about to 80e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // make the current one is indeed a global object. 81e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ASSERT(func->context()->global()->IsGlobalObject()); 82e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save and restore context around invocation and block the 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // allocation of handles without explicit handle scopes. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SaveContext save; 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NoHandleAllocation na; 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSEntryFunction entry = FUNCTION_CAST<JSEntryFunction>(code->entry()); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call the function through the right JS entry stub. 91402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu byte* entry_address = func->code()->entry(); 923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block JSFunction* function = *func; 933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block Object* receiver_pointer = *receiver; 943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block value = CALL_GENERATED_CODE(entry, entry_address, function, 953ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block receiver_pointer, argc, args); 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value->Verify(); 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the pending exception flag and return the value. 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *has_pending_exception = value->IsException(); 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(*has_pending_exception == Top::has_pending_exception()); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*has_pending_exception) { 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::ReportPendingMessages(); 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Object>(); 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::clear_pending_message(); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 1125913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return Handle<Object>(value->ToObjectUnchecked()); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::Call(Handle<JSFunction> func, 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* pending_exception) { 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Invoke(false, func, receiver, argc, args, pending_exception); 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::New(Handle<JSFunction> func, int argc, 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, bool* pending_exception) { 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Invoke(true, func, Top::global(), argc, args, pending_exception); 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::TryCall(Handle<JSFunction> func, 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter a try-block while executing the JavaScript code. To avoid 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // duplicate error printing it must be non-verbose. Also, to avoid 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // creating message objects during stack overflow we shouldn't 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // capture messages. 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch catcher; 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block catcher.SetVerbose(false); 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block catcher.SetCaptureMessage(false); 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = Invoke(false, func, receiver, argc, args, 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught_exception); 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*caught_exception) { 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(catcher.HasCaught()); 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Top::has_pending_exception()); 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Top::external_caught_exception()); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Top::pending_exception() == Heap::termination_exception()) { 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Factory::termination_exception(); 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = v8::Utils::OpenHandle(*catcher.Exception()); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::OptionalRescheduleException(true); 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!Top::has_pending_exception()); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!Top::external_caught_exception()); 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!object->IsJSFunction()); 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If you return a function from here, it will be called when an 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // attempt is made to call the given object as a function. 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Regular expressions can be called as functions in both Firefox 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and Safari so we allow it too. 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsJSRegExp()) { 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> exec = Factory::exec_symbol(); 1755913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // TODO(lrn): Bug 617. We should use the default function here, not the 1765913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // one on the RegExp object. 1775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* exec_function; 1785913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck { MaybeObject* maybe_exec_function = object->GetProperty(*exec); 1795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // This can lose an exception, but the alternative is to put a failure 1805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // object in a handle, which is not GC safe. 1815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (!maybe_exec_function->ToObject(&exec_function)) { 1825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return Factory::undefined_value(); 1835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 1845913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 1855913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck return Handle<Object>(exec_function); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Objects created through the API can have an instance-call handler 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that should be used when calling the object as a function. 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsHeapObject() && 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject::cast(*object)->map()->has_instance_call_handler()) { 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>( 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::global_context()->call_as_function_delegate()); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!object->IsJSFunction()); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If you return a function from here, it will be called when an 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // attempt is made to call the given object as a constructor. 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Objects created through the API can have an instance-call handler 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that should be used when calling the object as a function. 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsHeapObject() && 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject::cast(*object)->map()->has_instance_call_handler()) { 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>( 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::global_context()->call_as_constructor_delegate()); 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static state for stack guards. 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackGuard::ThreadLocal StackGuard::thread_local_; 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsStackOverflow() { 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (thread_local_.jslimit_ != kInterruptLimit && 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.climit_ != kInterruptLimit); 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::EnableInterrupts() { 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 2316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (has_pending_interrupts(access)) { 2326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::SetStackLimit(uintptr_t limit) { 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the current limits are special (eg due to a pending interrupt) then 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // leave them alone. 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(limit); 242d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (thread_local_.jslimit_ == thread_local_.real_jslimit_) { 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.jslimit_ = jslimit; 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 245d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (thread_local_.climit_ == thread_local_.real_climit_) { 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.climit_ = limit; 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 248d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block thread_local_.real_climit_ = limit; 249d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block thread_local_.real_jslimit_ = jslimit; 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DisableInterrupts() { 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reset_limits(access); 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsInterrupted() { 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & INTERRUPT; 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Interrupt() { 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= INTERRUPT; 2686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsPreempted() { 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & PREEMPT; 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Preempt() { 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= PREEMPT; 2816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsTerminateExecution() { 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & TERMINATE; 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::TerminateExecution() { 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= TERMINATE; 2946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugBreak() { 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & DEBUGBREAK; 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugBreak() { 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= DEBUGBREAK; 3086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugCommand() { 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & DEBUGCOMMAND; 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugCommand() { 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_debugger_auto_break) { 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= DEBUGCOMMAND; 3226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block set_interrupt_limits(access); 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Continue(InterruptFlag after_what) { 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); 3306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!should_postpone_interrupts(access) && !has_pending_interrupts(access)) { 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reset_limits(access); 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint StackGuard::ArchiveSpacePerThread() { 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return sizeof(ThreadLocal); 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::ArchiveStackGuard(char* to) { 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocal blank; 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_ = blank; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return to + sizeof(ThreadLocal); 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::RestoreStackGuard(char* from) { 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 353d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Heap::SetStackLimits(); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return from + sizeof(ThreadLocal); 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic internal::Thread::LocalStorageKey stack_limit_key = 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block internal::Thread::CreateThreadLocalKey(); 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::FreeThreadResources() { 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Thread::SetThreadLocal( 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack_limit_key, 365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block reinterpret_cast<void*>(thread_local_.real_climit_)); 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ThreadLocal::Clear() { 370d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block real_jslimit_ = kIllegalLimit; 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jslimit_ = kIllegalLimit; 372d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block real_climit_ = kIllegalLimit; 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block climit_ = kIllegalLimit; 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nesting_ = 0; 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block postpone_interrupts_nesting_ = 0; 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block interrupt_flags_ = 0; 377d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Heap::SetStackLimits(); 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ThreadLocal::Initialize() { 382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block if (real_climit_ == kIllegalLimit) { 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Takes the address of the limit variable in order to find out where 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top of stack is right now. 3853ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block uintptr_t limit = reinterpret_cast<uintptr_t>(&limit) - kLimitSize; 3863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block ASSERT(reinterpret_cast<uintptr_t>(&limit) > kLimitSize); 387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block real_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block real_climit_ = limit; 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block climit_ = limit; 391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block Heap::SetStackLimits(); 392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nesting_ = 0; 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block postpone_interrupts_nesting_ = 0; 395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block interrupt_flags_ = 0; 396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ClearThread(const ExecutionAccess& lock) { 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.Clear(); 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::InitThread(const ExecutionAccess& lock) { 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.Initialize(); 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void* stored_limit = Thread::GetThreadLocal(stack_limit_key); 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // You should hold the ExecutionAccess lock when you call this. 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (stored_limit != NULL) { 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::SetStackLimit(reinterpret_cast<intptr_t>(stored_limit)); 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- C a l l s t o n a t i v e s --- 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define RETURN_NATIVE_CALL(name, argc, argv, has_pending_exception) \ 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block do { \ 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[argc] = argv; \ 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(has_pending_exception != NULL); \ 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Call(Top::name##_fun(), Top::builtins(), argc, args, \ 421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block has_pending_exception); \ 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } while (false) 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToBoolean(Handle<Object> obj) { 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // See the similar code in runtime.js:ToBoolean. 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsBoolean()) return obj; 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool result = true; 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsString()) { 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Handle<String>::cast(obj)->length() != 0; 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (obj->IsNull() || obj->IsUndefined()) { 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = false; 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else if (obj->IsNumber()) { 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block double value = obj->Number(); 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = !((value == 0) || isnan(value)); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Object>(Heap::ToBoolean(result)); 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToNumber(Handle<Object> obj, bool* exc) { 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_number, 1, { obj.location() }, exc); 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToString(Handle<Object> obj, bool* exc) { 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_string, 1, { obj.location() }, exc); 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) { 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_detail_string, 1, { obj.location() }, exc); 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (obj->IsJSObject()) return obj; 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc); 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToInteger(Handle<Object> obj, bool* exc) { 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_integer, 1, { obj.location() }, exc); 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToUint32(Handle<Object> obj, bool* exc) { 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_uint32, 1, { obj.location() }, exc); 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::ToInt32(Handle<Object> obj, bool* exc) { 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(to_int32, 1, { obj.location() }, exc); 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::NewDate(double time, bool* exc) { 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> time_obj = Factory::NewNumber(time); 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RETURN_NATIVE_CALL(create_date, 1, { time_obj.location() }, exc); 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef RETURN_NATIVE_CALL 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 486f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochHandle<JSRegExp> Execution::NewJSRegExp(Handle<String> pattern, 487f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<String> flags, 488f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch bool* exc) { 489f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<Object> re_obj = RegExpImpl::CreateRegExpLiteral( 490f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch Handle<JSFunction>(Top::global_context()->regexp_function()), 491f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch pattern, 492f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch flags, 493f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch exc); 494f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch if (*exc) return Handle<JSRegExp>(); 495f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch return Handle<JSRegExp>::cast(re_obj); 496f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch} 497f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 498f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int int_index = static_cast<int>(index); 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (int_index < 0 || int_index >= string->length()) { 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> char_at = 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GetProperty(Top::builtins(), Factory::char_at_symbol()); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!char_at->IsJSFunction()) { 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception; 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> index_object = Factory::NewNumberFromInt(int_index); 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** index_arg[] = { index_object.location() }; 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block string, 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ARRAY_SIZE(index_arg), 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index_arg, 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSFunction> Execution::InstantiateFunction( 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo> data, bool* exc) { 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fast case: see if the function has already been instantiated 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int serial_number = Smi::cast(data->serial_number())->value(); 5305913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck Object* elm = Top::global_context()->function_cache()-> 5315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck GetElementNoExceptionThrown(serial_number); 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm)); 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The function has not yet been instantiated in this context; do it. 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[1] = { Handle<Object>::cast(data).location() }; 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Call(Top::instantiate_fun(), Top::builtins(), 1, args, exc); 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSFunction>::null(); 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>::cast(result); 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data, 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc) { 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (data->property_list()->IsUndefined() && 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !data->constructor()->IsUndefined()) { 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialization to make gcc happy. 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo> cons_template = 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo>( 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplateInfo::cast(data->constructor())); 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> cons = InstantiateFunction(cons_template, exc); 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value = New(cons, 0, NULL, exc); 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = *value; 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!*exc); 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSObject>(JSObject::cast(result)); 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[1] = { Handle<Object>::cast(data).location() }; 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Call(Top::instantiate_fun(), Top::builtins(), 1, args, exc); 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSObject>::cast(result); 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Execution::ConfigureInstance(Handle<Object> instance, 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> instance_template, 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc) { 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[2] = { instance.location(), instance_template.location() }; 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execution::Call(Top::configure_instance_fun(), Top::builtins(), 2, args, exc); 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> Execution::GetStackTraceLine(Handle<Object> recv, 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> fun, 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> pos, 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> is_global) { 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 4; 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[argc] = { recv.location(), 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>::cast(fun).location(), 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos.location(), 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_global.location() }; 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = TryCall(Top::get_stack_trace_line_fun(), 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::builtins(), argc, args, 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception || !result->IsString()) return Factory::empty_symbol(); 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<String>::cast(result); 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Object* RuntimePreempt() { 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the preempt request flag. 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(PREEMPT); 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextSwitcher::PreemptionReceived(); 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::InDebugger()) { 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If currently in the debugger don't do any actual preemption but record 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that preemption occoured while in the debugger. 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debug::PreemptionWhileInDebugger(); 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform preemption. 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Unlocker unlocker; 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Thread::YieldCPU(); 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform preemption. 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Unlocker unlocker; 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Thread::YieldCPU(); 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* Execution::DebugBreakHelper() { 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just continue if breaks are disabled. 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::disable_break()) { 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 630e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Ignore debug break during bootstrapping. 631e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke if (Bootstrapper::IsActive()) { 632e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return Heap::undefined_value(); 633e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke } 634e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIterator it; 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!it.done()); 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* fun = it.frame()->function(); 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (fun && fun->IsJSFunction()) { 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in builtin functions. 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (JSFunction::cast(fun)->IsBuiltin()) { 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GlobalObject* global = JSFunction::cast(fun)->context()->global(); 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in debugger functions. 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::IsDebugGlobal(global)) { 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Collect the break state before clearing the flags. 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool debug_command_only = 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::IsDebugCommand() && !StackGuard::IsDebugBreak(); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 656e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Clear the debug break request flag. 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(DEBUGBREAK); 658e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 659e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke ProcessDebugMesssages(debug_command_only); 660e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 661e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Return to continue execution. 662e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return Heap::undefined_value(); 663e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke} 664e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 665e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Execution::ProcessDebugMesssages(bool debug_command_only) { 666e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke // Clear the debug command request flag. 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(DEBUGCOMMAND); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. Just continue if we fail to enter the debugger. 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) { 673e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke return; 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify the debug event listeners. Indicate auto continue if the break was 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a debug command break. 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debugger::OnDebugBreak(Factory::undefined_value(), debug_command_only); 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 680e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 681e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 6845913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckMaybeObject* Execution::HandleStackGuardInterrupt() { 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsDebugBreak() || StackGuard::IsDebugCommand()) { 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugBreakHelper(); 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsPreempted()) RuntimePreempt(); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsTerminateExecution()) { 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(TERMINATE); 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Top::TerminateExecution(); 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsInterrupted()) { 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interrupt 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(INTERRUPT); 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Top::StackOverflow(); 699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- G C E x t e n s i o n --- 704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenconst char* const GCExtension::kSource = "native function gc();"; 706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction( 709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> str) { 710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::FunctionTemplate::New(GCExtension::GC); 711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { 715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All allocation spaces other than NEW_SPACE have the same effect. 716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Heap::CollectAllGarbage(false); 717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic GCExtension gc_extension; 7229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic v8::DeclareExtension gc_extension_declaration(&gc_extension); 7239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen// --- E x t e r n a l i z e S t r i n g E x t e n s i o n --- 7269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsentemplate <typename Char, typename Base> 7299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenclass SimpleStringResource : public Base { 7309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen public: 7319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen // Takes ownership of |data|. 7329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen SimpleStringResource(Char* data, size_t length) 7339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen : data_(data), 7349dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen length_(length) {} 7359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 736791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block virtual ~SimpleStringResource() { delete[] data_; } 7379dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7389dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen virtual const Char* data() const { return data_; } 7399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen virtual size_t length() const { return length_; } 7419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7429dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen private: 7439dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen Char* const data_; 7449dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const size_t length_; 7459dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}; 7469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7479dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsentypedef SimpleStringResource<char, v8::String::ExternalAsciiStringResource> 7499dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen SimpleAsciiStringResource; 7509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsentypedef SimpleStringResource<uc16, v8::String::ExternalStringResource> 7519dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen SimpleTwoByteStringResource; 7529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7539dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenconst char* const ExternalizeStringExtension::kSource = 7559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "native function externalizeString();" 7569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "native function isAsciiString();"; 7579dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenv8::Handle<v8::FunctionTemplate> ExternalizeStringExtension::GetNativeFunction( 7609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::Handle<v8::String> str) { 7619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (strcmp(*v8::String::AsciiValue(str), "externalizeString") == 0) { 7629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::FunctionTemplate::New(ExternalizeStringExtension::Externalize); 7639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } else { 7649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen ASSERT(strcmp(*v8::String::AsciiValue(str), "isAsciiString") == 0); 7659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::FunctionTemplate::New(ExternalizeStringExtension::IsAscii); 7669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 7679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 7689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7699dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 7709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenv8::Handle<v8::Value> ExternalizeStringExtension::Externalize( 7719dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::Arguments& args) { 7729dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (args.Length() < 1 || !args[0]->IsString()) { 7739dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::ThrowException(v8::String::New( 7749dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "First parameter to externalizeString() must be a string.")); 7759dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 7769dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool force_two_byte = false; 7779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (args.Length() >= 2) { 7789dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (args[1]->IsBoolean()) { 7799dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen force_two_byte = args[1]->BooleanValue(); 7809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } else { 7819dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::ThrowException(v8::String::New( 7829dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "Second parameter to externalizeString() must be a boolean.")); 7839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 7849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 7859dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen bool result = false; 7869dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen Handle<String> string = Utils::OpenHandle(*args[0].As<v8::String>()); 7879dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (string->IsExternalString()) { 7889dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::ThrowException(v8::String::New( 7899dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "externalizeString() can't externalize twice.")); 7909dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 7919dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (string->IsAsciiRepresentation() && !force_two_byte) { 7929dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen char* data = new char[string->length()]; 7939dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen String::WriteToFlat(*string, data, 0, string->length()); 7949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen SimpleAsciiStringResource* resource = new SimpleAsciiStringResource( 7959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen data, string->length()); 7969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen result = string->MakeExternal(resource); 7979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (result && !string->IsSymbol()) { 7989dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen i::ExternalStringTable::AddString(*string); 7999dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 8009dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } else { 8019dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen uc16* data = new uc16[string->length()]; 8029dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen String::WriteToFlat(*string, data, 0, string->length()); 8039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen SimpleTwoByteStringResource* resource = new SimpleTwoByteStringResource( 8049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen data, string->length()); 8059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen result = string->MakeExternal(resource); 8069dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (result && !string->IsSymbol()) { 8079dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen i::ExternalStringTable::AddString(*string); 8089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 8099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 8109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (!result) { 8119dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::ThrowException(v8::String::New("externalizeString() failed.")); 8129dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 8139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::Undefined(); 8149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 8159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 8169dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 8179dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenv8::Handle<v8::Value> ExternalizeStringExtension::IsAscii( 8189dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen const v8::Arguments& args) { 8199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen if (args.Length() != 1 || !args[0]->IsString()) { 8209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return v8::ThrowException(v8::String::New( 8219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen "isAsciiString() requires a single string argument.")); 8229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen } 8239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen return Utils::OpenHandle(*args[0].As<v8::String>())->IsAsciiRepresentation() ? 8249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen v8::True() : v8::False(); 8259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen} 8269dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 8279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen 8289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic ExternalizeStringExtension externalize_extension; 8299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenstatic v8::DeclareExtension externalize_extension_declaration( 8309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen &externalize_extension); 831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 833