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"
408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang#include "string-search.h"
41d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block#include "stub-cache.h"
42b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#include "vm-state-inl.h"
43a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
44a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
45a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
46a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
48a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint HandleScope::NumberOfHandles() {
4944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
5044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScopeImplementer* impl = isolate->handle_scope_implementer();
5144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int n = impl->blocks()->length();
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (n == 0) return 0;
53d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return ((n - 1) * kHandleBlockSize) + static_cast<int>(
5444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      (isolate->handle_scope_data()->next - impl->blocks()->last()));
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockObject** HandleScope::Extend() {
5944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::ImplementationUtilities::HandleScopeData* current =
6144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->handle_scope_data();
6244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Object** result = current->next;
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(result == current->limit);
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Make sure there's at least one scope on the stack and that the
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // top of the scope stack isn't a barrier.
6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (current->level == 0) {
69a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Utils::ReportApiFailure("v8::HandleScope::CreateHandle()",
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            "Cannot create a handle without a HandleScope");
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return NULL;
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
7344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScopeImplementer* impl = isolate->handle_scope_implementer();
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If there's more room in the last block, we use that. This is used
75a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for fast creation of scopes after scope barriers.
76a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!impl->blocks()->is_empty()) {
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object** limit = &impl->blocks()->last()[kHandleBlockSize];
7844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (current->limit != limit) {
7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      current->limit = limit;
8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      ASSERT(limit - current->next < kHandleBlockSize);
81a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
84a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If we still haven't found a slot for the handle, we extend the
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // current handle scope by allocating a new handle block.
8644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (result == current->limit) {
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If there's a spare block, use it for growing the current scope.
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    result = impl->GetSpareOrNewBlock();
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Add the extension to the global list of blocks, but count the
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // extension as part of the current scope.
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    impl->blocks()->Add(result);
9244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    current->limit = &result[kHandleBlockSize];
93a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
95a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
96a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9944f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid HandleScope::DeleteExtensions(Isolate* isolate) {
10044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(isolate == Isolate::Current());
10144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  v8::ImplementationUtilities::HandleScopeData* current =
10244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->handle_scope_data();
10344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->handle_scope_implementer()->DeleteExtensions(current->limit);
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScope::ZapRange(Object** start, Object** end) {
1085913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  ASSERT(end - start <= kHandleBlockSize);
1095913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  for (Object** p = start; p != end; p++) {
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue;
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1155913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckAddress HandleScope::current_level_address() {
11644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reinterpret_cast<Address>(
11744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      &Isolate::Current()->handle_scope_data()->level);
118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
119d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
121d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockAddress HandleScope::current_next_address() {
12244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reinterpret_cast<Address>(
12344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      &Isolate::Current()->handle_scope_data()->next);
124d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
125d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
127d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockAddress HandleScope::current_limit_address() {
12844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return reinterpret_cast<Address>(
12944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      &Isolate::Current()->handle_scope_data()->limit);
130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
131d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content,
134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      Handle<JSArray> array) {
13544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(content->GetIsolate(),
13644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     content->AddKeysFromJSArray(*array), FixedArray);
137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> UnionOfKeys(Handle<FixedArray> first,
141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Handle<FixedArray> second) {
14244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(first->GetIsolate(),
14344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     first->UnionOfKeys(*second), FixedArray);
144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSGlobalProxy> ReinitializeJSGlobalProxy(
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<JSFunction> constructor,
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<JSGlobalProxy> global) {
15044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(
15144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      constructor->GetIsolate(),
15244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global),
15344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      JSGlobalProxy);
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetExpectedNofProperties(Handle<JSFunction> func, int nof) {
1580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // If objects constructed from this function exist then changing
1598a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // 'estimated_nof_properties' is dangerous since the previous value might
1600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // have been compiled into the fast construct stub. More over, the inobject
1610d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // slack tracking logic might have adjusted the previous value, so even
1620d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // passing the same value is risky.
1630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (func->shared()->live_objects_may_exist()) return;
1640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  func->shared()->set_expected_nof_properties(nof);
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (func->has_initial_map()) {
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Map> new_initial_map =
16844f0eee88ff00398ff7f715fab053374d808c90dSteve Block        func->GetIsolate()->factory()->CopyMapDropTransitions(
16944f0eee88ff00398ff7f715fab053374d808c90dSteve Block            Handle<Map>(func->initial_map()));
170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    new_initial_map->set_unused_property_fields(nof);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    func->set_initial_map(*new_initial_map);
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
176a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value) {
17744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION_VOID(func->GetIsolate(),
17844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          func->SetPrototype(*value));
179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic int ExpectedNofPropertiesFromEstimate(int estimate) {
1830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // If no properties are added in the constructor, they are more likely
1840d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // to be added later.
1850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (estimate == 0) estimate = 2;
1860d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // We do not shrink objects that go into a snapshot (yet), so we adjust
1880d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // the estimate conservatively.
1890d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (Serializer::enabled()) return estimate + 2;
1900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Inobject slack tracking will reclaim redundant inobject space later,
1920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // so we can afford to adjust the estimate generously.
193f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return estimate + 8;
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid SetExpectedNofPropertiesFromEstimate(Handle<SharedFunctionInfo> shared,
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          int estimate) {
1990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // See the comment in SetExpectedNofProperties.
2000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (shared->live_objects_may_exist()) return;
2010d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  shared->set_expected_nof_properties(
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ExpectedNofPropertiesFromEstimate(estimate));
204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
207a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NormalizeProperties(Handle<JSObject> object,
208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         PropertyNormalizationMode mode,
209a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         int expected_additional_properties) {
21044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
21144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          object->NormalizeProperties(
21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              mode,
21344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              expected_additional_properties));
214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NormalizeElements(Handle<JSObject> object) {
21844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
21944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          object->NormalizeElements());
220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid TransformToFastProperties(Handle<JSObject> object,
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               int unused_property_fields) {
225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION_VOID(
22644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      object->GetIsolate(),
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      object->TransformToFastProperties(unused_property_fields));
228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2315913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reckvoid NumberDictionarySet(Handle<NumberDictionary> dictionary,
2325913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                         uint32_t index,
2335913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                         Handle<Object> value,
2345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                         PropertyDetails details) {
23544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(),
23644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                          dictionary->Set(index, *value, details));
2375913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck}
2385913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
2395913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
240a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FlattenString(Handle<String> string) {
24144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION_VOID(string->GetIsolate(), string->TryFlatten());
2428defd9ff6930b4e24729971a61cf7469daf119beSteve Block}
2438defd9ff6930b4e24729971a61cf7469daf119beSteve Block
2448defd9ff6930b4e24729971a61cf7469daf119beSteve Block
2458defd9ff6930b4e24729971a61cf7469daf119beSteve BlockHandle<String> FlattenGetString(Handle<String> string) {
24644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(string->GetIsolate(), string->TryFlatten(), String);
247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
250a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetPrototype(Handle<JSFunction> function,
251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                            Handle<Object> prototype) {
2526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(function->should_have_prototype());
25344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(function->GetIsolate(),
25444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Accessors::FunctionSetPrototype(*function,
255a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     *prototype,
256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                     NULL),
257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetProperty(Handle<JSObject> object,
262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<String> key,
263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> value,
264e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                           PropertyAttributes attributes,
265e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                           StrictModeFlag strict_mode) {
26644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(object->GetIsolate(),
26744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     object->SetProperty(*key, *value, attributes, strict_mode),
268e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                     Object);
269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
271a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
272a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetProperty(Handle<Object> object,
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> key,
274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> value,
275e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                           PropertyAttributes attributes,
276e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                           StrictModeFlag strict_mode) {
27744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(
27944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate,
28044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Runtime::SetObjectProperty(
28144f0eee88ff00398ff7f715fab053374d808c90dSteve Block          isolate, object, key, value, attributes, strict_mode),
282e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Object);
283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> ForceSetProperty(Handle<JSObject> object,
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                Handle<Object> key,
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                Handle<Object> value,
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                PropertyAttributes attributes) {
29044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = object->GetIsolate();
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CALL_HEAP_FUNCTION(
29244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate,
293e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Runtime::ForceSetObjectProperty(
29444f0eee88ff00398ff7f715fab053374d808c90dSteve Block          isolate, object, key, value, attributes),
295e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch      Object);
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2993100271588b61cbc1dc472a3f2f105d2eed8497fAndrei PopescuHandle<Object> SetNormalizedProperty(Handle<JSObject> object,
3003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                     Handle<String> key,
3013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                     Handle<Object> value,
3023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                                     PropertyDetails details) {
30344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(object->GetIsolate(),
30444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     object->SetNormalizedProperty(*key, *value, details),
3053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                     Object);
3063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu}
3073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
3083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> ForceDeleteProperty(Handle<JSObject> object,
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   Handle<Object> key) {
31144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = object->GetIsolate();
31244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate,
31344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Runtime::ForceDeleteObjectProperty(isolate, object, key),
31444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Object);
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
318086aeeaae12517475c22695a200be45495516549Ben MurdochHandle<Object> SetLocalPropertyIgnoreAttributes(
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<JSObject> object,
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<String> key,
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<Object> value,
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    PropertyAttributes attributes) {
32344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(
32444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    object->GetIsolate(),
32544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes),
32644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Object);
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3301e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockvoid SetLocalPropertyNoThrow(Handle<JSObject> object,
3311e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                             Handle<String> key,
3321e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                             Handle<Object> value,
3331e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                             PropertyAttributes attributes) {
33444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = object->GetIsolate();
33544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!isolate->has_pending_exception());
3361e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  CHECK(!SetLocalPropertyIgnoreAttributes(
3371e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block        object, key, value, attributes).is_null());
33844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CHECK(!isolate->has_pending_exception());
3391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
3401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
3411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<String> key,
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<Object> value,
345e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                          PropertyAttributes attributes,
346e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                          StrictModeFlag strict_mode) {
34744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(object->GetIsolate(),
34844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     object->SetPropertyWithInterceptor(*key,
349a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        *value,
350e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                        attributes,
351e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                                        strict_mode),
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetProperty(Handle<JSObject> obj,
357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           const char* name) {
35844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = obj->GetIsolate();
35944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<String> str = isolate->factory()->LookupAsciiSymbol(name);
36044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate, obj->GetProperty(*str), Object);
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetProperty(Handle<Object> obj,
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                           Handle<Object> key) {
36644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
36744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate,
36844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     Runtime::GetObjectProperty(isolate, obj, key), Object);
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3728b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochHandle<Object> GetProperty(Handle<JSObject> obj,
3738b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                           Handle<String> name,
3748b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                           LookupResult* result) {
3758b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  PropertyAttributes attributes;
3768b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Isolate* isolate = Isolate::Current();
3778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  CALL_HEAP_FUNCTION(isolate,
3788b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                     obj->GetProperty(*obj, result, *name, &attributes),
3798b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch                     Object);
3808b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
3818b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3828b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3836ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<Object> GetElement(Handle<Object> obj,
3846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                          uint32_t index) {
38544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
38644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate, Runtime::GetElement(obj, index), Object);
3876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
3886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver,
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<JSObject> holder,
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          Handle<String> name,
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          PropertyAttributes* attributes) {
39444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = receiver->GetIsolate();
39544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate,
39644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     holder->GetPropertyWithInterceptor(*receiver,
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        *name,
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                        attributes),
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetPrototype(Handle<Object> obj) {
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> result(obj->GetPrototype());
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
409402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuHandle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value) {
410402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  const bool skip_hidden_prototypes = false;
41144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(obj->GetIsolate(),
41244f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     obj->SetPrototype(*value, skip_hidden_prototypes), Object);
41344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
41444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
41644f0eee88ff00398ff7f715fab053374d808c90dSteve BlockHandle<Object> PreventExtensions(Handle<JSObject> object) {
41744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(object->GetIsolate(), object->PreventExtensions(), Object);
418402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
419402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
420402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> GetHiddenProperties(Handle<JSObject> obj,
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   bool create_if_needed) {
42344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = obj->GetIsolate();
424d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  Object* holder = obj->BypassGlobalProxy();
42544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (holder->IsUndefined()) return isolate->factory()->undefined_value();
42644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  obj = Handle<JSObject>(JSObject::cast(holder), isolate);
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->HasFastProperties()) {
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If the object has fast properties, check whether the first slot
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // in the descriptor array matches the hidden symbol. Since the
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // hidden symbols hash code is zero (and no other string has hash
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // code zero) it will always occupy the first entry if present.
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    DescriptorArray* descriptors = obj->map()->instance_descriptors();
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if ((descriptors->number_of_descriptors() > 0) &&
43544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        (descriptors->GetKey(0) == isolate->heap()->hidden_symbol()) &&
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        descriptors->IsProperty(0)) {
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ASSERT(descriptors->GetType(0) == FIELD);
43844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return Handle<Object>(obj->FastPropertyAt(descriptors->GetFieldIndex(0)),
43944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            isolate);
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only attempt to find the hidden properties in the local object and not
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // in the prototype chain.  Note that HasLocalProperty() can cause a GC in
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the general case in the presence of interceptors.
446d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (!obj->HasHiddenPropertiesObject()) {
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Hidden properties object not found. Allocate a new hidden properties
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // object if requested. Otherwise return the undefined value.
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (create_if_needed) {
45044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<Object> hidden_obj =
45144f0eee88ff00398ff7f715fab053374d808c90dSteve Block          isolate->factory()->NewJSObject(isolate->object_function());
45244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      CALL_HEAP_FUNCTION(isolate,
45344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                         obj->SetHiddenPropertiesObject(*hidden_obj), Object);
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
45544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return isolate->factory()->undefined_value();
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
45844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Handle<Object>(obj->GetHiddenPropertiesObject(), isolate);
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> DeleteElement(Handle<JSObject> obj,
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                             uint32_t index) {
46444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(obj->GetIsolate(),
46544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     obj->DeleteElement(index, JSObject::NORMAL_DELETION),
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> DeleteProperty(Handle<JSObject> obj,
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Handle<String> prop) {
47244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(obj->GetIsolate(),
47344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION),
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     Object);
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> LookupSingleCharacterStringFromCode(uint32_t index) {
47944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
48044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(
48144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate,
48244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->heap()->LookupSingleCharacterStringFromCode(index), Object);
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4866ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<String> SubString(Handle<String> str,
4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int start,
4886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         int end,
4896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         PretenureFlag pretenure) {
49044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(str->GetIsolate(),
49144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     str->SubString(start, end, pretenure), String);
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Object> SetElement(Handle<JSObject> object,
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          uint32_t index,
497e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          Handle<Object> value,
498e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                          StrictModeFlag strict_mode) {
49944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (object->HasExternalArrayElements()) {
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) {
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      bool has_exception;
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Handle<Object> number = Execution::ToNumber(value, &has_exception);
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (has_exception) return Handle<Object>();
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value = number;
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
50744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(object->GetIsolate(),
50844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     object->SetElement(index, *value, strict_mode), Object);
509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
512086aeeaae12517475c22695a200be45495516549Ben MurdochHandle<Object> SetOwnElement(Handle<JSObject> object,
513086aeeaae12517475c22695a200be45495516549Ben Murdoch                             uint32_t index,
514e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                             Handle<Object> value,
515e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                             StrictModeFlag strict_mode) {
516086aeeaae12517475c22695a200be45495516549Ben Murdoch  ASSERT(!object->HasExternalArrayElements());
51744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(object->GetIsolate(),
51844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     object->SetElement(index, *value, strict_mode, false),
519e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                     Object);
520086aeeaae12517475c22695a200be45495516549Ben Murdoch}
521086aeeaae12517475c22695a200be45495516549Ben Murdoch
522086aeeaae12517475c22695a200be45495516549Ben Murdoch
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSObject> Copy(Handle<JSObject> obj) {
52444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = obj->GetIsolate();
52544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(isolate,
52644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                     isolate->heap()->CopyJSObject(*obj), JSObject);
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
530f7060e27768c550ace7ec48ad8c093466db52dfaLeon ClarkeHandle<Object> SetAccessor(Handle<JSObject> obj, Handle<AccessorInfo> info) {
53144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CALL_HEAP_FUNCTION(obj->GetIsolate(), obj->DefineAccessor(*info), Object);
532f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
533f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
534f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Wrappers for scripts are kept alive and cached in weak global
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// handles referred from proxy objects held by the scripts as long as
537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// they are used. When they are not used anymore, the garbage
538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// collector will call the weak callback on the global handle
539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// associated with the wrapper and get rid of both the wrapper and the
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// handle.
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void ClearWrapperCache(Persistent<v8::Value> handle, void*) {
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_HEAP_PROTECTION
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Weak reference callbacks are called as if from outside V8.  We
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // need to reeenter to unprotect the heap.
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  VMState state(OTHER);
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> cache = Utils::OpenHandle(*handle);
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  JSValue* wrapper = JSValue::cast(*cache);
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Proxy* proxy = Script::cast(wrapper->value())->wrapper();
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ASSERT(proxy->proxy() == reinterpret_cast<Address>(cache.location()));
551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  proxy->set_proxy(0);
55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
55344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->global_handles()->Destroy(cache.location());
55444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->counters()->script_wrappers()->Decrement();
555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
557a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSValue> GetScriptWrapper(Handle<Script> script) {
559a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (script->wrapper()->proxy() != NULL) {
560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Return the script wrapper directly from the cache.
561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Handle<JSValue>(
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<JSValue**>(script->wrapper()->proxy()));
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
56444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = Isolate::Current();
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Construct a new script wrapper.
56644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->counters()->script_wrappers()->Increment();
56744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSFunction> constructor = isolate->script_function();
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<JSValue> result =
56944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor));
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  result->set_value(*script);
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Create a new weak global handle and use it to cache the wrapper
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // for future use. The cache will automatically be cleared by the
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // garbage collector when it is not used anymore.
57544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<Object> handle = isolate->global_handles()->Create(*result);
57644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->global_handles()->MakeWeak(handle.location(), NULL,
57744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                      &ClearWrapperCache);
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  script->wrapper()->set_proxy(reinterpret_cast<Address>(handle.location()));
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Init line_ends array with code positions of line ends inside script
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// source.
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid InitScriptLineEnds(Handle<Script> script) {
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!script->line_ends()->IsUndefined()) return;
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = script->GetIsolate();
58944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!script->source()->IsString()) {
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(script->source()->IsUndefined());
59244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FixedArray> empty = isolate->factory()->NewFixedArray(0);
5930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    script->set_line_ends(*empty);
594d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    ASSERT(script->line_ends()->IsFixedArray());
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
596a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
597a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
59844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<String> src(String::cast(script->source()), isolate);
5996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Handle<FixedArray> array = CalculateLineEnds(src, true);
6016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
60244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (*array != isolate->heap()->empty_fixed_array()) {
60344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    array->set_map(isolate->heap()->fixed_cow_array_map());
6048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
6058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  script->set_line_ends(*array);
6076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  ASSERT(script->line_ends()->IsFixedArray());
6086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
6096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6118a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangtemplate <typename SourceChar>
61244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic void CalculateLineEnds(Isolate* isolate,
61344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                              List<int>* line_ends,
6148a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                              Vector<const SourceChar> src,
6158a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                              bool with_last_line) {
6168a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  const int src_len = src.length();
61744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  StringSearch<char, SourceChar> search(isolate, CStrVector("\n"));
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6198a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Find and record line ends.
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int position = 0;
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (position != -1 && position < src_len) {
6228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    position = search.Search(src, position);
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (position != -1) {
6248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      line_ends->Add(position);
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      position++;
6268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    } else if (with_last_line) {
6276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      // Even if the last line misses a line end, it is counted.
6288a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      line_ends->Add(src_len);
6298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      return;
6306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6348a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
6358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) WangHandle<FixedArray> CalculateLineEnds(Handle<String> src,
6368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                                     bool with_last_line) {
6378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  src = FlattenGetString(src);
6388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Rough estimate of line count based on a roughly estimated average
6398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // length of (unpacked) code.
6408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  int line_count_estimate = src->length() >> 4;
6418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  List<int> line_ends(line_count_estimate);
64244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = src->GetIsolate();
6438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  {
6448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    AssertNoAllocation no_heap_allocation;  // ensure vectors stay valid.
6458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    // Dispatch on type of strings.
6468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    if (src->IsAsciiRepresentation()) {
64744f0eee88ff00398ff7f715fab053374d808c90dSteve Block      CalculateLineEnds(isolate,
64844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        &line_ends,
64944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        src->ToAsciiVector(),
65044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        with_last_line);
6518a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    } else {
65244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      CalculateLineEnds(isolate,
65344f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        &line_ends,
65444f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        src->ToUC16Vector(),
65544f0eee88ff00398ff7f715fab053374d808c90dSteve Block                        with_last_line);
6566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6588a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  int line_count = line_ends.length();
65944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<FixedArray> array = isolate->factory()->NewFixedArray(line_count);
6608a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  for (int i = 0; i < line_count; i++) {
6618a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    array->set(i, Smi::FromInt(line_ends[i]));
6628a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
6636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return array;
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Convert code position into line number.
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint GetScriptLineNumber(Handle<Script> script, int code_pos) {
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitScriptLineEnds(script);
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  AssertNoAllocation no_allocation;
671402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  FixedArray* line_ends_array = FixedArray::cast(script->line_ends());
672d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  const int line_ends_len = line_ends_array->length();
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6748a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if (!line_ends_len) return -1;
675402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
6768a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  if ((Smi::cast(line_ends_array->get(0)))->value() >= code_pos) {
677402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    return script->line_offset()->value();
6788a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  }
679402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
680402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int left = 0;
681402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  int right = line_ends_len;
682402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  while (int half = (right - left) / 2) {
683402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    if ((Smi::cast(line_ends_array->get(left + half)))->value() > code_pos) {
684402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      right -= half;
685402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    } else {
686402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu      left += half;
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
689402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return right + script->line_offset()->value();
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6936ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockint GetScriptLineNumberSafe(Handle<Script> script, int code_pos) {
6946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  AssertNoAllocation no_allocation;
6956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!script->line_ends()->IsUndefined()) {
6966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return GetScriptLineNumber(script, code_pos);
6976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
6986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Slow mode: we do not have line_ends. We have to iterate through source.
6996ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!script->source()->IsString()) {
7006ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return -1;
7016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
7026ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  String* source = String::cast(script->source());
7036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int line = 0;
7046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  int len = source->length();
7056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  for (int pos = 0; pos < len; pos++) {
7066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (pos == code_pos) {
7076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      break;
7086ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
7096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    if (source->Get(pos) == '\n') {
7106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      line++;
7116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    }
7126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
7136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return line;
7146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
7156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid CustomArguments::IterateInstance(ObjectVisitor* v) {
7186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  v->VisitPointers(values_, values_ + ARRAY_SIZE(values_));
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compute the property keys from the interceptor.
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver,
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                 Handle<JSObject> object) {
72544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = receiver->GetIsolate();
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
72744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CustomArguments args(isolate, interceptor->data(), *receiver, *object);
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::AccessorInfo info(args.end());
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::Handle<v8::Array> result;
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!interceptor->enumerator()->IsUndefined()) {
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::NamedPropertyEnumerator enum_fun =
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator());
73344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
73644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = enum_fun(info);
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Compute the element keys from the interceptor.
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver,
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                   Handle<JSObject> object) {
74744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = receiver->GetIsolate();
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor());
74944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  CustomArguments args(isolate, interceptor->data(), *receiver, *object);
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::AccessorInfo info(args.end());
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  v8::Handle<v8::Array> result;
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!interceptor->enumerator()->IsUndefined()) {
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::IndexedPropertyEnumerator enum_fun =
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator());
75544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    {
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Leaving JavaScript.
75844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      VMState state(isolate, EXTERNAL);
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      result = enum_fun(info);
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
766f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
767f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  int len = array->length();
768f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  for (int i = 0; i < len; i++) {
769f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    Object* e = array->get(i);
770f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    if (!(e->IsString() || e->IsNumber())) return false;
771f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
772f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return true;
773f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
774f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
775f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object,
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                          KeyCollectionType type) {
778f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  USE(ContainsOnlyValidKeys);
77944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = object->GetIsolate();
78044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<FixedArray> content = isolate->factory()->empty_fixed_array();
78144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSObject> arguments_boilerplate = Handle<JSObject>(
78244f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->context()->global_context()->arguments_boilerplate(),
78344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate);
78444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Handle<JSFunction> arguments_function = Handle<JSFunction>(
78544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      JSFunction::cast(arguments_boilerplate->map()->constructor()),
78644f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate);
787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Only collect keys if access is permitted.
789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (Handle<Object> p = object;
79044f0eee88ff00398ff7f715fab053374d808c90dSteve Block       *p != isolate->heap()->null_value();
79144f0eee88ff00398ff7f715fab053374d808c90dSteve Block       p = Handle<Object>(p->GetPrototype(), isolate)) {
79244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<JSObject> current(JSObject::cast(*p), isolate);
793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Check access rights if required.
795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current->IsAccessCheckNeeded() &&
79644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        !isolate->MayNamedAccess(*current,
79744f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                 isolate->heap()->undefined_value(),
79844f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                 v8::ACCESS_KEYS)) {
79944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->ReportFailedAccessCheck(*current, v8::ACCESS_KEYS);
800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Compute the element keys.
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<FixedArray> element_keys =
80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->factory()->NewFixedArray(current->NumberOfEnumElements());
806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    current->GetEnumElementKeys(*element_keys);
807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    content = UnionOfKeys(content, element_keys);
808f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    ASSERT(ContainsOnlyValidKeys(content));
809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Add the element keys from the interceptor.
811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current->HasIndexedInterceptor()) {
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::Handle<v8::Array> result =
813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          GetKeysForIndexedInterceptor(object, current);
814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!result.IsEmpty())
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
816f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      ASSERT(ContainsOnlyValidKeys(content));
817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
819d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // We can cache the computed property keys if access checks are
820d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // not needed and no interceptors are involved.
821d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    //
822d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // We do not use the cache if the object has elements and
823d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // therefore it does not make sense to cache the property names
824d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // for arguments objects.  Arguments objects will always have
825d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // elements.
82650ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    // Wrapped strings have elements, but don't have an elements
82750ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    // array or dictionary.  So the fast inline test for whether to
82850ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen    // use the cache says yes, so we should not create a cache.
829d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    bool cache_enum_keys =
830d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        ((current->map()->constructor() != *arguments_function) &&
83150ef84f5fad2def87d3fbc737bec4a32711fdef4Kristian Monsen         !current->IsJSValue() &&
832d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block         !current->IsAccessCheckNeeded() &&
833d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block         !current->HasNamedInterceptor() &&
834d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block         !current->HasIndexedInterceptor());
835d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Compute the property keys and cache them if possible.
836d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    content =
837d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        UnionOfKeys(content, GetEnumPropertyKeys(current, cache_enum_keys));
838f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    ASSERT(ContainsOnlyValidKeys(content));
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Add the property keys from the interceptor.
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (current->HasNamedInterceptor()) {
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      v8::Handle<v8::Array> result =
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          GetKeysForNamedInterceptor(object, current);
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!result.IsEmpty())
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result));
846f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      ASSERT(ContainsOnlyValidKeys(content));
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If we only want local properties we bail out after the first
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // iteration.
851a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (type == LOCAL_ONLY)
852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      break;
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return content;
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<JSArray> GetKeysFor(Handle<JSObject> object) {
85944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = object->GetIsolate();
86044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->counters()->for_in()->Increment();
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> elements = GetKeysInFixedArrayFor(object,
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                                       INCLUDE_PROTOS);
86344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return isolate->factory()->NewJSArrayWithElements(elements);
864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
867d0582a6c46733687d045e4188a1bcd0123c758a1Steve BlockHandle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object,
868d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                                       bool cache_result) {
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int index = 0;
87044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Isolate* isolate = object->GetIsolate();
871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (object->HasFastProperties()) {
872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (object->map()->instance_descriptors()->HasEnumCache()) {
87344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->counters()->enum_cache_hits()->Increment();
874a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      DescriptorArray* desc = object->map()->instance_descriptors();
87544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache()),
87644f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                isolate);
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
87844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->counters()->enum_cache_misses()->Increment();
879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int num_enum = object->NumberOfEnumProperties();
88044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
88144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FixedArray> sort_array = isolate->factory()->NewFixedArray(num_enum);
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Handle<DescriptorArray> descs =
88344f0eee88ff00398ff7f715fab053374d808c90dSteve Block        Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < descs->number_of_descriptors(); i++) {
885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (descs->IsProperty(i) && !descs->IsDontEnum(i)) {
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (*storage)->set(index, descs->GetKey(i));
887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        PropertyDetails details(descs->GetDetails(i));
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        (*sort_array)->set(index, Smi::FromInt(details.index()));
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        index++;
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    (*storage)->SortPairs(*sort_array, sort_array->length());
893d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (cache_result) {
894d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      Handle<FixedArray> bridge_storage =
89544f0eee88ff00398ff7f715fab053374d808c90dSteve Block          isolate->factory()->NewFixedArray(
89644f0eee88ff00398ff7f715fab053374d808c90dSteve Block              DescriptorArray::kEnumCacheBridgeLength);
897d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      DescriptorArray* desc = object->map()->instance_descriptors();
898d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      desc->SetEnumCache(*bridge_storage, *storage);
899d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    ASSERT(storage->length() == index);
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return storage;
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    int num_enum = object->NumberOfEnumProperties();
90444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
90544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    Handle<FixedArray> sort_array = isolate->factory()->NewFixedArray(num_enum);
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    object->property_dictionary()->CopyEnumKeysTo(*storage, *sort_array);
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return storage;
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9124515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool EnsureCompiled(Handle<SharedFunctionInfo> shared,
9134515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                    ClearExceptionFlag flag) {
9144515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  return shared->is_compiled() || CompileLazyShared(shared, flag);
9154515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke}
9164515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
9174515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
9184515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkestatic bool CompileLazyHelper(CompilationInfo* info,
9194515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                              ClearExceptionFlag flag) {
920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compile the source information to a code object.
921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(info->IsOptimizing() || !info->shared_info()->is_compiled());
92244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(!info->isolate()->has_pending_exception());
9234515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  bool result = Compiler::CompileLazy(info);
92444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ASSERT(result != Isolate::Current()->has_pending_exception());
92544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!result && flag == CLEAR_EXCEPTION) {
92644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    info->isolate()->clear_pending_exception();
92744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
9324515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool CompileLazyShared(Handle<SharedFunctionInfo> shared,
9334515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                       ClearExceptionFlag flag) {
9343100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  CompilationInfo info(shared);
9354515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  return CompileLazyHelper(&info, flag);
9364515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke}
9374515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
9384515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke
939e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochstatic bool CompileLazyFunction(Handle<JSFunction> function,
940e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                ClearExceptionFlag flag,
941e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                                InLoopFlag in_loop_flag) {
942b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool result = true;
943756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (function->shared()->is_compiled()) {
944b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    function->ReplaceCode(function->shared()->code());
945756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    function->shared()->set_code_age(0);
946756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  } else {
947f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    CompilationInfo info(function);
948e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch    if (in_loop_flag == IN_LOOP) info.MarkAsInLoop();
949b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    result = CompileLazyHelper(&info, flag);
950f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    ASSERT(!result || function->is_compiled());
951b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
952b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return result;
953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
956e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochbool CompileLazy(Handle<JSFunction> function,
957e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                 ClearExceptionFlag flag) {
958e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return CompileLazyFunction(function, flag, NOT_IN_LOOP);
959e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch}
960e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
961e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
9624515c472dc3e5ed2448a564600976759e569a0a8Leon Clarkebool CompileLazyInLoop(Handle<JSFunction> function,
9634515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke                       ClearExceptionFlag flag) {
964e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return CompileLazyFunction(function, flag, IN_LOOP);
965b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
966b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
967b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
968e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdochbool CompileOptimized(Handle<JSFunction> function,
969e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                      int osr_ast_id,
970e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch                      ClearExceptionFlag flag) {
971b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  CompilationInfo info(function);
972b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  info.SetOptimizing(osr_ast_id);
973e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch  return CompileLazyHelper(&info, flag);
974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
977