blob: a5c81cec56f1d0056be0d1066683fc27432a4362 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28
29#ifndef V8_HANDLES_INL_H_
30#define V8_HANDLES_INL_H_
31
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000032#include "api.h"
ager@chromium.orgddb913d2009-01-27 10:01:48 +000033#include "apiutils.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034#include "handles.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000035#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036
kasperl@chromium.org71affb52009-05-26 05:44:31 +000037namespace v8 {
38namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000040inline Isolate* GetIsolateForHandle(Object* obj) {
41 return Isolate::Current();
42}
43
44inline Isolate* GetIsolateForHandle(HeapObject* obj) {
45 return obj->GetIsolate();
46}
47
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +000048template<typename T>
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049Handle<T>::Handle(T* obj) {
ager@chromium.org3bf7b912008-11-17 09:09:45 +000050 ASSERT(!obj->IsFailure());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000051 location_ = HandleScope::CreateHandle(obj, GetIsolateForHandle(obj));
52}
53
54
55template<typename T>
56Handle<T>::Handle(T* obj, Isolate* isolate) {
57 ASSERT(!obj->IsFailure());
58 location_ = HandleScope::CreateHandle(obj, isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000059}
60
61
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +000062template <typename T>
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063inline T* Handle<T>::operator*() const {
64 ASSERT(location_ != NULL);
65 ASSERT(reinterpret_cast<Address>(*location_) != kHandleZapValue);
vegorov@chromium.org26c16f82010-08-11 13:41:03 +000066 return *BitCast<T**>(location_);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000067}
68
69
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000070HandleScope::HandleScope() {
71 Isolate* isolate = Isolate::Current();
72 v8::ImplementationUtilities::HandleScopeData* current =
73 isolate->handle_scope_data();
74 isolate_ = isolate;
75 prev_next_ = current->next;
76 prev_limit_ = current->limit;
77 current->level++;
78}
79
80
81HandleScope::HandleScope(Isolate* isolate) {
82 ASSERT(isolate == Isolate::Current());
83 v8::ImplementationUtilities::HandleScopeData* current =
84 isolate->handle_scope_data();
85 isolate_ = isolate;
86 prev_next_ = current->next;
87 prev_limit_ = current->limit;
88 current->level++;
89}
90
91
92HandleScope::~HandleScope() {
93 CloseScope();
94}
95
96void HandleScope::CloseScope() {
97 ASSERT(isolate_ == Isolate::Current());
98 v8::ImplementationUtilities::HandleScopeData* current =
99 isolate_->handle_scope_data();
100 current->next = prev_next_;
101 current->level--;
102 if (current->limit != prev_limit_) {
103 current->limit = prev_limit_;
104 DeleteExtensions(isolate_);
105 }
106#ifdef DEBUG
107 ZapRange(prev_next_, prev_limit_);
108#endif
109}
110
111
112template <typename T>
113Handle<T> HandleScope::CloseAndEscape(Handle<T> handle_value) {
114 T* value = *handle_value;
115 // Throw away all handles in the current scope.
116 CloseScope();
117 v8::ImplementationUtilities::HandleScopeData* current =
118 isolate_->handle_scope_data();
119 // Allocate one handle in the parent scope.
120 ASSERT(current->level > 0);
121 Handle<T> result(CreateHandle<T>(value, isolate_));
122 // Reinitialize the current scope (so that it's ready
123 // to be used or closed again).
124 prev_next_ = current->next;
125 prev_limit_ = current->limit;
126 current->level++;
127 return result;
128}
129
130
131template <typename T>
132T** HandleScope::CreateHandle(T* value, Isolate* isolate) {
133 ASSERT(isolate == Isolate::Current());
134 v8::ImplementationUtilities::HandleScopeData* current =
135 isolate->handle_scope_data();
136
137 internal::Object** cur = current->next;
138 if (cur == current->limit) cur = Extend();
139 // Update the current next field, set the value in the created
140 // handle, and return the result.
141 ASSERT(cur < current->limit);
142 current->next = cur + 1;
143
144 T** result = reinterpret_cast<T**>(cur);
145 *result = value;
146 return result;
147}
148
149
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150#ifdef DEBUG
151inline NoHandleAllocation::NoHandleAllocation() {
ager@chromium.orgddb913d2009-01-27 10:01:48 +0000152 v8::ImplementationUtilities::HandleScopeData* current =
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000153 Isolate::Current()->handle_scope_data();
154
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155 // Shrink the current handle scope to make it impossible to do
156 // handle allocations without an explicit handle scope.
157 current->limit = current->next;
lrn@chromium.org303ada72010-10-27 09:33:13 +0000158
159 level_ = current->level;
160 current->level = 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000161}
162
163
164inline NoHandleAllocation::~NoHandleAllocation() {
165 // Restore state in current handle scope to re-enable handle
166 // allocations.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000167 v8::ImplementationUtilities::HandleScopeData* data =
168 Isolate::Current()->handle_scope_data();
169 ASSERT_EQ(0, data->level);
170 data->level = level_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000171}
172#endif
173
174
175} } // namespace v8::internal
176
177#endif // V8_HANDLES_INL_H_