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