execution.cc revision a7e24c173cf37484693b9abb38e494fa7bd7baeb
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" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "codegen-inl.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#if V8_TARGET_ARCH_IA32 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "ia32/simulator-ia32.h" 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#elif V8_TARGET_ARCH_X64 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "x64/simulator-x64.h" 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#elif V8_TARGET_ARCH_ARM 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arm/simulator-arm.h" 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#error Unsupported target architecture. 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h" 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "v8threads.h" 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Handle<Object> Invoke(bool construct, 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> func, 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* has_pending_exception) { 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Make sure we have a real function, not a boilerplate function. 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!func->IsBoilerplate()); 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Entering JavaScript. 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block VMState state(JS); 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Placeholder for return value. 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* value = reinterpret_cast<Object*>(kZapValue); 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block typedef Object* (*JSEntryFunction)( 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block byte* entry, 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* function, 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* receiver, 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Code> code; 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (construct) { 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSConstructEntryStub stub; 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code = stub.GetCode(); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSEntryStub stub; 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block code = stub.GetCode(); 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Convert calls on global objects to be calls on the global 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // receiver instead to avoid having a 'this' pointer which refers 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // directly to a global object. 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (receiver->IsGlobalObject()) { 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block receiver = Handle<JSObject>(global->global_receiver()); 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Save and restore context around invocation and block the 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // allocation of handles without explicit handle scopes. 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block SaveContext save; 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NoHandleAllocation na; 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JSEntryFunction entry = FUNCTION_CAST<JSEntryFunction>(code->entry()); 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Call the function through the right JS entry stub. 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value = CALL_GENERATED_CODE(entry, func->code()->entry(), *func, 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *receiver, argc, args); 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block value->Verify(); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Update the pending exception flag and return the value. 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *has_pending_exception = value->IsException(); 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(*has_pending_exception == Top::has_pending_exception()); 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*has_pending_exception) { 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::ReportPendingMessages(); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Object>(); 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::clear_pending_message(); 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Object>(value); 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::Call(Handle<JSFunction> func, 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* pending_exception) { 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Invoke(false, func, receiver, argc, args, pending_exception); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::New(Handle<JSFunction> func, int argc, 131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, bool* pending_exception) { 132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Invoke(true, func, Top::global(), argc, args, pending_exception); 133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::TryCall(Handle<JSFunction> func, 137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> receiver, 138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int argc, 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object*** args, 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* caught_exception) { 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter a try-block while executing the JavaScript code. To avoid 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // duplicate error printing it must be non-verbose. Also, to avoid 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // creating message objects during stack overflow we shouldn't 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // capture messages. 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::TryCatch catcher; 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block catcher.SetVerbose(false); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block catcher.SetCaptureMessage(false); 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = Invoke(false, func, receiver, argc, args, 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block caught_exception); 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*caught_exception) { 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(catcher.HasCaught()); 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Top::has_pending_exception()); 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(Top::external_caught_exception()); 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Top::pending_exception() == Heap::termination_exception()) { 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = Factory::termination_exception(); 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = v8::Utils::OpenHandle(*catcher.Exception()); 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::OptionalRescheduleException(true); 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!Top::has_pending_exception()); 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!Top::external_caught_exception()); 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetFunctionDelegate(Handle<Object> object) { 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!object->IsJSFunction()); 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If you return a function from here, it will be called when an 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // attempt is made to call the given object as a function. 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Regular expressions can be called as functions in both Firefox 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // and Safari so we allow it too. 178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsJSRegExp()) { 179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<String> exec = Factory::exec_symbol(); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<Object>(object->GetProperty(*exec)); 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Objects created through the API can have an instance-call handler 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that should be used when calling the object as a function. 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsHeapObject() && 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject::cast(*object)->map()->has_instance_call_handler()) { 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>( 188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::global_context()->call_as_function_delegate()); 189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::GetConstructorDelegate(Handle<Object> object) { 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!object->IsJSFunction()); 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If you return a function from here, it will be called when an 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // attempt is made to call the given object as a constructor. 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Objects created through the API can have an instance-call handler 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that should be used when calling the object as a function. 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (object->IsHeapObject() && 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HeapObject::cast(*object)->map()->has_instance_call_handler()) { 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>( 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::global_context()->call_as_constructor_delegate()); 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static state for stack guards. 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockStackGuard::ThreadLocal StackGuard::thread_local_; 215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsStackOverflow() { 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return (thread_local_.jslimit_ != kInterruptLimit && 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.climit_ != kInterruptLimit); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::EnableInterrupts() { 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (IsSet(access)) { 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_limits(kInterruptLimit, access); 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::SetStackLimit(uintptr_t limit) { 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If the current limits are special (eg due to a pending interrupt) then 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // leave them alone. 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block uintptr_t jslimit = SimulatorStack::JsLimitFromCLimit(limit); 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (thread_local_.jslimit_ == thread_local_.initial_jslimit_) { 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.jslimit_ = jslimit; 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Heap::SetStackLimit(jslimit); 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (thread_local_.climit_ == thread_local_.initial_climit_) { 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.climit_ = limit; 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.initial_climit_ = limit; 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.initial_jslimit_ = jslimit; 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DisableInterrupts() { 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reset_limits(access); 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsSet(const ExecutionAccess& lock) { 256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ != 0; 257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsInterrupted() { 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & INTERRUPT; 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Interrupt() { 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= INTERRUPT; 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_limits(kInterruptLimit, access); 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsPreempted() { 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & PREEMPT; 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Preempt() { 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= PREEMPT; 282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_limits(kInterruptLimit, access); 283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsTerminateExecution() { 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & TERMINATE; 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::TerminateExecution() { 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= TERMINATE; 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_limits(kInterruptLimit, access); 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugBreak() { 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & DEBUGBREAK; 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugBreak() { 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= DEBUGBREAK; 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_limits(kInterruptLimit, access); 310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool StackGuard::IsDebugCommand() { 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return thread_local_.interrupt_flags_ & DEBUGCOMMAND; 316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::DebugCommand() { 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (FLAG_debugger_auto_break) { 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ |= DEBUGCOMMAND; 323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block set_limits(kInterruptLimit, access); 324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::Continue(InterruptFlag after_what) { 329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_.interrupt_flags_ &= ~static_cast<int>(after_what); 331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (thread_local_.interrupt_flags_ == 0) { 332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reset_limits(access); 333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint StackGuard::ArchiveSpacePerThread() { 338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return sizeof(ThreadLocal); 339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::ArchiveStackGuard(char* to) { 343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(to, reinterpret_cast<char*>(&thread_local_), sizeof(ThreadLocal)); 345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ThreadLocal blank; 346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block thread_local_ = blank; 347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return to + sizeof(ThreadLocal); 348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* StackGuard::RestoreStackGuard(char* from) { 352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExecutionAccess access; 353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block memcpy(reinterpret_cast<char*>(&thread_local_), from, sizeof(ThreadLocal)); 354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Heap::SetStackLimit(thread_local_.jslimit_); 355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return from + sizeof(ThreadLocal); 356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic internal::Thread::LocalStorageKey stack_limit_key = 360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block internal::Thread::CreateThreadLocalKey(); 361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::FreeThreadResources() { 364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Thread::SetThreadLocal( 365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block stack_limit_key, 366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<void*>(thread_local_.initial_climit_)); 367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ThreadLocal::Clear() { 371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block initial_jslimit_ = kIllegalLimit; 372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jslimit_ = kIllegalLimit; 373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block initial_climit_ = kIllegalLimit; 374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block climit_ = kIllegalLimit; 375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block nesting_ = 0; 376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block postpone_interrupts_nesting_ = 0; 377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block interrupt_flags_ = 0; 378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Heap::SetStackLimit(kIllegalLimit); 379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid StackGuard::ThreadLocal::Initialize() { 383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (initial_climit_ == kIllegalLimit) { 384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Takes the address of the limit variable in order to find out where 385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // the top of stack is right now. 386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block intptr_t limit = reinterpret_cast<intptr_t>(&limit) - kLimitSize; 387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block initial_jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block jslimit_ = SimulatorStack::JsLimitFromCLimit(limit); 389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block initial_climit_ = limit; 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block climit_ = limit; 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Heap::SetStackLimit(SimulatorStack::JsLimitFromCLimit(limit)); 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 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> Execution::CharAt(Handle<String> string, uint32_t index) { 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int int_index = static_cast<int>(index); 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (int_index < 0 || int_index >= string->length()) { 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> char_at = 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GetProperty(Top::builtins(), Factory::char_at_symbol()); 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (!char_at->IsJSFunction()) { 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception; 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> index_object = Factory::NewNumberFromInt(int_index); 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** index_arg[] = { index_object.location() }; 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = TryCall(Handle<JSFunction>::cast(char_at), 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block string, 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ARRAY_SIZE(index_arg), 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block index_arg, 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception) { 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Factory::undefined_value(); 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return result; 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSFunction> Execution::InstantiateFunction( 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo> data, bool* exc) { 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Fast case: see if the function has already been instantiated 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int serial_number = Smi::cast(data->serial_number())->value(); 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* elm = 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::global_context()->function_cache()->GetElement(serial_number); 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (elm->IsJSFunction()) return Handle<JSFunction>(JSFunction::cast(elm)); 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // The function has not yet been instantiated in this context; do it. 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[1] = { Handle<Object>::cast(data).location() }; 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Call(Top::instantiate_fun(), Top::builtins(), 1, args, exc); 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSFunction>::null(); 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSFunction>::cast(result); 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSObject> Execution::InstantiateObject(Handle<ObjectTemplateInfo> data, 530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc) { 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (data->property_list()->IsUndefined() && 532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block !data->constructor()->IsUndefined()) { 533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Initialization to make gcc happy. 534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* result = NULL; 535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo> cons_template = 538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<FunctionTemplateInfo>( 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FunctionTemplateInfo::cast(data->constructor())); 540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> cons = InstantiateFunction(cons_template, exc); 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> value = New(cons, 0, NULL, exc); 543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block result = *value; 545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!*exc); 547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSObject>(JSObject::cast(result)); 548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[1] = { Handle<Object>::cast(data).location() }; 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = 551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Call(Top::instantiate_fun(), Top::builtins(), 1, args, exc); 552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (*exc) return Handle<JSObject>::null(); 553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<JSObject>::cast(result); 554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Execution::ConfigureInstance(Handle<Object> instance, 559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> instance_template, 560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool* exc) { 561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[2] = { instance.location(), instance_template.location() }; 562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Execution::Call(Top::configure_instance_fun(), Top::builtins(), 2, args, exc); 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> Execution::GetStackTraceLine(Handle<Object> recv, 567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<JSFunction> fun, 568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> pos, 569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> is_global) { 570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const int argc = 4; 571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** args[argc] = { recv.location(), 572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object>::cast(fun).location(), 573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block pos.location(), 574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block is_global.location() }; 575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool caught_exception = false; 576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Handle<Object> result = TryCall(Top::get_stack_trace_line_fun(), 577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Top::builtins(), argc, args, 578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block &caught_exception); 579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (caught_exception || !result->IsString()) return Factory::empty_symbol(); 580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Handle<String>::cast(result); 581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic Object* RuntimePreempt() { 585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the preempt request flag. 586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(PREEMPT); 587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ContextSwitcher::PreemptionReceived(); 589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::InDebugger()) { 592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // If currently in the debugger don't do any actual preemption but record 593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // that preemption occoured while in the debugger. 594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debug::PreemptionWhileInDebugger(); 595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } else { 596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform preemption. 597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Unlocker unlocker; 598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Thread::YieldCPU(); 599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else 601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Perform preemption. 602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Unlocker unlocker; 603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Thread::YieldCPU(); 604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* Execution::DebugBreakHelper() { 612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Just continue if breaks are disabled. 613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::disable_break()) { 614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block { 618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block JavaScriptFrameIterator it; 619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!it.done()); 620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object* fun = it.frame()->function(); 621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (fun && fun->IsJSFunction()) { 622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in builtin functions. 623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (JSFunction::cast(fun)->IsBuiltin()) { 624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block GlobalObject* global = JSFunction::cast(fun)->context()->global(); 627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Don't stop in debugger functions. 628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (Debug::IsDebugGlobal(global)) { 629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Collect the break state before clearing the flags. 635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block bool debug_command_only = 636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::IsDebugCommand() && !StackGuard::IsDebugBreak(); 637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Clear the debug request flags. 639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(DEBUGBREAK); 640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(DEBUGCOMMAND); 641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScope scope; 643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Enter the debugger. Just continue if we fail to enter the debugger. 644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block EnterDebugger debugger; 645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (debugger.FailedToEnter()) { 646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Notify the debug event listeners. Indicate auto continue if the break was 650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // a debug command break. 651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Debugger::OnDebugBreak(Factory::undefined_value(), debug_command_only); 652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Return to continue execution. 654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject* Execution::HandleStackGuardInterrupt() { 659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT 660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsDebugBreak() || StackGuard::IsDebugCommand()) { 661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DebugBreakHelper(); 662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsPreempted()) RuntimePreempt(); 665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsTerminateExecution()) { 666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(TERMINATE); 667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Top::TerminateExecution(); 668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (StackGuard::IsInterrupted()) { 670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // interrupt 671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block StackGuard::Continue(INTERRUPT); 672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Top::StackOverflow(); 673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Heap::undefined_value(); 675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- G C E x t e n s i o n --- 678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockconst char* GCExtension::kSource = "native function gc();"; 680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::FunctionTemplate> GCExtension::GetNativeFunction( 683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::Handle<v8::String> str) { 684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::FunctionTemplate::New(GCExtension::GC); 685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Value> GCExtension::GC(const v8::Arguments& args) { 689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // All allocation spaces other than NEW_SPACE have the same effect. 690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Heap::CollectAllGarbage(false); 691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::Undefined(); 692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic GCExtension kGCExtension; 696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::DeclareExtension kGCExtensionDeclaration(&kGCExtension); 697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 699