1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 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#ifndef V8_API_H_ 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_API_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "apiutils.h" 32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "factory.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 34b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "../include/v8-testing.h" 35b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Constants used in the implementation of the API. The most natural thing 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// would usually be to place these with the classes that use them, but 40a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// we want to keep them out of v8.h because it is an externally 41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// visible file. 42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Consts { 43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block enum TemplateType { 45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block FUNCTION_TEMPLATE = 0, 46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OBJECT_TEMPLATE = 1 47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block }; 48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utilities for working with neander-objects, primitive 52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// env-independent JSObjects used by the api. 53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass NeanderObject { 54a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit NeanderObject(int size); 568b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit inline NeanderObject(v8::internal::Handle<v8::internal::Object> obj); 578b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit inline NeanderObject(v8::internal::Object* obj); 58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline v8::internal::Object* get(int index); 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void set(int index, v8::internal::Object* value); 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline v8::internal::Handle<v8::internal::JSObject> value() { return value_; } 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int size(); 62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::JSObject> value_; 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Utilities for working with neander-arrays, a simple extensible 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// array abstraction built on neander-objects. 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass NeanderArray { 70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NeanderArray(); 728b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch explicit inline NeanderArray(v8::internal::Handle<v8::internal::Object> obj); 73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline v8::internal::Handle<v8::internal::JSObject> value() { 74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return obj_.value(); 75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void add(v8::internal::Handle<v8::internal::Object> value); 78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int length(); 80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Object* get(int index); 82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Change the value at an index to undefined value. If the index is 83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // out of bounds, the request is ignored. Returns the old value. 84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set(int index, v8::internal::Object* value); 85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NeanderObject obj_; 87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockNeanderObject::NeanderObject(v8::internal::Handle<v8::internal::Object> obj) 91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : value_(v8::internal::Handle<v8::internal::JSObject>::cast(obj)) { } 92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockNeanderObject::NeanderObject(v8::internal::Object* obj) 95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : value_(v8::internal::Handle<v8::internal::JSObject>( 96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::JSObject::cast(obj))) { } 97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockNeanderArray::NeanderArray(v8::internal::Handle<v8::internal::Object> obj) 100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : obj_(obj) { } 101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::internal::Object* NeanderObject::get(int offset) { 104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(value()->HasFastElements()); 105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::internal::FixedArray::cast(value()->elements())->get(offset); 106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NeanderObject::set(int offset, v8::internal::Object* value) { 110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(value_->HasFastElements()); 111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::FixedArray::cast(value_->elements())->set(offset, value); 112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <typename T> static inline T ToCData(v8::internal::Object* obj) { 116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); 117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<T>( 118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<intptr_t>(v8::internal::Proxy::cast(obj)->proxy())); 119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <typename T> 123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) { 124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); 12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return FACTORY->NewProxy( 126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj))); 127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockclass ApiFunction { 131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block public: 132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { } 133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::internal::Address address() { return addr_; } 134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block private: 135d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block v8::internal::Address addr_; 136d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}; 137d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 138d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block 139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockenum ExtensionTraversalState { 140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block UNVISITED, VISITED, INSTALLED 141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass RegisteredExtension { 145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block explicit RegisteredExtension(Extension* extension); 147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static void Register(RegisteredExtension* that); 148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Extension* extension() { return extension_; } 149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegisteredExtension* next() { return next_; } 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegisteredExtension* next_auto() { return next_auto_; } 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExtensionTraversalState state() { return state_; } 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void set_state(ExtensionTraversalState value) { state_ = value; } 153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static RegisteredExtension* first_extension() { return first_extension_; } 154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Extension* extension_; 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegisteredExtension* next_; 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block RegisteredExtension* next_auto_; 158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ExtensionTraversalState state_; 159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static RegisteredExtension* first_extension_; 160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass Utils { 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static bool ReportApiFailure(const char* location, const char* message); 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj); 168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj); 169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Context> ToLocal( 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::Context> obj); 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Value> ToLocal( 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::Object> obj); 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Function> ToLocal( 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::JSFunction> obj); 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<String> ToLocal( 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::String> obj); 178f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static inline Local<RegExp> ToLocal( 179f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch v8::internal::Handle<v8::internal::JSRegExp> obj); 180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Object> ToLocal( 181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::JSObject> obj); 182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Array> ToLocal( 183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::JSArray> obj); 184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<External> ToLocal( 185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::Proxy> obj); 186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Message> MessageToLocal( 187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::Object> obj); 18825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen static inline Local<StackTrace> StackTraceToLocal( 18925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen v8::internal::Handle<v8::internal::JSArray> obj); 19025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen static inline Local<StackFrame> StackFrameToLocal( 19125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen v8::internal::Handle<v8::internal::JSObject> obj); 192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Number> NumberToLocal( 193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::Object> obj); 194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Integer> IntegerToLocal( 195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::Object> obj); 196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Uint32> Uint32ToLocal( 197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::Object> obj); 198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<FunctionTemplate> ToLocal( 199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj); 200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<ObjectTemplate> ToLocal( 201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj); 202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<Signature> ToLocal( 203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::SignatureInfo> obj); 204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline Local<TypeSwitch> ToLocal( 205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::TypeSwitchInfo> obj); 206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::TemplateInfo> 208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const Template* that); 209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::FunctionTemplateInfo> 210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const FunctionTemplate* that); 211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::ObjectTemplateInfo> 212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const ObjectTemplate* that); 213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::Object> 214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const Data* data); 215f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch static inline v8::internal::Handle<v8::internal::JSRegExp> 216f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch OpenHandle(const RegExp* data); 217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::JSObject> 218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const v8::Object* data); 219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::JSArray> 220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const v8::Array* data); 221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::String> 222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const String* data); 2236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block static inline v8::internal::Handle<v8::internal::Object> 224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const Script* data); 225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::JSFunction> 226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const Function* data); 227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::JSObject> 228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const Message* message); 22925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen static inline v8::internal::Handle<v8::internal::JSArray> 23025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen OpenHandle(const StackTrace* stack_trace); 23125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen static inline v8::internal::Handle<v8::internal::JSObject> 23225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen OpenHandle(const StackFrame* stack_frame); 233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::Context> 234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const v8::Context* context); 235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::SignatureInfo> 236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const v8::Signature* sig); 237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::TypeSwitchInfo> 238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const v8::TypeSwitch* that); 239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static inline v8::internal::Handle<v8::internal::Proxy> 240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block OpenHandle(const v8::External* that); 241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class T> 245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) { 246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return reinterpret_cast<T*>(obj.location()); 247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocktemplate <class T> 251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom( 252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::HandleScope* scope) { 2536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block v8::internal::Handle<T> handle; 2546ded16be15dd865a9b21ea304d5273c8be299c87Steve Block if (!is_null()) { 2556ded16be15dd865a9b21ea304d5273c8be299c87Steve Block handle = *this; 2566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block } 2576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block return Utils::OpenHandle(*scope->Close(Utils::ToLocal(handle))); 258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementations of ToLocal 262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_TO_LOCAL(Name, From, To) \ 264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \ 2656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block ASSERT(obj.is_null() || !obj->IsTheHole()); \ 266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return Local<To>(reinterpret_cast<To*>(obj.location())); \ 267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, Context, Context) 270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, Object, Value) 271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, JSFunction, Function) 272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, String, String) 273f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochMAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp) 274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, JSObject, Object) 275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, JSArray, Array) 276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, Proxy, External) 277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate) 278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate) 279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature) 280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(ToLocal, TypeSwitchInfo, TypeSwitch) 281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(MessageToLocal, Object, Message) 28225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenMAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace) 28325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenMAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame) 284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(NumberToLocal, Object, Number) 285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(IntegerToLocal, Object, Integer) 286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32) 287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_TO_LOCAL 289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Implementations of OpenHandle 292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define MAKE_OPEN_HANDLE(From, To) \ 294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::internal::Handle<v8::internal::To> Utils::OpenHandle(\ 295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block const v8::From* that) { \ 296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return v8::internal::Handle<v8::internal::To>( \ 297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \ 298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Template, TemplateInfo) 301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(FunctionTemplate, FunctionTemplateInfo) 302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(ObjectTemplate, ObjectTemplateInfo) 303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Signature, SignatureInfo) 304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(TypeSwitch, TypeSwitchInfo) 305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Data, Object) 306f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochMAKE_OPEN_HANDLE(RegExp, JSRegExp) 307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Object, JSObject) 308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Array, JSArray) 309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(String, String) 3106ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockMAKE_OPEN_HANDLE(Script, Object) 311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Function, JSFunction) 312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Message, JSObject) 313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(Context, Context) 314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockMAKE_OPEN_HANDLE(External, Proxy) 31525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenMAKE_OPEN_HANDLE(StackTrace, JSArray) 31625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenMAKE_OPEN_HANDLE(StackFrame, JSObject) 317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef MAKE_OPEN_HANDLE 319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Tracks string usage to help make better decisions when 32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// externalizing strings. 32544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// 32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Implementation note: internally this class only tracks fresh 32744f0eee88ff00398ff7f715fab053374d808c90dSteve Block// strings and keeps a single use counter for them. 32844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockclass StringTracker { 32944f0eee88ff00398ff7f715fab053374d808c90dSteve Block public: 33044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Records that the given string's characters were copied to some 33144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // external buffer. If this happens often we should honor 33244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // externalization requests for the string. 33344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void RecordWrite(Handle<String> string) { 33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address = reinterpret_cast<Address>(*string); 33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address top = isolate_->heap()->NewSpaceTop(); 33644f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (IsFreshString(address, top)) { 33744f0eee88ff00398ff7f715fab053374d808c90dSteve Block IncrementUseCount(top); 33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 33944f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 34044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 34144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Estimates freshness and use frequency of the given string based 34244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // on how close it is to the new space top and the recorded usage 34344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // history. 34444f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline bool IsFreshUnusedString(Handle<String> string) { 34544f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address address = reinterpret_cast<Address>(*string); 34644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address top = isolate_->heap()->NewSpaceTop(); 34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return IsFreshString(address, top) && IsUseCountLow(top); 34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 34944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35044f0eee88ff00398ff7f715fab053374d808c90dSteve Block private: 35144f0eee88ff00398ff7f715fab053374d808c90dSteve Block StringTracker() : use_count_(0), last_top_(NULL), isolate_(NULL) { } 35244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block static inline bool IsFreshString(Address string, Address top) { 35444f0eee88ff00398ff7f715fab053374d808c90dSteve Block return top - kFreshnessLimit <= string && string <= top; 35544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 35644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 35744f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline bool IsUseCountLow(Address top) { 35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (last_top_ != top) return true; 35944f0eee88ff00398ff7f715fab053374d808c90dSteve Block return use_count_ < kUseLimit; 36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 36144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 36244f0eee88ff00398ff7f715fab053374d808c90dSteve Block inline void IncrementUseCount(Address top) { 36344f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (last_top_ != top) { 36444f0eee88ff00398ff7f715fab053374d808c90dSteve Block use_count_ = 0; 36544f0eee88ff00398ff7f715fab053374d808c90dSteve Block last_top_ = top; 36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ++use_count_; 36844f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 36944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 37044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Single use counter shared by all fresh strings. 37144f0eee88ff00398ff7f715fab053374d808c90dSteve Block int use_count_; 37244f0eee88ff00398ff7f715fab053374d808c90dSteve Block 37344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Last new space top when the use count above was valid. 37444f0eee88ff00398ff7f715fab053374d808c90dSteve Block Address last_top_; 37544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 37644f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate_; 37744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 37844f0eee88ff00398ff7f715fab053374d808c90dSteve Block // How close to the new space top a fresh string has to be. 37944f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const int kFreshnessLimit = 1024; 38044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 38144f0eee88ff00398ff7f715fab053374d808c90dSteve Block // The number of uses required to consider a string useful. 38244f0eee88ff00398ff7f715fab053374d808c90dSteve Block static const int kUseLimit = 32; 38344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 38444f0eee88ff00398ff7f715fab053374d808c90dSteve Block friend class Isolate; 38544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block DISALLOW_COPY_AND_ASSIGN(StringTracker); 38744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}; 38844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 38944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This class is here in order to be able to declare it a friend of 391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HandleScope. Moving these methods to be members of HandleScope would be 39244f0eee88ff00398ff7f715fab053374d808c90dSteve Block// neat in some ways, but it would expose internal implementation details in 393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// our public header file, which is undesirable. 394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// 39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block// An isolate has a single instance of this class to hold the current thread's 39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block// data. In multithreaded V8 programs this data is copied in and out of storage 397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// so that the currently executing thread always has its own copy of this 398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// data. 39944f0eee88ff00398ff7f715fab053374d808c90dSteve BlockISOLATED_CLASS HandleScopeImplementer { 400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public: 401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block HandleScopeImplementer() 403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block : blocks_(0), 404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block entered_contexts_(0), 405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block saved_contexts_(0), 406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_(NULL), 407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call_depth_(0) { } 408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Threading support for handle data. 410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static int ArchiveSpacePerThread(); 41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block char* RestoreThread(char* from); 41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block char* ArchiveThread(char* to); 41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block void FreeThreadResources(); 414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Garbage collection support. 41644f0eee88ff00398ff7f715fab053374d808c90dSteve Block void Iterate(v8::internal::ObjectVisitor* v); 417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block static char* Iterate(v8::internal::ObjectVisitor* v, char* data); 418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline internal::Object** GetSpareOrNewBlock(); 4215913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck inline void DeleteExtensions(internal::Object** prev_limit); 422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void IncrementCallDepth() {call_depth_++;} 424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void DecrementCallDepth() {call_depth_--;} 425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool CallDepthIsZero() { return call_depth_ == 0; } 426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void EnterContext(Handle<Object> context); 428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool LeaveLastContext(); 429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Returns the last entered context or an empty handle if no 431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // contexts have been entered. 432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Handle<Object> LastEnteredContext(); 433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline void SaveContext(Context* context); 435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline Context* RestoreContext(); 436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline bool HasSavedContexts(); 437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block inline List<internal::Object**>* blocks() { return &blocks_; } 439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private: 441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void ResetAfterArchive() { 442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block blocks_.Initialize(0); 443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block entered_contexts_.Initialize(0); 444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block saved_contexts_.Initialize(0); 445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_ = NULL; 446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block call_depth_ = 0; 447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void Free() { 450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(blocks_.length() == 0); 451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(entered_contexts_.length() == 0); 452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(saved_contexts_.length() == 0); 453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block blocks_.Free(); 454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block entered_contexts_.Free(); 455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block saved_contexts_.Free(); 456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (spare_ != NULL) { 457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DeleteArray(spare_); 458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_ = NULL; 459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(call_depth_ == 0); 461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block } 462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block List<internal::Object**> blocks_; 464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used as a stack to keep track of entered contexts. 465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block List<Handle<Object> > entered_contexts_; 466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Used as a stack to keep track of saved contexts. 467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block List<Context*> saved_contexts_; 468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block Object** spare_; 469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block int call_depth_; 470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // This is only used for threading support. 471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ImplementationUtilities::HandleScopeData handle_scope_data_; 472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block void IterateThis(ObjectVisitor* v); 474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* RestoreThreadHelper(char* from); 475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block char* ArchiveThreadHelper(char* to); 476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer); 478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}; 479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 480a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 481a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic const int kHandleBlockSize = v8::internal::KB - 2; // fit in one page 482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScopeImplementer::SaveContext(Context* context) { 485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block saved_contexts_.Add(context); 486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockContext* HandleScopeImplementer::RestoreContext() { 490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return saved_contexts_.RemoveLast(); 491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool HandleScopeImplementer::HasSavedContexts() { 495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return !saved_contexts_.is_empty(); 496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScopeImplementer::EnterContext(Handle<Object> context) { 500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block entered_contexts_.Add(context); 501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool HandleScopeImplementer::LeaveLastContext() { 505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (entered_contexts_.is_empty()) return false; 506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block entered_contexts_.RemoveLast(); 507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return true; 508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> HandleScopeImplementer::LastEnteredContext() { 512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block if (entered_contexts_.is_empty()) return Handle<Object>::null(); 513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return entered_contexts_.last(); 514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If there's a spare block, use it for growing the current scope. 518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinternal::Object** HandleScopeImplementer::GetSpareOrNewBlock() { 519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block internal::Object** block = (spare_ != NULL) ? 520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_ : 521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block NewArray<internal::Object*>(kHandleBlockSize); 522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block spare_ = NULL; 523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block return block; 524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 5275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckvoid HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) { 5285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck while (!blocks_.is_empty()) { 5295913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck internal::Object** block_start = blocks_.last(); 5305913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck internal::Object** block_limit = block_start + kHandleBlockSize; 531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 5325913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck // NoHandleAllocation may make the prev_limit to point inside the block. 5335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (block_start <= prev_limit && prev_limit <= block_limit) break; 5345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck#else 5355913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (prev_limit == block_limit) break; 536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 5375913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 5385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck blocks_.RemoveLast(); 539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 5405913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck v8::ImplementationUtilities::ZapHandleRange(block_start, block_limit); 541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 5425913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck if (spare_ != NULL) { 5435913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck DeleteArray(spare_); 5445913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 5455913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck spare_ = block_start; 5465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck } 5475913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck ASSERT((blocks_.is_empty() && prev_limit == NULL) || 5485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck (!blocks_.is_empty() && prev_limit != NULL)); 549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 551b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 552b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass Testing { 553b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public: 554b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static v8::Testing::StressType stress_type() { return stress_type_; } 555b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static void set_stress_type(v8::Testing::StressType stress_type) { 556b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch stress_type_ = stress_type; 557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch } 558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private: 560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch static v8::Testing::StressType stress_type_; 561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}; 562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch 563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_API_H_ 566