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 29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_HANDLES_INL_H_ 30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_HANDLES_INL_H_ 31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 3244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "api.h" 33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "apiutils.h" 34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "handles.h" 3544f0eee88ff00398ff7f715fab053374d808c90dSteve Block#include "isolate.h" 36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 { 38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal { 39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 4044f0eee88ff00398ff7f715fab053374d808c90dSteve Blockinline Isolate* GetIsolateForHandle(Object* obj) { 4144f0eee88ff00398ff7f715fab053374d808c90dSteve Block return Isolate::Current(); 4244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 4344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 4444f0eee88ff00398ff7f715fab053374d808c90dSteve Blockinline Isolate* GetIsolateForHandle(HeapObject* obj) { 4544f0eee88ff00398ff7f715fab053374d808c90dSteve Block return obj->GetIsolate(); 4644f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 4744f0eee88ff00398ff7f715fab053374d808c90dSteve Block 48e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochtemplate<typename T> 49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<T>::Handle(T* obj) { 50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(!obj->IsFailure()); 5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block location_ = HandleScope::CreateHandle(obj, GetIsolateForHandle(obj)); 5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 5344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 5544f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktemplate<typename T> 5644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<T>::Handle(T* obj, Isolate* isolate) { 5744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(!obj->IsFailure()); 5844f0eee88ff00398ff7f715fab053374d808c90dSteve Block location_ = HandleScope::CreateHandle(obj, isolate); 59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 62e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochtemplate <typename T> 63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline T* Handle<T>::operator*() const { 64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(location_ != NULL); 65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block ASSERT(reinterpret_cast<Address>(*location_) != kHandleZapValue); 66756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick return *BitCast<T**>(location_); 67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 7044f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandleScope::HandleScope() { 7144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate* isolate = Isolate::Current(); 7244f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::ImplementationUtilities::HandleScopeData* current = 7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->handle_scope_data(); 7444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_ = isolate; 7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_next_ = current->next; 7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_limit_ = current->limit; 7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->level++; 7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 8144f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandleScope::HandleScope(Isolate* isolate) { 8244f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate == Isolate::Current()); 8344f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::ImplementationUtilities::HandleScopeData* current = 8444f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->handle_scope_data(); 8544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_ = isolate; 8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_next_ = current->next; 8744f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_limit_ = current->limit; 8844f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->level++; 8944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 9044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandleScope::~HandleScope() { 9344f0eee88ff00398ff7f715fab053374d808c90dSteve Block CloseScope(); 9444f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 9544f0eee88ff00398ff7f715fab053374d808c90dSteve Block 9644f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid HandleScope::CloseScope() { 9744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate_ == Isolate::Current()); 9844f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::ImplementationUtilities::HandleScopeData* current = 9944f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->handle_scope_data(); 10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->next = prev_next_; 10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->level--; 10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (current->limit != prev_limit_) { 10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->limit = prev_limit_; 10444f0eee88ff00398ff7f715fab053374d808c90dSteve Block DeleteExtensions(isolate_); 10544f0eee88ff00398ff7f715fab053374d808c90dSteve Block } 10644f0eee88ff00398ff7f715fab053374d808c90dSteve Block#ifdef DEBUG 10744f0eee88ff00398ff7f715fab053374d808c90dSteve Block ZapRange(prev_next_, prev_limit_); 10844f0eee88ff00398ff7f715fab053374d808c90dSteve Block#endif 10944f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 11044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11144f0eee88ff00398ff7f715fab053374d808c90dSteve Block 11244f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktemplate <typename T> 11344f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) { 11444f0eee88ff00398ff7f715fab053374d808c90dSteve Block T* value = *handle_value; 11544f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Throw away all handles in the current scope. 11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block CloseScope(); 11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::ImplementationUtilities::HandleScopeData* current = 11844f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate_->handle_scope_data(); 11944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Allocate one handle in the parent scope. 12044f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(current->level > 0); 12144f0eee88ff00398ff7f715fab053374d808c90dSteve Block Handle<T> result(CreateHandle<T>(value, isolate_)); 12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Reinitialize the current scope (so that it's ready 12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block // to be used or closed again). 12444f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_next_ = current->next; 12544f0eee88ff00398ff7f715fab053374d808c90dSteve Block prev_limit_ = current->limit; 12644f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->level++; 12744f0eee88ff00398ff7f715fab053374d808c90dSteve Block return result; 12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 13044f0eee88ff00398ff7f715fab053374d808c90dSteve Block 13144f0eee88ff00398ff7f715fab053374d808c90dSteve Blocktemplate <typename T> 13244f0eee88ff00398ff7f715fab053374d808c90dSteve BlockT** HandleScope::CreateHandle(T* value, Isolate* isolate) { 13344f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(isolate == Isolate::Current()); 13444f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::ImplementationUtilities::HandleScopeData* current = 13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block isolate->handle_scope_data(); 13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block 13744f0eee88ff00398ff7f715fab053374d808c90dSteve Block internal::Object** cur = current->next; 13844f0eee88ff00398ff7f715fab053374d808c90dSteve Block if (cur == current->limit) cur = Extend(); 13944f0eee88ff00398ff7f715fab053374d808c90dSteve Block // Update the current next field, set the value in the created 14044f0eee88ff00398ff7f715fab053374d808c90dSteve Block // handle, and return the result. 14144f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT(cur < current->limit); 14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block current->next = cur + 1; 14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14444f0eee88ff00398ff7f715fab053374d808c90dSteve Block T** result = reinterpret_cast<T**>(cur); 14544f0eee88ff00398ff7f715fab053374d808c90dSteve Block *result = value; 14644f0eee88ff00398ff7f715fab053374d808c90dSteve Block return result; 14744f0eee88ff00398ff7f715fab053374d808c90dSteve Block} 14844f0eee88ff00398ff7f715fab053374d808c90dSteve Block 14944f0eee88ff00398ff7f715fab053374d808c90dSteve Block 150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef DEBUG 151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline NoHandleAllocation::NoHandleAllocation() { 152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block v8::ImplementationUtilities::HandleScopeData* current = 15344f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->handle_scope_data(); 15444f0eee88ff00398ff7f715fab053374d808c90dSteve Block 155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Shrink the current handle scope to make it impossible to do 156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // handle allocations without an explicit handle scope. 157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block current->limit = current->next; 1585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck 1595913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck level_ = current->level; 1605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck current->level = 0; 161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockinline NoHandleAllocation::~NoHandleAllocation() { 165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // Restore state in current handle scope to re-enable handle 166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block // allocations. 16744f0eee88ff00398ff7f715fab053374d808c90dSteve Block v8::ImplementationUtilities::HandleScopeData* data = 16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block Isolate::Current()->handle_scope_data(); 16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block ASSERT_EQ(0, data->level); 17044f0eee88ff00398ff7f715fab053374d808c90dSteve Block data->level = level_; 171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} 172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif 173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} } // namespace v8::internal 176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block 177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif // V8_HANDLES_INL_H_ 178