api.h revision 69a99ed0b2b2ef69d393c371b03db3a98aaf880e
130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Copyright 2011 the V8 project authors. All rights reserved. 230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Redistribution and use in source and binary forms, with or without 330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// modification, are permitted provided that the following conditions are 430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// met: 530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// 630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// * Redistributions of source code must retain the above copyright 730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// notice, this list of conditions and the following disclaimer. 830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// * Redistributions in binary form must reproduce the above 930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// copyright notice, this list of conditions and the following 1030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// disclaimer in the documentation and/or other materials provided 1130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// with the distribution. 1230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// * Neither the name of Google Inc. nor the names of its 1330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// contributors may be used to endorse or promote products derived 1430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// from this software without specific prior written permission. 1530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// 1630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 2830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#ifndef V8_API_H_ 2930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#define V8_API_H_ 3030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "apiutils.h" 3230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "factory.h" 3330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun#include "../include/v8-testing.h" 3530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunnamespace v8 { 3730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 3830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Constants used in the implementation of the API. The most natural thing 3930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// would usually be to place these with the classes that use them, but 4030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// we want to keep them out of v8.h because it is an externally 4130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// visible file. 4230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass Consts { 4330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public: 4430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun enum TemplateType { 4530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun FUNCTION_TEMPLATE = 0, 4630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OBJECT_TEMPLATE = 1 4730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun }; 4830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 4930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 5130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Utilities for working with neander-objects, primitive 5230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// env-independent JSObjects used by the api. 5330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass NeanderObject { 5430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public: 5530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun explicit NeanderObject(int size); 5630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun explicit inline NeanderObject(v8::internal::Handle<v8::internal::Object> obj); 5730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun explicit inline NeanderObject(v8::internal::Object* obj); 5830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun inline v8::internal::Object* get(int index); 5930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun inline void set(int index, v8::internal::Object* value); 6030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun inline v8::internal::Handle<v8::internal::JSObject> value() { return value_; } 6130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int size(); 6230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private: 6330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::JSObject> value_; 6430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 6530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 6730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// Utilities for working with neander-arrays, a simple extensible 6830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun// array abstraction built on neander-objects. 6930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass NeanderArray { 7030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public: 7130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun NeanderArray(); 7230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun explicit inline NeanderArray(v8::internal::Handle<v8::internal::Object> obj); 7330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun inline v8::internal::Handle<v8::internal::JSObject> value() { 7430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return obj_.value(); 7530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun } 7630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun void add(v8::internal::Handle<v8::internal::Object> value); 7830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 7930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun int length(); 8030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Object* get(int index); 8230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // Change the value at an index to undefined value. If the index is 8330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun // out of bounds, the request is ignored. Returns the old value. 8430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun void set(int index, v8::internal::Object* value); 8530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private: 8630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun NeanderObject obj_; 8730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 8830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 8930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunNeanderObject::NeanderObject(v8::internal::Handle<v8::internal::Object> obj) 9130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : value_(v8::internal::Handle<v8::internal::JSObject>::cast(obj)) { } 9230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunNeanderObject::NeanderObject(v8::internal::Object* obj) 9530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : value_(v8::internal::Handle<v8::internal::JSObject>( 9630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::JSObject::cast(obj))) { } 9730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 9930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim GurunNeanderArray::NeanderArray(v8::internal::Handle<v8::internal::Object> obj) 10030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun : obj_(obj) { } 10130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunv8::internal::Object* NeanderObject::get(int offset) { 10430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ASSERT(value()->HasFastElements()); 10530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return v8::internal::FixedArray::cast(value()->elements())->get(offset); 10630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 10730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 10930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunvoid NeanderObject::set(int offset, v8::internal::Object* value) { 11030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ASSERT(value_->HasFastElements()); 11130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::FixedArray::cast(value_->elements())->set(offset, value); 11230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 11330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 11530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntemplate <typename T> static inline T ToCData(v8::internal::Object* obj) { 11630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); 11730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return reinterpret_cast<T>( 11830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun reinterpret_cast<intptr_t>(v8::internal::Foreign::cast(obj)->address())); 11930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntemplate <typename T> 12330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunstatic inline v8::internal::Handle<v8::internal::Object> FromCData(T obj) { 12430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun STATIC_ASSERT(sizeof(T) == sizeof(v8::internal::Address)); 12530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun return FACTORY->NewForeign( 12630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(obj))); 12730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun} 12830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 12930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass ApiFunction { 13130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public: 13230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun explicit ApiFunction(v8::internal::Address addr) : addr_(addr) { } 13330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Address address() { return addr_; } 13430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private: 13530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Address addr_; 13630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 13730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 13930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunenum ExtensionTraversalState { 14030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun UNVISITED, VISITED, INSTALLED 14130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 14230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 14430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass RegisteredExtension { 14530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public: 14630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun explicit RegisteredExtension(Extension* extension); 14730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static void Register(RegisteredExtension* that); 14830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Extension* extension() { return extension_; } 14930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun RegisteredExtension* next() { return next_; } 15030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun RegisteredExtension* next_auto() { return next_auto_; } 15130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ExtensionTraversalState state() { return state_; } 15230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun void set_state(ExtensionTraversalState value) { state_ = value; } 15330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static RegisteredExtension* first_extension() { return first_extension_; } 15430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun private: 15530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun Extension* extension_; 15630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun RegisteredExtension* next_; 15730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun RegisteredExtension* next_auto_; 15830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun ExtensionTraversalState state_; 15930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static RegisteredExtension* first_extension_; 16030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 16130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurunclass Utils { 16430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun public: 16530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static bool ReportApiFailure(const char* location, const char* message); 16630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 16730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static Local<FunctionTemplate> ToFunctionTemplate(NeanderObject obj); 16830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static Local<ObjectTemplate> ToObjectTemplate(NeanderObject obj); 16930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 17030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Context> ToLocal( 17130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::Context> obj); 17230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Value> ToLocal( 17330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::Object> obj); 17430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Function> ToLocal( 17530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::JSFunction> obj); 17630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<String> ToLocal( 17730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::String> obj); 17830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<RegExp> ToLocal( 17930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::JSRegExp> obj); 18030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Object> ToLocal( 18130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::JSObject> obj); 18230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Array> ToLocal( 18330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::JSArray> obj); 18430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<External> ToLocal( 18530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::Foreign> obj); 18630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Message> MessageToLocal( 18730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::Object> obj); 18830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<StackTrace> StackTraceToLocal( 18930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::JSArray> obj); 19030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<StackFrame> StackFrameToLocal( 19130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::JSObject> obj); 19230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Number> NumberToLocal( 19330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::Object> obj); 19430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Integer> IntegerToLocal( 19530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::Object> obj); 19630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Uint32> Uint32ToLocal( 19730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::Object> obj); 19830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<FunctionTemplate> ToLocal( 19930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::FunctionTemplateInfo> obj); 20030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<ObjectTemplate> ToLocal( 20130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::ObjectTemplateInfo> obj); 20230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<Signature> ToLocal( 20330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::SignatureInfo> obj); 20430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline Local<TypeSwitch> ToLocal( 20530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun v8::internal::Handle<v8::internal::TypeSwitchInfo> obj); 20630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 20730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::TemplateInfo> 20830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const Template* that); 20930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::FunctionTemplateInfo> 21030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const FunctionTemplate* that); 21130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::ObjectTemplateInfo> 21230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const ObjectTemplate* that); 21330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::Object> 21430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const Data* data); 21530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::JSRegExp> 21630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const RegExp* data); 21730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::JSObject> 21830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const v8::Object* data); 21930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::JSArray> 22030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const v8::Array* data); 22130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::String> 22230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const String* data); 22330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::Object> 22430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const Script* data); 22530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::JSFunction> 22630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const Function* data); 22730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::JSObject> 22830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const Message* message); 22930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::JSArray> 23030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const StackTrace* stack_trace); 23130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::JSObject> 23230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const StackFrame* stack_frame); 23330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::Context> 23430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const v8::Context* context); 23530d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::SignatureInfo> 23630d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const v8::Signature* sig); 23730d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::TypeSwitchInfo> 23830d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const v8::TypeSwitch* that); 23930d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun static inline v8::internal::Handle<v8::internal::Foreign> 24030d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun OpenHandle(const v8::External* that); 24130d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun}; 24230d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24330d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Gurun 24430d4e1f3d81ad9f7a1aa14ce6d2ceb5df56c15cdSelim Guruntemplate <class T> 245static inline T* ToApi(v8::internal::Handle<v8::internal::Object> obj) { 246 return reinterpret_cast<T*>(obj.location()); 247} 248 249 250template <class T> 251v8::internal::Handle<T> v8::internal::Handle<T>::EscapeFrom( 252 v8::HandleScope* scope) { 253 v8::internal::Handle<T> handle; 254 if (!is_null()) { 255 handle = *this; 256 } 257 return Utils::OpenHandle(*scope->Close(Utils::ToLocal(handle))); 258} 259 260 261// Implementations of ToLocal 262 263#define MAKE_TO_LOCAL(Name, From, To) \ 264 Local<v8::To> Utils::Name(v8::internal::Handle<v8::internal::From> obj) { \ 265 ASSERT(obj.is_null() || !obj->IsTheHole()); \ 266 return Local<To>(reinterpret_cast<To*>(obj.location())); \ 267 } 268 269MAKE_TO_LOCAL(ToLocal, Context, Context) 270MAKE_TO_LOCAL(ToLocal, Object, Value) 271MAKE_TO_LOCAL(ToLocal, JSFunction, Function) 272MAKE_TO_LOCAL(ToLocal, String, String) 273MAKE_TO_LOCAL(ToLocal, JSRegExp, RegExp) 274MAKE_TO_LOCAL(ToLocal, JSObject, Object) 275MAKE_TO_LOCAL(ToLocal, JSArray, Array) 276MAKE_TO_LOCAL(ToLocal, Foreign, External) 277MAKE_TO_LOCAL(ToLocal, FunctionTemplateInfo, FunctionTemplate) 278MAKE_TO_LOCAL(ToLocal, ObjectTemplateInfo, ObjectTemplate) 279MAKE_TO_LOCAL(ToLocal, SignatureInfo, Signature) 280MAKE_TO_LOCAL(ToLocal, TypeSwitchInfo, TypeSwitch) 281MAKE_TO_LOCAL(MessageToLocal, Object, Message) 282MAKE_TO_LOCAL(StackTraceToLocal, JSArray, StackTrace) 283MAKE_TO_LOCAL(StackFrameToLocal, JSObject, StackFrame) 284MAKE_TO_LOCAL(NumberToLocal, Object, Number) 285MAKE_TO_LOCAL(IntegerToLocal, Object, Integer) 286MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32) 287 288#undef MAKE_TO_LOCAL 289 290 291// Implementations of OpenHandle 292 293#define MAKE_OPEN_HANDLE(From, To) \ 294 v8::internal::Handle<v8::internal::To> Utils::OpenHandle(\ 295 const v8::From* that) { \ 296 return v8::internal::Handle<v8::internal::To>( \ 297 reinterpret_cast<v8::internal::To**>(const_cast<v8::From*>(that))); \ 298 } 299 300MAKE_OPEN_HANDLE(Template, TemplateInfo) 301MAKE_OPEN_HANDLE(FunctionTemplate, FunctionTemplateInfo) 302MAKE_OPEN_HANDLE(ObjectTemplate, ObjectTemplateInfo) 303MAKE_OPEN_HANDLE(Signature, SignatureInfo) 304MAKE_OPEN_HANDLE(TypeSwitch, TypeSwitchInfo) 305MAKE_OPEN_HANDLE(Data, Object) 306MAKE_OPEN_HANDLE(RegExp, JSRegExp) 307MAKE_OPEN_HANDLE(Object, JSObject) 308MAKE_OPEN_HANDLE(Array, JSArray) 309MAKE_OPEN_HANDLE(String, String) 310MAKE_OPEN_HANDLE(Script, Object) 311MAKE_OPEN_HANDLE(Function, JSFunction) 312MAKE_OPEN_HANDLE(Message, JSObject) 313MAKE_OPEN_HANDLE(Context, Context) 314MAKE_OPEN_HANDLE(External, Foreign) 315MAKE_OPEN_HANDLE(StackTrace, JSArray) 316MAKE_OPEN_HANDLE(StackFrame, JSObject) 317 318#undef MAKE_OPEN_HANDLE 319 320 321namespace internal { 322 323// Tracks string usage to help make better decisions when 324// externalizing strings. 325// 326// Implementation note: internally this class only tracks fresh 327// strings and keeps a single use counter for them. 328class StringTracker { 329 public: 330 // Records that the given string's characters were copied to some 331 // external buffer. If this happens often we should honor 332 // externalization requests for the string. 333 void RecordWrite(Handle<String> string) { 334 Address address = reinterpret_cast<Address>(*string); 335 Address top = isolate_->heap()->NewSpaceTop(); 336 if (IsFreshString(address, top)) { 337 IncrementUseCount(top); 338 } 339 } 340 341 // Estimates freshness and use frequency of the given string based 342 // on how close it is to the new space top and the recorded usage 343 // history. 344 inline bool IsFreshUnusedString(Handle<String> string) { 345 Address address = reinterpret_cast<Address>(*string); 346 Address top = isolate_->heap()->NewSpaceTop(); 347 return IsFreshString(address, top) && IsUseCountLow(top); 348 } 349 350 private: 351 StringTracker() : use_count_(0), last_top_(NULL), isolate_(NULL) { } 352 353 static inline bool IsFreshString(Address string, Address top) { 354 return top - kFreshnessLimit <= string && string <= top; 355 } 356 357 inline bool IsUseCountLow(Address top) { 358 if (last_top_ != top) return true; 359 return use_count_ < kUseLimit; 360 } 361 362 inline void IncrementUseCount(Address top) { 363 if (last_top_ != top) { 364 use_count_ = 0; 365 last_top_ = top; 366 } 367 ++use_count_; 368 } 369 370 // Single use counter shared by all fresh strings. 371 int use_count_; 372 373 // Last new space top when the use count above was valid. 374 Address last_top_; 375 376 Isolate* isolate_; 377 378 // How close to the new space top a fresh string has to be. 379 static const int kFreshnessLimit = 1024; 380 381 // The number of uses required to consider a string useful. 382 static const int kUseLimit = 32; 383 384 friend class Isolate; 385 386 DISALLOW_COPY_AND_ASSIGN(StringTracker); 387}; 388 389 390// This class is here in order to be able to declare it a friend of 391// HandleScope. Moving these methods to be members of HandleScope would be 392// neat in some ways, but it would expose internal implementation details in 393// our public header file, which is undesirable. 394// 395// An isolate has a single instance of this class to hold the current thread's 396// data. In multithreaded V8 programs this data is copied in and out of storage 397// so that the currently executing thread always has its own copy of this 398// data. 399class HandleScopeImplementer { 400 public: 401 explicit HandleScopeImplementer(Isolate* isolate) 402 : isolate_(isolate), 403 blocks_(0), 404 entered_contexts_(0), 405 saved_contexts_(0), 406 spare_(NULL), 407 call_depth_(0) { } 408 409 ~HandleScopeImplementer() { 410 DeleteArray(spare_); 411 } 412 413 // Threading support for handle data. 414 static int ArchiveSpacePerThread(); 415 char* RestoreThread(char* from); 416 char* ArchiveThread(char* to); 417 void FreeThreadResources(); 418 419 // Garbage collection support. 420 void Iterate(v8::internal::ObjectVisitor* v); 421 static char* Iterate(v8::internal::ObjectVisitor* v, char* data); 422 423 424 inline internal::Object** GetSpareOrNewBlock(); 425 inline void DeleteExtensions(internal::Object** prev_limit); 426 427 inline void IncrementCallDepth() {call_depth_++;} 428 inline void DecrementCallDepth() {call_depth_--;} 429 inline bool CallDepthIsZero() { return call_depth_ == 0; } 430 431 inline void EnterContext(Handle<Object> context); 432 inline bool LeaveLastContext(); 433 434 // Returns the last entered context or an empty handle if no 435 // contexts have been entered. 436 inline Handle<Object> LastEnteredContext(); 437 438 inline void SaveContext(Context* context); 439 inline Context* RestoreContext(); 440 inline bool HasSavedContexts(); 441 442 inline List<internal::Object**>* blocks() { return &blocks_; } 443 444 private: 445 void ResetAfterArchive() { 446 blocks_.Initialize(0); 447 entered_contexts_.Initialize(0); 448 saved_contexts_.Initialize(0); 449 spare_ = NULL; 450 call_depth_ = 0; 451 } 452 453 void Free() { 454 ASSERT(blocks_.length() == 0); 455 ASSERT(entered_contexts_.length() == 0); 456 ASSERT(saved_contexts_.length() == 0); 457 blocks_.Free(); 458 entered_contexts_.Free(); 459 saved_contexts_.Free(); 460 if (spare_ != NULL) { 461 DeleteArray(spare_); 462 spare_ = NULL; 463 } 464 ASSERT(call_depth_ == 0); 465 } 466 467 Isolate* isolate_; 468 List<internal::Object**> blocks_; 469 // Used as a stack to keep track of entered contexts. 470 List<Handle<Object> > entered_contexts_; 471 // Used as a stack to keep track of saved contexts. 472 List<Context*> saved_contexts_; 473 Object** spare_; 474 int call_depth_; 475 // This is only used for threading support. 476 v8::ImplementationUtilities::HandleScopeData handle_scope_data_; 477 478 void IterateThis(ObjectVisitor* v); 479 char* RestoreThreadHelper(char* from); 480 char* ArchiveThreadHelper(char* to); 481 482 DISALLOW_COPY_AND_ASSIGN(HandleScopeImplementer); 483}; 484 485 486static const int kHandleBlockSize = v8::internal::KB - 2; // fit in one page 487 488 489void HandleScopeImplementer::SaveContext(Context* context) { 490 saved_contexts_.Add(context); 491} 492 493 494Context* HandleScopeImplementer::RestoreContext() { 495 return saved_contexts_.RemoveLast(); 496} 497 498 499bool HandleScopeImplementer::HasSavedContexts() { 500 return !saved_contexts_.is_empty(); 501} 502 503 504void HandleScopeImplementer::EnterContext(Handle<Object> context) { 505 entered_contexts_.Add(context); 506} 507 508 509bool HandleScopeImplementer::LeaveLastContext() { 510 if (entered_contexts_.is_empty()) return false; 511 entered_contexts_.RemoveLast(); 512 return true; 513} 514 515 516Handle<Object> HandleScopeImplementer::LastEnteredContext() { 517 if (entered_contexts_.is_empty()) return Handle<Object>::null(); 518 return entered_contexts_.last(); 519} 520 521 522// If there's a spare block, use it for growing the current scope. 523internal::Object** HandleScopeImplementer::GetSpareOrNewBlock() { 524 internal::Object** block = (spare_ != NULL) ? 525 spare_ : 526 NewArray<internal::Object*>(kHandleBlockSize); 527 spare_ = NULL; 528 return block; 529} 530 531 532void HandleScopeImplementer::DeleteExtensions(internal::Object** prev_limit) { 533 while (!blocks_.is_empty()) { 534 internal::Object** block_start = blocks_.last(); 535 internal::Object** block_limit = block_start + kHandleBlockSize; 536#ifdef DEBUG 537 // NoHandleAllocation may make the prev_limit to point inside the block. 538 if (block_start <= prev_limit && prev_limit <= block_limit) break; 539#else 540 if (prev_limit == block_limit) break; 541#endif 542 543 blocks_.RemoveLast(); 544#ifdef DEBUG 545 v8::ImplementationUtilities::ZapHandleRange(block_start, block_limit); 546#endif 547 if (spare_ != NULL) { 548 DeleteArray(spare_); 549 } 550 spare_ = block_start; 551 } 552 ASSERT((blocks_.is_empty() && prev_limit == NULL) || 553 (!blocks_.is_empty() && prev_limit != NULL)); 554} 555 556 557class Testing { 558 public: 559 static v8::Testing::StressType stress_type() { return stress_type_; } 560 static void set_stress_type(v8::Testing::StressType stress_type) { 561 stress_type_ = stress_type; 562 } 563 564 private: 565 static v8::Testing::StressType stress_type_; 566}; 567 568} } // namespace v8::internal 569 570#endif // V8_API_H_ 571