handles.cc revision d0582a6c46733687d045e4188a1bcd0123c758a1
1a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Copyright 2009 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#include "v8.h"
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "accessors.h"
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "api.h"
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "arguments.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "bootstrapper.h"
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "compiler.h"
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "debug.h"
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "execution.h"
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "global-handles.h"
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "natives.h"
39a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "runtime.h"
40d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "stub-cache.h"
41a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
42a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::ImplementationUtilities::HandleScopeData HandleScope::current_ =
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    { -1, NULL, NULL };
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint HandleScope::NumberOfHandles() {
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int n = HandleScopeImplementer::instance()->blocks()->length();
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (n == 0) return 0;
53d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return ((n - 1) * kHandleBlockSize) + static_cast<int>(
54d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      (current_.next - HandleScopeImplementer::instance()->blocks()->last()));
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** HandleScope::Extend() {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Object** result = current_.next;
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(result == current_.limit);
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure there's at least one scope on the stack and that the
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // top of the scope stack isn't a barrier.
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (current_.extensions < 0) {
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Utils::ReportApiFailure("v8::HandleScope::CreateHandle()",
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            "Cannot create a handle without a HandleScope");
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return NULL;
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScopeImplementer* impl = HandleScopeImplementer::instance();
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If there's more room in the last block, we use that. This is used
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for fast creation of scopes after scope barriers.
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!impl->blocks()->is_empty()) {
73a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object** limit = &impl->blocks()->last()[kHandleBlockSize];
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current_.limit != limit) {
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      current_.limit = limit;
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
79a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If we still haven't found a slot for the handle, we extend the
80a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // current handle scope by allocating a new handle block.
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result == current_.limit) {
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If there's a spare block, use it for growing the current scope.
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = impl->GetSpareOrNewBlock();
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Add the extension to the global list of blocks, but count the
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // extension as part of the current scope.
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    impl->blocks()->Add(result);
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    current_.extensions++;
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    current_.limit = &result[kHandleBlockSize];
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScope::DeleteExtensions() {
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(current_.extensions != 0);
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScopeImplementer::instance()->DeleteExtensions(current_.extensions);
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScope::ZapRange(Object** start, Object** end) {
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (start == NULL) return;
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (Object** p = start; p < end; p++) {
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue;
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
109d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockAddress HandleScope::current_extensions_address() {
110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return reinterpret_cast<Address>(&current_.extensions);
111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
114d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockAddress HandleScope::current_next_address() {
115d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return reinterpret_cast<Address>(&current_.next);
116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
117d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
119d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockAddress HandleScope::current_limit_address() {
120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return reinterpret_cast<Address>(&current_.limit);
121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
122d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
123d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content,
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Handle<JSArray> array) {
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(content->AddKeysFromJSArray(*array), FixedArray);
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> UnionOfKeys(Handle<FixedArray> first,
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<FixedArray> second) {
132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(first->UnionOfKeys(*second), FixedArray);
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSGlobalProxy> ReinitializeJSGlobalProxy(
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<JSFunction> constructor,
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<JSGlobalProxy> global) {
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(Heap::ReinitializeJSGlobalProxy(*constructor, *global),
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     JSGlobalProxy);
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
142a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
143a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetExpectedNofProperties(Handle<JSFunction> func, int nof) {
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  func->shared()->set_expected_nof_properties(nof);
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (func->has_initial_map()) {
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Map> new_initial_map =
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Factory::CopyMapDropTransitions(Handle<Map>(func->initial_map()));
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    new_initial_map->set_unused_property_fields(nof);
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    func->set_initial_map(*new_initial_map);
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value) {
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION_VOID(func->SetPrototype(*value));
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int ExpectedNofPropertiesFromEstimate(int estimate) {
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // TODO(1231235): We need dynamic feedback to estimate the number
162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // of expected properties in an object. The static hack below
163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is barely a solution.
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (estimate == 0) return 4;
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return estimate + 2;
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          int estimate) {
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shared->set_expected_nof_properties(
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ExpectedNofPropertiesFromEstimate(estimate));
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetExpectedNofPropertiesFromEstimate(Handle<JSFunction> func,
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          int estimate) {
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SetExpectedNofProperties(
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      func, ExpectedNofPropertiesFromEstimate(estimate));
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NormalizeProperties(Handle<JSObject> object,
184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         PropertyNormalizationMode mode,
185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         int expected_additional_properties) {
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION_VOID(object->NormalizeProperties(
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      mode,
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      expected_additional_properties));
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NormalizeElements(Handle<JSObject> object) {
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION_VOID(object->NormalizeElements());
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid TransformToFastProperties(Handle<JSObject> object,
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               int unused_property_fields) {
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION_VOID(
200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      object->TransformToFastProperties(unused_property_fields));
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FlattenString(Handle<String> string) {
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION_VOID(string->TryFlattenIfNotFlat());
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(string->IsFlat());
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
210a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetPrototype(Handle<JSFunction> function,
211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Handle<Object> prototype) {
212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(Accessors::FunctionSetPrototype(*function,
213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     *prototype,
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     NULL),
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetProperty(Handle<JSObject> object,
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<String> key,
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> value,
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           PropertyAttributes attributes) {
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(object->SetProperty(*key, *value, attributes), Object);
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetProperty(Handle<Object> object,
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> key,
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> value,
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           PropertyAttributes attributes) {
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Runtime::SetObjectProperty(object, key, value, attributes), Object);
233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> ForceSetProperty(Handle<JSObject> object,
237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                Handle<Object> key,
238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                Handle<Object> value,
239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                PropertyAttributes attributes) {
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(
241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Runtime::ForceSetObjectProperty(object, key, value, attributes), Object);
242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> ForceDeleteProperty(Handle<JSObject> object,
246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   Handle<Object> key) {
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(Runtime::ForceDeleteObjectProperty(object, key), Object);
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> IgnoreAttributesAndSetLocalProperty(
252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<JSObject> object,
253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<String> key,
254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Object> value,
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PropertyAttributes attributes) {
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(object->
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      IgnoreAttributesAndSetLocalProperty(*key, *value, attributes), Object);
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<String> key,
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<Object> value,
264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          PropertyAttributes attributes) {
265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(object->SetPropertyWithInterceptor(*key,
266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        *value,
267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        attributes),
268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetProperty(Handle<JSObject> obj,
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           const char* name) {
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> str = Factory::LookupAsciiSymbol(name);
275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(obj->GetProperty(*str), Object);
276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetProperty(Handle<Object> obj,
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> key) {
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(Runtime::GetObjectProperty(obj, key), Object);
282a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<JSObject> holder,
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<String> name,
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          PropertyAttributes* attributes) {
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(holder->GetPropertyWithInterceptor(*receiver,
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        *name,
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        attributes),
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
294a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetPrototype(Handle<Object> obj) {
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> result(obj->GetPrototype());
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetHiddenProperties(Handle<JSObject> obj,
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   bool create_if_needed) {
304d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Object* holder = obj->BypassGlobalProxy();
305d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (holder->IsUndefined()) return Factory::undefined_value();
306d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  obj = Handle<JSObject>(JSObject::cast(holder));
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->HasFastProperties()) {
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the object has fast properties, check whether the first slot
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // in the descriptor array matches the hidden symbol. Since the
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // hidden symbols hash code is zero (and no other string has hash
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // code zero) it will always occupy the first entry if present.
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    DescriptorArray* descriptors = obj->map()->instance_descriptors();
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if ((descriptors->number_of_descriptors() > 0) &&
315d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        (descriptors->GetKey(0) == Heap::hidden_symbol()) &&
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        descriptors->IsProperty(0)) {
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ASSERT(descriptors->GetType(0) == FIELD);
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return Handle<Object>(obj->FastPropertyAt(descriptors->GetFieldIndex(0)));
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only attempt to find the hidden properties in the local object and not
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in the prototype chain.  Note that HasLocalProperty() can cause a GC in
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the general case in the presence of interceptors.
325d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (!obj->HasHiddenPropertiesObject()) {
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Hidden properties object not found. Allocate a new hidden properties
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // object if requested. Otherwise return the undefined value.
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (create_if_needed) {
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<Object> hidden_obj = Factory::NewJSObject(Top::object_function());
330d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      CALL_HEAP_FUNCTION(obj->SetHiddenPropertiesObject(*hidden_obj), Object);
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return Factory::undefined_value();
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
335d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return Handle<Object>(obj->GetHiddenPropertiesObject());
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> DeleteElement(Handle<JSObject> obj,
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             uint32_t index) {
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(obj->DeleteElement(index, JSObject::NORMAL_DELETION),
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> DeleteProperty(Handle<JSObject> obj,
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Handle<String> prop) {
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION),
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> LookupSingleCharacterStringFromCode(uint32_t index) {
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(Heap::LookupSingleCharacterStringFromCode(index), Object);
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<String> SubString(Handle<String> str, int start, int end) {
359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CALL_HEAP_FUNCTION(str->SubString(start, end), String);
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetElement(Handle<JSObject> object,
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          uint32_t index,
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Handle<Object> value) {
3663ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (object->HasPixelElements() || object->HasExternalArrayElements()) {
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) {
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bool has_exception;
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<Object> number = Execution::ToNumber(value, &has_exception);
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (has_exception) return Handle<Object>();
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value = number;
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(object->SetElement(index, *value), Object);
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSObject> Copy(Handle<JSObject> obj) {
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(Heap::CopyJSObject(*obj), JSObject);
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Wrappers for scripts are kept alive and cached in weak global
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// handles referred from proxy objects held by the scripts as long as
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// they are used. When they are not used anymore, the garbage
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// collector will call the weak callback on the global handle
387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// associated with the wrapper and get rid of both the wrapper and the
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// handle.
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_HEAP_PROTECTION
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Weak reference callbacks are called as if from outside V8.  We
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // need to reeenter to unprotect the heap.
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(OTHER);
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> cache = Utils::OpenHandle(*handle);
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSValue* wrapper = JSValue::cast(*cache);
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Proxy* proxy = Script::cast(wrapper->value())->wrapper();
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(proxy->proxy() == reinterpret_cast<Address>(cache.location()));
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  proxy->set_proxy(0);
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  GlobalHandles::Destroy(cache.location());
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::script_wrappers.Decrement();
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSValue> GetScriptWrapper(Handle<Script> script) {
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (script->wrapper()->proxy() != NULL) {
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Return the script wrapper directly from the cache.
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<JSValue>(
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<JSValue**>(script->wrapper()->proxy()));
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Construct a new script wrapper.
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::script_wrappers.Increment();
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<JSFunction> constructor = Top::script_function();
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<JSValue> result =
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<JSValue>::cast(Factory::NewJSObject(constructor));
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  result->set_value(*script);
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a new weak global handle and use it to cache the wrapper
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for future use. The cache will automatically be cleared by the
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // garbage collector when it is not used anymore.
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> handle = GlobalHandles::Create(*result);
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  GlobalHandles::MakeWeak(handle.location(), NULL, &ClearWrapperCache);
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  script->wrapper()->set_proxy(reinterpret_cast<Address>(handle.location()));
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Init line_ends array with code positions of line ends inside script
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// source.
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid InitScriptLineEnds(Handle<Script> script) {
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!script->line_ends()->IsUndefined()) return;
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!script->source()->IsString()) {
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(script->source()->IsUndefined());
436d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    script->set_line_ends(*(Factory::NewFixedArray(0)));
437d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ASSERT(script->line_ends()->IsFixedArray());
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> src(String::cast(script->source()));
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  const int src_len = src->length();
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<String> new_line = Factory::NewStringFromAscii(CStrVector("\n"));
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Pass 1: Identify line count.
446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int line_count = 0;
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int position = 0;
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (position != -1 && position < src_len) {
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    position = Runtime::StringMatch(src, new_line, position);
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (position != -1) {
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      position++;
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Even if the last line misses a line end, it is counted.
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line_count++;
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Pass 2: Fill in line ends positions
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> array = Factory::NewFixedArray(line_count);
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int array_index = 0;
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  position = 0;
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (position != -1 && position < src_len) {
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    position = Runtime::StringMatch(src, new_line, position);
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the script does not end with a line ending add the final end
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // position as just past the last line ending.
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    array->set(array_index++,
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               Smi::FromInt(position != -1 ? position++ : src_len));
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(array_index == line_count);
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
470d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  script->set_line_ends(*array);
471d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  ASSERT(script->line_ends()->IsFixedArray());
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert code position into line number.
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint GetScriptLineNumber(Handle<Script> script, int code_pos) {
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitScriptLineEnds(script);
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  AssertNoAllocation no_allocation;
479d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  FixedArray* line_ends_array =
480d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      FixedArray::cast(script->line_ends());
481d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  const int line_ends_len = line_ends_array->length();
482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int line = -1;
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line_ends_len > 0 &&
485d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      code_pos <= (Smi::cast(line_ends_array->get(0)))->value()) {
486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line = 0;
487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 1; i < line_ends_len; ++i) {
489d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      if ((Smi::cast(line_ends_array->get(i - 1)))->value() < code_pos &&
490d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block          code_pos <= (Smi::cast(line_ends_array->get(i)))->value()) {
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        line = i;
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        break;
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return line != -1 ? line + script->line_offset()->value() : line;
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CustomArguments::IterateInstance(ObjectVisitor* v) {
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v->VisitPointers(values_, values_ + 4);
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compute the property keys from the interceptor.
507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver,
508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                 Handle<JSObject> object) {
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CustomArguments args(interceptor->data(), *receiver, *object);
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::AccessorInfo info(args.end());
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::Handle<v8::Array> result;
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!interceptor->enumerator()->IsUndefined()) {
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::NamedPropertyEnumerator enum_fun =
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator());
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    LOG(ApiObjectAccess("interceptor-named-enum", *object));
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      VMState state(EXTERNAL);
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = enum_fun(info);
521a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compute the element keys from the interceptor.
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver,
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                   Handle<JSObject> object) {
530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CustomArguments args(interceptor->data(), *receiver, *object);
532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::AccessorInfo info(args.end());
533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::Handle<v8::Array> result;
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!interceptor->enumerator()->IsUndefined()) {
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::IndexedPropertyEnumerator enum_fun =
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator());
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    LOG(ApiObjectAccess("interceptor-indexed-enum", *object));
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      VMState state(EXTERNAL);
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = enum_fun(info);
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object,
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          KeyCollectionType type) {
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> content = Factory::empty_fixed_array();
551d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Handle<JSObject> arguments_boilerplate =
552d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Handle<JSObject>(
553d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block          Top::context()->global_context()->arguments_boilerplate());
554d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Handle<JSFunction> arguments_function =
555d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Handle<JSFunction>(
556d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block          JSFunction::cast(arguments_boilerplate->map()->constructor()));
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only collect keys if access is permitted.
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (Handle<Object> p = object;
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       *p != Heap::null_value();
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       p = Handle<Object>(p->GetPrototype())) {
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<JSObject> current(JSObject::cast(*p));
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Check access rights if required.
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current->IsAccessCheckNeeded() &&
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      !Top::MayNamedAccess(*current, Heap::undefined_value(),
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           v8::ACCESS_KEYS)) {
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Top::ReportFailedAccessCheck(*current, v8::ACCESS_KEYS);
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Compute the element keys.
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> element_keys =
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Factory::NewFixedArray(current->NumberOfEnumElements());
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    current->GetEnumElementKeys(*element_keys);
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    content = UnionOfKeys(content, element_keys);
577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Add the element keys from the interceptor.
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current->HasIndexedInterceptor()) {
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::Handle<v8::Array> result =
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          GetKeysForIndexedInterceptor(object, current);
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!result.IsEmpty())
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
586d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // We can cache the computed property keys if access checks are
587d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // not needed and no interceptors are involved.
588d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    //
589d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // We do not use the cache if the object has elements and
590d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // therefore it does not make sense to cache the property names
591d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // for arguments objects.  Arguments objects will always have
592d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // elements.
593d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    bool cache_enum_keys =
594d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        ((current->map()->constructor() != *arguments_function) &&
595d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block         !current->IsAccessCheckNeeded() &&
596d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block         !current->HasNamedInterceptor() &&
597d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block         !current->HasIndexedInterceptor());
598d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Compute the property keys and cache them if possible.
599d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    content =
600d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        UnionOfKeys(content, GetEnumPropertyKeys(current, cache_enum_keys));
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Add the property keys from the interceptor.
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current->HasNamedInterceptor()) {
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::Handle<v8::Array> result =
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          GetKeysForNamedInterceptor(object, current);
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!result.IsEmpty())
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If we only want local properties we bail out after the first
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // iteration.
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (type == LOCAL_ONLY)
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return content;
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
617a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSArray> GetKeysFor(Handle<JSObject> object) {
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Counters::for_in.Increment();
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> elements = GetKeysInFixedArrayFor(object,
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                       INCLUDE_PROTOS);
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Factory::NewJSArrayWithElements(elements);
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
627d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
628d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                       bool cache_result) {
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int index = 0;
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (object->HasFastProperties()) {
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (object->map()->instance_descriptors()->HasEnumCache()) {
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Counters::enum_cache_hits.Increment();
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      DescriptorArray* desc = object->map()->instance_descriptors();
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache()));
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Counters::enum_cache_misses.Increment();
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int num_enum = object->NumberOfEnumProperties();
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> storage = Factory::NewFixedArray(num_enum);
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum);
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<DescriptorArray> descs =
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        Handle<DescriptorArray>(object->map()->instance_descriptors());
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < descs->number_of_descriptors(); i++) {
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (descs->IsProperty(i) && !descs->IsDontEnum(i)) {
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (*storage)->set(index, descs->GetKey(i));
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        PropertyDetails details(descs->GetDetails(i));
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (*sort_array)->set(index, Smi::FromInt(details.index()));
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        index++;
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    (*storage)->SortPairs(*sort_array, sort_array->length());
651d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (cache_result) {
652d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Handle<FixedArray> bridge_storage =
653d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block          Factory::NewFixedArray(DescriptorArray::kEnumCacheBridgeLength);
654d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      DescriptorArray* desc = object->map()->instance_descriptors();
655d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      desc->SetEnumCache(*bridge_storage, *storage);
656d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(storage->length() == index);
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return storage;
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int num_enum = object->NumberOfEnumProperties();
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> storage = Factory::NewFixedArray(num_enum);
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum);
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    object->property_dictionary()->CopyEnumKeysTo(*storage, *sort_array);
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return storage;
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool CompileLazyShared(Handle<SharedFunctionInfo> shared,
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       ClearExceptionFlag flag,
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int loop_nesting) {
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the source information to a code object.
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!shared->is_compiled());
674a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result = Compiler::CompileLazy(shared, loop_nesting);
675a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(result != Top::has_pending_exception());
676a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!result && flag == CLEAR_EXCEPTION) Top::clear_pending_exception();
677a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
678a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) {
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the source information to a code object.
683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<SharedFunctionInfo> shared(function->shared());
684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return CompileLazyShared(shared, flag, 0);
685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag flag) {
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the source information to a code object.
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<SharedFunctionInfo> shared(function->shared());
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return CompileLazyShared(shared, flag, 1);
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOptimizedObjectForAddingMultipleProperties::
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOptimizedObjectForAddingMultipleProperties(Handle<JSObject> object,
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                           int expected_additional_properties,
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                           bool condition) {
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  object_ = object;
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (condition && object_->HasFastProperties()) {
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Normalize the properties of object to avoid n^2 behavior
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // when extending the object multiple properties. Indicate the number of
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // properties to be added.
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    unused_property_fields_ = object->map()->unused_property_fields();
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    NormalizeProperties(object_,
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        KEEP_INOBJECT_PROPERTIES,
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        expected_additional_properties);
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    has_been_transformed_ = true;
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    has_been_transformed_ = false;
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
715d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<Code> ComputeLazyCompile(int argc) {
716d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  CALL_HEAP_FUNCTION(StubCache::ComputeLazyCompile(argc), Code);
717d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
718d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
719d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockOptimizedObjectForAddingMultipleProperties::
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block~OptimizedObjectForAddingMultipleProperties() {
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Reoptimize the object to allow fast property access.
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (has_been_transformed_) {
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TransformToFastProperties(object_, unused_property_fields_);
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid LoadLazy(Handle<JSObject> obj, bool* pending_exception) {
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  HandleScope scope;
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> info(FixedArray::cast(obj->map()->constructor()));
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int index = Smi::cast(info->get(0))->value();
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(index >= 0);
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Context> compile_context(Context::cast(info->get(1)));
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Context> function_context(Context::cast(info->get(2)));
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> receiver(compile_context->global()->builtins());
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Vector<const char> name = Natives::GetScriptName(index);
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<JSFunction> boilerplate;
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!Bootstrapper::NativesCacheLookup(name, &boilerplate)) {
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<String> source_code = Bootstrapper::NativesSourceLookup(index);
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<String> script_name = Factory::NewStringFromAscii(name);
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    bool allow_natives_syntax = FLAG_allow_natives_syntax;
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FLAG_allow_natives_syntax = true;
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    boilerplate = Compiler::Compile(source_code, script_name, 0, 0, NULL, NULL);
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    FLAG_allow_natives_syntax = allow_natives_syntax;
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the compilation failed (possibly due to stack overflows), we
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // should never enter the result in the natives cache. Instead we
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // return from the function without marking the function as having
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // been lazily loaded.
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (boilerplate.is_null()) {
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      *pending_exception = true;
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return;
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Bootstrapper::NativesCacheAdd(name, boilerplate);
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We shouldn't get here if compiling the script failed.
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!boilerplate.is_null());
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // When the debugger running in its own context touches lazy loaded
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // functions loading can be triggered. In that case ensure that the
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // execution of the boilerplate is in the correct context.
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  SaveContext save;
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!Debug::debug_context().is_null() &&
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Top::context() == *Debug::debug_context()) {
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Top::set_context(*compile_context);
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Reset the lazy load data before running the script to make sure
775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // not to get recursive lazy loading.
776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->map()->set_needs_loading(false);
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->map()->set_constructor(info->get(3));
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Run the script.
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<JSFunction> script_fun(
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Factory::NewFunctionFromBoilerplate(boilerplate, function_context));
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Execution::Call(script_fun, receiver, 0, NULL, pending_exception);
783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If lazy loading failed, restore the unloaded state of obj.
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (*pending_exception) {
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    obj->map()->set_needs_loading(true);
787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    obj->map()->set_constructor(*info);
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetupLazy(Handle<JSObject> obj,
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               int index,
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               Handle<Context> compile_context,
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block               Handle<Context> function_context) {
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> arr = Factory::NewFixedArray(4);
797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  arr->set(0, Smi::FromInt(index));
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  arr->set(1, *compile_context);  // Compile in this context
799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  arr->set(2, *function_context);  // Set function context to this
800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  arr->set(3, obj->map()->constructor());  // Remember the constructor
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Map> old_map(obj->map());
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Map> new_map = Factory::CopyMapDropTransitions(old_map);
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_map(*new_map);
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  new_map->set_needs_loading(true);
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Store the lazy loading info in the constructor field.  We'll
806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // reestablish the constructor from the fixed array after loading.
807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  new_map->set_constructor(*arr);
808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(!obj->IsLoaded());
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
812