13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/api.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
73ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#include <string.h>  // For memcpy, strlen.
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef V8_USE_ADDRESS_SANITIZER
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <sanitizer/asan_interface.h>
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // V8_USE_ADDRESS_SANITIZER
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <cmath>  // For isnan.
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-debug.h"
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-profiler.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "include/v8-testing.h"
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/assert-scope.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/background-parsing-task.h"
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/platform.h"
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/platform/time.h"
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/utils/random-number-generator.h"
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bootstrapper.h"
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/code-stubs.h"
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler.h"
23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/conversions-inl.h"
24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/counters.h"
25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/cpu-profiler.h"
26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/debug.h"
27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h"
28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/execution.h"
29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/global-handles.h"
30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap-profiler.h"
31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/heap-snapshot-generator-inl.h"
32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/icu_util.h"
33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/json-parser.h"
34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/messages.h"
35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/natives.h"
36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/parser.h"
37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/profile-generator-inl.h"
38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/property.h"
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/property-details.h"
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/prototype.h"
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime.h"
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/runtime-profiler.h"
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/scanner-character-streams.h"
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/simulator.h"
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/snapshot.h"
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/unicode-inl.h"
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/v8threads.h"
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/version.h"
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/vm-state-inl.h"
50a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
51a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5244f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ENTER_V8(isolate)                                          \
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((isolate)->IsInitialized());                              \
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::VMState<i::OTHER> __state__((isolate))
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6044f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define ON_BAILOUT(isolate, location, code)                        \
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsExecutionTerminatingCheck(isolate)) {                      \
62f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    code;                                                          \
63f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke    UNREACHABLE();                                                 \
64a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
65a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
66a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6744f0eee88ff00398ff7f715fab053374d808c90dSteve Block#define EXCEPTION_PREAMBLE(isolate)                                         \
6844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  (isolate)->handle_scope_implementer()->IncrementCallDepth();              \
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!(isolate)->external_caught_exception());                          \
70a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool has_pending_exception = false
71a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
72a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback)           \
74a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  do {                                                                         \
7544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    i::HandleScopeImplementer* handle_scope_implementer =                      \
7644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        (isolate)->handle_scope_implementer();                                 \
7744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    handle_scope_implementer->DecrementCallDepth();                            \
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (has_pending_exception) {                                               \
7944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();   \
8044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      (isolate)->OptionalRescheduleException(call_depth_is_zero);              \
813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      do_callback                                                              \
82a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return value;                                                            \
83a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }                                                                          \
843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    do_callback                                                                \
85a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } while (false)
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value)                    \
893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  EXCEPTION_BAILOUT_CHECK_GENERIC(                                             \
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, value, isolate->FireCallCompletedCallback();)
913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#define EXCEPTION_BAILOUT_CHECK(isolate, value)                                \
943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
97a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- E x c e p t i o n   B e h a v i o r ---
98a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
99a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangvoid i::FatalProcessOutOfMemory(const char* location) {
1018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::V8::FatalProcessOutOfMemory(location, false);
1028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
1038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The default fatal error handler is called and execution is stopped.
107bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdochvoid i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
108d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  i::HeapStats heap_stats;
109d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int start_marker;
110d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.start_marker = &start_marker;
111d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int new_space_size;
112d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.new_space_size = &new_space_size;
113d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int new_space_capacity;
114d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.new_space_capacity = &new_space_capacity;
115f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t old_pointer_space_size;
116d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.old_pointer_space_size = &old_pointer_space_size;
117f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t old_pointer_space_capacity;
118d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
119f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t old_data_space_size;
120d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.old_data_space_size = &old_data_space_size;
121f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t old_data_space_capacity;
122d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.old_data_space_capacity = &old_data_space_capacity;
123f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t code_space_size;
124d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.code_space_size = &code_space_size;
125f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t code_space_capacity;
126d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.code_space_capacity = &code_space_capacity;
127f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t map_space_size;
128d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.map_space_size = &map_space_size;
129f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t map_space_capacity;
130d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.map_space_capacity = &map_space_capacity;
131f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t cell_space_size;
132d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.cell_space_size = &cell_space_size;
133f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t cell_space_capacity;
134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.cell_space_capacity = &cell_space_capacity;
135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t property_cell_space_size;
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_stats.property_cell_space_size = &property_cell_space_size;
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  intptr_t property_cell_space_capacity;
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_stats.property_cell_space_capacity = &property_cell_space_capacity;
139f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t lo_space_size;
140d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.lo_space_size = &lo_space_size;
141d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int global_handle_count;
142d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.global_handle_count = &global_handle_count;
143d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int weak_global_handle_count;
144d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.weak_global_handle_count = &weak_global_handle_count;
145d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int pending_global_handle_count;
146d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.pending_global_handle_count = &pending_global_handle_count;
147d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int near_death_global_handle_count;
148d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
1493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int free_global_handle_count;
1503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  heap_stats.free_global_handle_count = &free_global_handle_count;
151f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t memory_allocator_size;
152bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  heap_stats.memory_allocator_size = &memory_allocator_size;
153f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  intptr_t memory_allocator_capacity;
154bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
155bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  int objects_per_type[LAST_TYPE + 1] = {0};
156bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  heap_stats.objects_per_type = objects_per_type;
157bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  int size_per_type[LAST_TYPE + 1] = {0};
158bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  heap_stats.size_per_type = size_per_type;
159756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  int os_error;
160756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  heap_stats.os_error = &os_error;
161d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  int end_marker;
162d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  heap_stats.end_marker = &end_marker;
16344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate->heap()->HasBeenSetUp()) {
165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // BUG(1718): Don't use the take_snapshot since we don't support
166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // HeapIterator here without doing a special GC.
167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->heap()->RecordStats(&heap_stats, false);
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(false, location, "Allocation failed - process out of memory");
170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the fatal error handler returns, we stop execution.
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FATAL("API fatal error handler returned after process out of memory");
172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Utils::ReportApiFailure(const char* location, const char* message) {
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  FatalErrorCallback callback = isolate->exception_behavior();
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (callback == NULL) {
179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         message);
181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    base::OS::Abort();
182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    callback(location, message);
184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->SignalFatalError();
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool V8::IsDead() {
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->IsDead();
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
19544f0eee88ff00398ff7f715fab053374d808c90dSteve Blockstatic inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
19644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!isolate->IsInitialized()) return false;
19744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (isolate->has_scheduled_exception()) {
19844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return isolate->scheduled_exception() ==
19944f0eee88ff00398ff7f715fab053374d808c90dSteve Block        isolate->heap()->termination_exception();
20044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
20144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return false;
20244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
20344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
20444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
2053fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochStartupDataDecompressor::StartupDataDecompressor()
2063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
2073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
2083fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    raw_data[i] = NULL;
2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2123fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2133fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochStartupDataDecompressor::~StartupDataDecompressor() {
2143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
2153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    i::DeleteArray(raw_data[i]);
2163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
2173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::DeleteArray(raw_data);
2183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
2193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint StartupDataDecompressor::Decompress() {
2223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  int compressed_data_count = V8::GetCompressedStartupDataCount();
2233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  StartupData* compressed_data =
2243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::NewArray<StartupData>(compressed_data_count);
2253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V8::GetCompressedStartupData(compressed_data);
2263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  for (int i = 0; i < compressed_data_count; ++i) {
2273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    char* decompressed = raw_data[i] =
2283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        i::NewArray<char>(compressed_data[i].raw_size);
2293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    if (compressed_data[i].compressed_size != 0) {
2303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      int result = DecompressData(decompressed,
2313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                  &compressed_data[i].raw_size,
2323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                  compressed_data[i].data,
2333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                                  compressed_data[i].compressed_size);
2343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      if (result != 0) return result;
2353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    } else {
236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK_EQ(0, compressed_data[i].raw_size);
2373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    }
2383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    compressed_data[i].data = decompressed;
2393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
2403fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  V8::SetDecompressedStartupData(compressed_data);
2413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::DeleteArray(compressed_data);
2423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return 0;
2433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
2443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
246257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochStartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
247257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2
248257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return StartupData::kBZip2;
249257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else
250257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return StartupData::kUncompressed;
251257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
252257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
253257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
254257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
255257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochenum CompressedStartupDataItems {
256257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  kSnapshot = 0,
257257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  kSnapshotContext,
2583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  kLibraries,
2593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  kExperimentalLibraries,
260257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  kCompressedStartupDataCount
261257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch};
262257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
264257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochint V8::GetCompressedStartupDataCount() {
265257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2
266257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return kCompressedStartupDataCount;
267257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#else
268257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return 0;
269257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
270257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
271257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
272257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
273257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid V8::GetCompressedStartupData(StartupData* compressed_data) {
274257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2
275257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  compressed_data[kSnapshot].data =
276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      reinterpret_cast<const char*>(i::Snapshot::data());
277257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
278257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  compressed_data[kSnapshotContext].data =
281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      reinterpret_cast<const char*>(i::Snapshot::context_data());
282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  compressed_data[kSnapshotContext].compressed_size =
283257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      i::Snapshot::context_size();
284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
2853fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2863fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
2873fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  compressed_data[kLibraries].data =
2883fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      reinterpret_cast<const char*>(libraries_source.start());
2893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  compressed_data[kLibraries].compressed_size = libraries_source.length();
2903fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
2913fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Vector<const i::byte> exp_libraries_source =
2933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::ExperimentalNatives::GetScriptsSource();
2943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  compressed_data[kExperimentalLibraries].data =
2953fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      reinterpret_cast<const char*>(exp_libraries_source.start());
2963fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  compressed_data[kExperimentalLibraries].compressed_size =
2973fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      exp_libraries_source.length();
2983fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  compressed_data[kExperimentalLibraries].raw_size =
2993fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::ExperimentalNatives::GetRawScriptsSize();
300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
301257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
302257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
303257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
304257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid V8::SetDecompressedStartupData(StartupData* decompressed_data) {
305257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#ifdef COMPRESS_STARTUP_DATA_BZ2
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
307257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Snapshot::set_raw_data(
308257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
309257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(i::Snapshot::context_raw_size(),
311257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch            decompressed_data[kSnapshotContext].raw_size);
312257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Snapshot::set_context_raw_data(
313257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      reinterpret_cast<const i::byte*>(
314257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          decompressed_data[kSnapshotContext].data));
3153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(i::Natives::GetRawScriptsSize(),
3173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            decompressed_data[kLibraries].raw_size);
3183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Vector<const char> libraries_source(
3193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      decompressed_data[kLibraries].data,
3203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      decompressed_data[kLibraries].raw_size);
3213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Natives::SetRawScriptsSource(libraries_source);
3223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
3243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch            decompressed_data[kExperimentalLibraries].raw_size);
3253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Vector<const char> exp_libraries_source(
3263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      decompressed_data[kExperimentalLibraries].data,
3273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      decompressed_data[kExperimentalLibraries].raw_size);
3283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
329257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch#endif
330257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
331257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
332257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::SetNativesDataBlob(StartupData* natives_blob) {
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef V8_USE_EXTERNAL_STARTUP_DATA
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::SetNativesFromFile(natives_blob);
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(false);
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef V8_USE_EXTERNAL_STARTUP_DATA
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::SetSnapshotFromFile(snapshot_blob);
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(false);
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
35144f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid V8::SetFatalErrorHandler(FatalErrorCallback that) {
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
35344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->set_exception_behavior(that);
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid V8::SetAllowCodeGenerationFromStringsCallback(
358257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    AllowCodeGenerationFromStringsCallback callback) {
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
360257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  isolate->set_allow_code_gen_callback(callback);
361257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
362257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
363257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid V8::SetFlagsFromString(const char* str, int length) {
365a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::FlagList::SetFlagsFromString(str, length);
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegisteredExtension* RegisteredExtension::first_extension_ = NULL;
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockRegisteredExtension::RegisteredExtension(Extension* extension)
3783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    : extension_(extension) { }
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegisteredExtension::Register(RegisteredExtension* that) {
38244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  that->next_ = first_extension_;
38344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  first_extension_ = that;
384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisteredExtension::UnregisterAll() {
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  RegisteredExtension* re = first_extension_;
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (re != NULL) {
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RegisteredExtension* next = re->next();
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete re;
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    re = next;
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  first_extension_ = NULL;
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid RegisterExtension(Extension* that) {
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegisteredExtension* extension = new RegisteredExtension(that);
400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  RegisteredExtension::Register(extension);
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockExtension::Extension(const char* name,
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     const char* source,
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                     int dep_count,
4073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     const char** deps,
4083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     int source_length)
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    : name_(name),
4103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      source_length_(source_length >= 0 ?
4113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     source_length :
4123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                     (source ? static_cast<int>(strlen(source)) : 0)),
4133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      source_(source, source_length_),
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      dep_count_(dep_count),
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      deps_(deps),
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      auto_enable_(false) {
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(source != NULL || source_length_ == 0);
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochResourceConstraints::ResourceConstraints()
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : max_semi_space_size_(0),
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_old_space_size_(0),
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_executable_size_(0),
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      stack_limit_(NULL),
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_available_threads_(0),
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code_range_size_(0) { }
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            uint64_t virtual_memory_limit,
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            uint32_t number_of_processors) {
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#if V8_OS_ANDROID
433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Android has higher physical memory requirements before raising the maximum
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // heap size limits since it has no swap space.
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint64_t low_limit = 512ul * i::MB;
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint64_t medium_limit = 1ul * i::GB;
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint64_t high_limit = 2ul * i::GB;
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#else
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint64_t low_limit = 512ul * i::MB;
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint64_t medium_limit = 768ul * i::MB;
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const uint64_t high_limit = 1ul  * i::GB;
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (physical_memory <= low_limit) {
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice);
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (physical_memory <= medium_limit) {
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice);
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (physical_memory <= high_limit) {
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice);
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice);
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
46044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u));
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Reserve no more than 1/8 of the memory for the code range, but at most
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // kMaximalCodeRangeSize.
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_code_range_size(
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Min(i::kMaximalCodeRangeSize / i::MB,
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               static_cast<size_t>((virtual_memory_limit >> 3) / i::MB)));
47044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid SetResourceConstraints(i::Isolate* isolate,
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            const ResourceConstraints& constraints) {
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int semi_space_size = constraints.max_semi_space_size();
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int old_space_size = constraints.max_old_space_size();
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int max_executable_size = constraints.max_executable_size();
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t code_range_size = constraints.code_range_size();
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (semi_space_size != 0 || old_space_size != 0 ||
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      max_executable_size != 0 || code_range_size != 0) {
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->heap()->ConfigureHeap(semi_space_size, old_space_size,
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   max_executable_size, code_range_size);
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (constraints.stack_limit() != NULL) {
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
48744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->stack_guard()->SetStackLimit(limit);
488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->set_max_available_threads(constraints.max_available_threads());
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochi::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
49544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "Persistent::New");
496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  (*obj)->ObjectVerify();
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result.location();
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochi::Object** V8::CopyPersistent(i::Object** obj) {
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  (*obj)->ObjectVerify();
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif  // DEBUG
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result.location();
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::MakeWeak(i::Object** object,
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  void* parameters,
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  WeakCallback weak_callback) {
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::GlobalHandles::MakeWeak(object, parameters, weak_callback);
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* V8::ClearWeak(i::Object** obj) {
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::GlobalHandles::ClearWeakness(obj);
522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
523257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
524257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::DisposeGlobal(i::Object** obj) {
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::GlobalHandles::Destroy(obj);
527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Object* object = *Utils::OpenHandle(value);
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->eternal_handles()->Create(isolate, object, index);
534a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
535a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
536a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(isolate->eternal_handles()->Get(index));
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- H a n d l e s ---
544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandleScope::HandleScope(Isolate* isolate) {
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Initialize(isolate);
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HandleScope::Initialize(Isolate* isolate) {
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not want to check the correct usage of the Locker class all over the
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // place, so we do it only here: Without a HandleScope, an embedder can do
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // almost nothing, so it is enough to check in this central place.
556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(!v8::Locker::IsActive() ||
557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  internal_isolate->thread_manager()->IsLockedByCurrentThread(),
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "HandleScope::HandleScope",
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Entering the V8 API without proper locking in place");
560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScopeData* current = internal_isolate->handle_scope_data();
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_ = internal_isolate;
56244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  prev_next_ = current->next;
56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  prev_limit_ = current->limit;
56444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  current->level++;
565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandleScope::~HandleScope() {
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint HandleScope::NumberOfHandles(Isolate* isolate) {
574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::HandleScope::NumberOfHandles(
575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::Isolate*>(isolate));
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5775913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochi::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::HandleScope::CreateHandle(isolate, value);
5815913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck}
5825913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
5835913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochi::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      i::Object* value) {
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(heap_object->IsHeapObject());
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochEscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Initialize(v8_isolate);
59544f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
59644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
59744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochi::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(*escape_slot_ == heap->the_hole_value(),
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "EscapeableHandleScope::Escape",
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Escape value set twice");
603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (escape_value == NULL) {
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *escape_slot_ = heap->undefined_value();
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  *escape_slot_ = *escape_value;
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return escape_slot_;
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Context::Enter() {
6133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Context> env = Utils::OpenHandle(this);
6143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Isolate* isolate = env->GetIsolate();
61544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  impl->EnterContext(env);
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  impl->SaveContext(isolate->context());
61944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->set_context(*env);
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Context::Exit() {
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> env = Utils::OpenHandle(this);
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = env->GetIsolate();
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Context::Exit()",
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "Cannot exit non-entered context")) {
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  impl->LeaveContext();
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->set_context(impl->RestoreContext());
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void* DecodeSmiToAligned(i::Object* value, const char* location) {
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<void*>(value);
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Smi* smi = reinterpret_cast<i::Smi*>(value);
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return smi;
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                int index,
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                bool can_grow,
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                const char* location) {
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> env = Utils::OpenHandle(context);
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool ok =
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::ApiCheck(env->IsNativeContext(),
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      location,
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      "Not a native context") &&
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::ApiCheck(index >= 0, location, "Negative index");
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!ok) return i::Handle<i::FixedArray>();
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> data(env->embedder_data());
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (index < data->length()) return data;
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::Handle<i::FixedArray>();
66644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int new_size = i::Max(index, data->length() << 1) + 1;
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data = i::FixedArray::CopySize(data, new_size);
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  env->set_embedder_data(*data);
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return data;
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Context::GetEmbedderData()";
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.is_null()) return Local<Value>();
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result(data->get(index), data->GetIsolate());
679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Context::SetEmbedderData(int index, v8::Handle<Value> value) {
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Context::SetEmbedderData()";
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.is_null()) return;
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> val = Utils::OpenHandle(*value);
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data->set(index, *val);
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(*Utils::OpenHandle(*value),
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            *Utils::OpenHandle(*GetEmbedderData(index)));
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.is_null()) return NULL;
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DecodeSmiToAligned(data->get(index), location);
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7016ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Context::SetAlignedPointerInEmbedderData(int index, void* value) {
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data->set(index, EncodeAlignedAsSmi(value, location));
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- N e a n d e r ---
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A constructor cannot easily return an error value, therefore it is necessary
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to check for a dead VM with ON_BAILOUT before constructing any Neander
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// objects.  To remind you about this there is no HandleScope in the
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// NeanderObject constructor.  When you add one to the site calling the
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// constructor you should check that you ensured the VM was not dead first.
718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) {
71944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
72044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  value_ = isolate->factory()->NewNeanderObject();
72144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  value_->set_elements(*elements);
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint NeanderObject::size() {
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return i::FixedArray::cast(value_->elements())->length();
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochNeanderArray::NeanderArray(v8::internal::Isolate* isolate) : obj_(isolate, 2) {
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj_.set(0, i::Smi::FromInt(0));
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint NeanderArray::length() {
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return i::Smi::cast(obj_.get(0))->value();
738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocki::Object* NeanderArray::get(int offset) {
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(0 <= offset);
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(offset < length());
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return obj_.get(offset + 1);
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// This method cannot easily return an error value, therefore it is necessary
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// to check for a dead VM with ON_BAILOUT before calling it.  To remind you
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// about this there is no HandleScope in this method.  When you add one to the
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// site calling this method you should check that you ensured the VM was not
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// dead first.
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NeanderArray::add(i::Handle<i::Object> value) {
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int length = this->length();
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size = obj_.size();
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (length == size - 1) {
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Factory* factory = i::Isolate::Current()->factory();
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < length; i++)
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      new_elms->set(i + 1, get(i));
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    obj_.value()->set_elements(*new_elms);
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj_.set(length + 1, *value);
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj_.set(0, i::Smi::FromInt(length + 1));
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid NeanderArray::set(int index, i::Object* value) {
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (index < 0 || index >= this->length()) return;
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj_.set(index + 1, value);
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- T e m p l a t e ---
775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  that->set_tag(i::Smi::FromInt(type));
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void TemplateSet(i::Isolate* isolate,
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        v8::Template* templ,
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        int length,
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        v8::Handle<v8::Data>* data) {
786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (list->IsUndefined()) {
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    list = NeanderArray(isolate).value();
789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Utils::OpenHandle(templ)->set_property_list(*list);
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NeanderArray array(list);
792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.add(isolate->factory()->NewNumberFromInt(length));
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < length; i++) {
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> value = data[i].IsEmpty() ?
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::Object>(isolate->factory()->undefined_value()) :
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Utils::OpenHandle(*data[i]);
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    array.add(value);
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Template::Set(v8::Handle<Name> name,
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   v8::Handle<Data> value,
804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                   v8::PropertyAttribute attribute) {
80544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
80644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
80744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kSize = 3;
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Handle<v8::Data> data[kSize] = {
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    name,
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value,
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Integer::New(v8_isolate, attribute)};
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TemplateSet(isolate, this, kSize, data);
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Template::SetAccessorProperty(
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<v8::Name> name,
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<FunctionTemplate> getter,
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<FunctionTemplate> setter,
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::PropertyAttribute attribute,
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::AccessControl access_control) {
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(verwaest): Remove |access_control|.
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(v8::DEFAULT, access_control);
826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!name.IsEmpty());
829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int kSize = 5;
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Handle<v8::Data> data[kSize] = {
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    name,
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    getter,
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    setter,
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Integer::New(v8_isolate, attribute)};
838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TemplateSet(isolate, this, kSize, data);
839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- F u n c t i o n   T e m p l a t e ---
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic void InitializeFunctionTemplate(
844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::FunctionTemplateInfo> info) {
845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  info->set_flag(0);
847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              i_isolate);
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsUndefined()) {
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(i_isolate);
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = Utils::OpenHandle(*ObjectTemplate::New(isolate));
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Utils::OpenHandle(this)->set_prototype_template(*result);
859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<ObjectTemplate>(result);
861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
864a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
86544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
86644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Local<FunctionTemplate> FunctionTemplateNew(
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FunctionCallback callback,
874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Value> data,
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Signature> signature,
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int length,
877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool do_not_cache) {
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Struct> struct_obj =
87944f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::FunctionTemplateInfo> obj =
881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitializeFunctionTemplate(obj);
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_do_not_cache(do_not_cache);
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int next_serial_number = 0;
885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!do_not_cache) {
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_serial_number = isolate->next_serial_number() + 1;
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->set_next_serial_number(next_serial_number);
888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
88944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  obj->set_serial_number(i::Smi::FromInt(next_serial_number));
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (callback != 0) {
891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (data.IsEmpty()) {
892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Utils::ToLocal(obj)->SetCallHandler(callback, data);
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_length(length);
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_undetectable(false);
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_needs_access_check(false);
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!signature.IsEmpty())
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    obj->set_signature(*Utils::OpenHandle(*signature));
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(obj);
902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<FunctionTemplate> FunctionTemplate::New(
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FunctionCallback callback,
907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Value> data,
908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Signature> signature,
909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int length) {
910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "FunctionTemplate::New");
912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return FunctionTemplateNew(
914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate, callback, data, signature, length, false);
915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Signature> Signature::New(Isolate* isolate,
919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                Handle<FunctionTemplate> receiver, int argc,
920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                Handle<FunctionTemplate> argv[]) {
921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "Signature::New");
923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Struct> struct_obj =
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::SignatureInfo> obj =
927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::Handle<i::SignatureInfo>::cast(struct_obj);
928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (argc > 0) {
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::FixedArray> args = i_isolate->factory()->NewFixedArray(argc);
931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    for (int i = 0; i < argc; i++) {
932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!argv[i].IsEmpty())
933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        args->set(i, *Utils::OpenHandle(*argv[i]));
934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    obj->set_args(*args);
936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(obj);
938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<AccessorSignature> AccessorSignature::New(
942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<FunctionTemplate> receiver) {
944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename Operation>
949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Local<Operation> NewDescriptor(
950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const i::DeclaredAccessorDescriptorData& data,
952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Data* previous_descriptor) {
953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::DeclaredAccessorDescriptor> previous =
955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::DeclaredAccessorDescriptor>();
956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (previous_descriptor != NULL) {
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    previous = Utils::OpenHandle(
958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        static_cast<DeclaredAccessorDescriptor*>(previous_descriptor));
959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::DeclaredAccessorDescriptor> descriptor =
961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous);
962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::Convert<i::DeclaredAccessorDescriptor, Operation>(descriptor);
963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<RawOperationDescriptor>
967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochObjectOperationDescriptor::NewInternalFieldDereference(
968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int internal_field) {
970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeclaredAccessorDescriptorData data;
971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.type = i::kDescriptorObjectDereference;
972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.object_dereference_descriptor.internal_field = internal_field;
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewDescriptor<RawOperationDescriptor>(isolate, data, NULL);
974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<RawOperationDescriptor> RawOperationDescriptor::NewRawShift(
978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int16_t byte_offset) {
980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeclaredAccessorDescriptorData data;
981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.type = i::kDescriptorPointerShift;
982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.pointer_shift_descriptor.byte_offset = byte_offset;
983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<DeclaredAccessorDescriptor> RawOperationDescriptor::NewHandleDereference(
988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate) {
989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeclaredAccessorDescriptorData data;
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.type = i::kDescriptorReturnObject;
991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<RawOperationDescriptor> RawOperationDescriptor::NewRawDereference(
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate) {
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeclaredAccessorDescriptorData data;
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.type = i::kDescriptorPointerDereference;
999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPointerCompare(
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void* compare_value) {
1006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeclaredAccessorDescriptorData data;
1007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.type = i::kDescriptorPointerCompare;
1008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.pointer_compare_descriptor.compare_value = compare_value;
1009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPrimitiveValue(
1014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DeclaredAccessorDescriptorDataType data_type,
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint8_t bool_offset) {
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeclaredAccessorDescriptorData data;
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.type = i::kDescriptorPrimitiveValue;
1019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.primitive_value_descriptor.data_type = data_type;
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.primitive_value_descriptor.bool_offset = bool_offset;
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename T>
1026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Local<DeclaredAccessorDescriptor> NewBitmaskCompare(
1027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    T bitmask,
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    T compare_value,
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    RawOperationDescriptor* operation) {
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeclaredAccessorDescriptorData data;
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.type = i::kDescriptorBitmaskCompare;
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.bitmask_compare_descriptor.bitmask = bitmask;
1034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.bitmask_compare_descriptor.compare_value = compare_value;
1035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  data.bitmask_compare_descriptor.size = sizeof(T);
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, operation);
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare8(
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint8_t bitmask,
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint8_t compare_value) {
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare16(
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint16_t bitmask,
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint16_t compare_value) {
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare32(
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
1058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t bitmask,
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint32_t compare_value) {
1060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FunctionTemplate> types[1] = { type };
1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return TypeSwitch::New(1, types);
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
107144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
107244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "TypeSwitch::New");
107344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
107444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < argc; i++)
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    vector->set(i, *Utils::OpenHandle(*types[i]));
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Struct> struct_obj =
107844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::TypeSwitchInfo> obj =
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_types(*vector);
1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(obj);
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint TypeSwitch::match(v8::Handle<Value> value) {
108744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
108844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "TypeSwitch::match");
10893fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  USE(isolate);
1090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(*value);
1091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
1092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::FixedArray* types = i::FixedArray::cast(info->types());
1093a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < types->length(); i++) {
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return i + 1;
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return 0;
1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define SET_FIELD_WRAPPED(obj, setter, cdata) do {                      \
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    (obj)->setter(*foreign);                                            \
11040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  } while (false)
11050d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
11060d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FunctionTemplate::SetCallHandler(FunctionCallback callback,
1108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                      v8::Handle<Value> data) {
110944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
111044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
111144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
1112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Struct> struct_obj =
111344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::CallHandlerInfo> obj =
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::Handle<i::CallHandlerInfo>::cast(struct_obj);
11160d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  SET_FIELD_WRAPPED(obj, set_callback, callback);
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.IsEmpty()) {
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_data(*Utils::OpenHandle(*data));
1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Utils::OpenHandle(this)->set_call_code(*obj);
1122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::AccessorInfo> obj,
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Name> name,
1128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::AccessControl settings,
1129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::PropertyAttribute attributes,
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<AccessorSignature> signature) {
1131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_name(*Utils::OpenHandle(*name));
1132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
1134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!signature.IsEmpty()) {
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1138f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  return obj;
1139f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
1140f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename Getter, typename Setter>
1143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::AccessorInfo> MakeAccessorInfo(
1144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Name> name,
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Getter getter,
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Setter setter,
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Value> data,
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::AccessControl settings,
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::PropertyAttribute attributes,
1150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<AccessorSignature> signature) {
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::ExecutableAccessorInfo> obj =
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewExecutableAccessorInfo();
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SET_FIELD_WRAPPED(obj, set_getter, getter);
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SET_FIELD_WRAPPED(obj, set_setter, setter);
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.IsEmpty()) {
1157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1158f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_data(*Utils::OpenHandle(*data));
1160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1162f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::AccessorInfo> MakeAccessorInfo(
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Name> name,
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
1167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void* setter_ignored,
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void* data_ignored,
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::AccessControl settings,
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::PropertyAttribute attributes,
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<AccessorSignature> signature) {
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (descriptor.IsEmpty()) return i::Handle<i::DeclaredAccessorInfo>();
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::DeclaredAccessorInfo> obj =
1175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewDeclaredAccessorInfo();
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_descriptor(*Utils::OpenHandle(*descriptor));
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1180a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(!handle.is_null(),
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::FunctionTemplate::InstanceTemplate()",
1185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "Reading from empty handle")) {
1186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Local<ObjectTemplate>();
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = handle->GetIsolate();
118944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (handle->instance_template()->IsUndefined()) {
1191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Local<ObjectTemplate> templ =
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    handle->set_instance_template(*Utils::OpenHandle(*templ));
1194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::ObjectTemplateInfo> result(
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::ObjectTemplateInfo::cast(handle->instance_template()));
1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FunctionTemplate::SetLength(int length) {
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::OpenHandle(this)->set_length(length);
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1208a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FunctionTemplate::SetClassName(Handle<String> name) {
120944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
121044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1211a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1212a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1213a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid FunctionTemplate::SetHiddenPrototype(bool value) {
121644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
121744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Utils::OpenHandle(this)->set_hidden_prototype(value);
1219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
122269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdochvoid FunctionTemplate::ReadOnlyPrototype() {
12233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
12243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ENTER_V8(isolate);
122569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Utils::OpenHandle(this)->set_read_only_prototype(true);
12263fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
12273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
12283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid FunctionTemplate::RemovePrototype() {
123044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
123144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::OpenHandle(this)->set_remove_prototype(true);
1233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --- O b j e c t T e m p l a t e ---
1237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<ObjectTemplate> ObjectTemplate::New(Isolate* isolate) {
1240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return New(reinterpret_cast<i::Isolate*>(isolate), Local<FunctionTemplate>());
1241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<ObjectTemplate> ObjectTemplate::New() {
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return New(i::Isolate::Current(), Local<FunctionTemplate>());
1246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1248a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<ObjectTemplate> ObjectTemplate::New(
1250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
1251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<FunctionTemplate> constructor) {
125244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "ObjectTemplate::New");
125344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Struct> struct_obj =
125544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
1256a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::ObjectTemplateInfo> obj =
1257a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1258a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1259a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!constructor.IsEmpty())
1260a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    obj->set_constructor(*Utils::OpenHandle(*constructor));
1261a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->set_internal_field_count(i::Smi::FromInt(0));
1262a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(obj);
1263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Ensure that the object template has a constructor.  If no
1267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// constructor is available we create one.
1268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
1270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectTemplate* object_template) {
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!obj ->IsUndefined()) {
1273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::Handle<i::FunctionTemplateInfo>(info, isolate);
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<FunctionTemplate> templ =
1277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  constructor->set_instance_template(*Utils::OpenHandle(object_template));
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::OpenHandle(object_template)->set_constructor(*constructor);
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return constructor;
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void AddPropertyToTemplate(
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::TemplateInfo> info,
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::AccessorInfo> obj) {
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = info->GetIsolate();
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> list(info->property_accessors(), isolate);
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (list->IsUndefined()) {
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    list = NeanderArray(isolate).value();
1292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    info->set_property_accessors(*list);
1293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NeanderArray array(list);
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  array.add(obj);
1296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Template* template_obj) {
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(template_obj);
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(dcarney): remove this with ObjectTemplate::SetAccessor
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectTemplate* object_template) {
1310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureConstructor(isolate, object_template);
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(object_template);
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename Getter, typename Setter, typename Data, typename Template>
1316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool TemplateSetAccessor(
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Template* template_obj,
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<Name> name,
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Getter getter,
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Setter setter,
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Data data,
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AccessControl settings,
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PropertyAttribute attribute,
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<AccessorSignature> signature) {
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      name, getter, setter, data, settings, attribute, signature);
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj.is_null()) return false;
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::TemplateInfo> info = GetTemplateInfo(isolate, template_obj);
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AddPropertyToTemplate(info, obj);
1333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Template::SetDeclaredAccessor(
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Local<Name> name,
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Local<DeclaredAccessorDescriptor> descriptor,
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    PropertyAttribute attribute,
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Local<AccessorSignature> signature,
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AccessControl settings) {
1343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* null = NULL;
1344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return TemplateSetAccessor(
1345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, descriptor, null, null, settings, attribute, signature);
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Template::SetNativeDataProperty(v8::Local<String> name,
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     AccessorGetterCallback getter,
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     AccessorSetterCallback setter,
1352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     v8::Handle<Value> data,
1353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     PropertyAttribute attribute,
1354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     v8::Local<AccessorSignature> signature,
1355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     AccessControl settings) {
1356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TemplateSetAccessor(
1357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, getter, setter, data, settings, attribute, signature);
1358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Template::SetNativeDataProperty(v8::Local<Name> name,
1362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     AccessorNameGetterCallback getter,
1363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     AccessorNameSetterCallback setter,
1364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     v8::Handle<Value> data,
1365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     PropertyAttribute attribute,
1366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     v8::Local<AccessorSignature> signature,
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     AccessControl settings) {
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TemplateSetAccessor(
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, getter, setter, data, settings, attribute, signature);
1370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ObjectTemplate::SetAccessor(v8::Handle<String> name,
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AccessorGetterCallback getter,
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AccessorSetterCallback setter,
1376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 v8::Handle<Value> data,
1377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                 AccessControl settings,
1378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 PropertyAttribute attribute,
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 v8::Handle<AccessorSignature> signature) {
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TemplateSetAccessor(
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, getter, setter, data, settings, attribute, signature);
1382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ObjectTemplate::SetAccessor(v8::Handle<Name> name,
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AccessorNameGetterCallback getter,
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AccessorNameSetterCallback setter,
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 v8::Handle<Value> data,
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AccessControl settings,
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 PropertyAttribute attribute,
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 v8::Handle<AccessorSignature> signature) {
1392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TemplateSetAccessor(
1393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, getter, setter, data, settings, attribute, signature);
1394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ObjectTemplate::SetNamedPropertyHandler(
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NamedPropertyGetterCallback getter,
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NamedPropertySetterCallback setter,
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NamedPropertyQueryCallback query,
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NamedPropertyDeleterCallback remover,
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NamedPropertyEnumeratorCallback enumerator,
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Value> data) {
140444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
140544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
140644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureConstructor(isolate, this);
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(this)->constructor());
1410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::FunctionTemplateInfo> cons(constructor);
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Struct> struct_obj =
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::InterceptorInfo> obj =
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::InterceptorInfo>::cast(struct_obj);
1415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.IsEmpty()) {
1423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_data(*Utils::OpenHandle(*data));
1426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cons->set_named_property_handler(*obj);
1427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ObjectTemplate::MarkAsUndetectable() {
143144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
143244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
143344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
1434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureConstructor(isolate, this);
1435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::FunctionTemplateInfo* constructor =
1436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::FunctionTemplateInfo> cons(constructor);
1438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  cons->set_undetectable(true);
1439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ObjectTemplate::SetAccessCheckCallbacks(
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    NamedSecurityCallback named_callback,
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IndexedSecurityCallback indexed_callback,
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Value> data,
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool turned_on_by_default) {
144744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
144844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
144944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureConstructor(isolate, this);
1451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Struct> struct_info =
145344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
1454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::AccessCheckInfo> info =
1455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::Handle<i::AccessCheckInfo>::cast(struct_info);
14560d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
14570d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
14580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
14590d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.IsEmpty()) {
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  info->set_data(*Utils::OpenHandle(*data));
1464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::FunctionTemplateInfo* constructor =
1466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::FunctionTemplateInfo> cons(constructor);
1468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  cons->set_access_check_info(*info);
1469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  cons->set_needs_access_check(turned_on_by_default);
1470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ObjectTemplate::SetIndexedPropertyHandler(
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IndexedPropertyGetterCallback getter,
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IndexedPropertySetterCallback setter,
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IndexedPropertyQueryCallback query,
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IndexedPropertyDeleterCallback remover,
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    IndexedPropertyEnumeratorCallback enumerator,
1479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<Value> data) {
148044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
148144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
148244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
1483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureConstructor(isolate, this);
1484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(this)->constructor());
1486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::FunctionTemplateInfo> cons(constructor);
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Struct> struct_obj =
1488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::InterceptorInfo> obj =
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::InterceptorInfo>::cast(struct_obj);
1491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.IsEmpty()) {
1499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_data(*Utils::OpenHandle(*data));
1502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cons->set_indexed_property_handler(*obj);
1503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
1507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                              Handle<Value> data) {
150844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
150944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
151044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EnsureConstructor(isolate, this);
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(this)->constructor());
1514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::FunctionTemplateInfo> cons(constructor);
1515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Struct> struct_obj =
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::CallHandlerInfo> obj =
1518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SET_FIELD_WRAPPED(obj, set_callback, callback);
1520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (data.IsEmpty()) {
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_data(*Utils::OpenHandle(*data));
1524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  cons->set_instance_call_handler(*obj);
1525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1528a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint ObjectTemplate::InternalFieldCount() {
1529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid ObjectTemplate::SetInternalFieldCount(int value) {
153444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(i::Smi::IsValid(value),
1536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::ObjectTemplate::SetInternalFieldCount()",
1537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "Invalid internal field count")) {
1538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
154044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (value > 0) {
1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // The internal field count is set by the constructor function's
1543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // construct code, so we ensure that there is a constructor
1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // function to do the setting.
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EnsureConstructor(isolate, this);
1546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --- S c r i p t s ---
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// JSFunction.
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       BufferPolicy buffer_policy_)
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : data(data_), length(length_), buffer_policy(buffer_policy_) {}
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochScriptCompiler::CachedData::~CachedData() {
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (buffer_policy == BufferOwned) {
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete[] data;
1565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Encoding encoding)
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : impl_(new i::StreamedSource(stream, encoding)) {}
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; }
1575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst ScriptCompiler::CachedData*
1578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochScriptCompiler::StreamedSource::GetCachedData() const {
1579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return impl_->cached_data.get();
1580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Script> UnboundScript::BindToCurrentContext() {
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::HeapObject> obj =
1585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::SharedFunctionInfo>
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> function =
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          function_info, obj->GetIsolate()->global_context());
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<Script>(function);
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint UnboundScript::GetId() {
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::HeapObject> obj =
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = obj->GetIsolate();
1599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::UnboundScript::GetId()", return -1);
1600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "v8::UnboundScript::GetId");
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  {
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::HandleScope scope(isolate);
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::SharedFunctionInfo> function_info(
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::SharedFunctionInfo::cast(*obj));
1605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return script->id()->value();
1607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint UnboundScript::GetLineNumber(int code_pos) {
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::SharedFunctionInfo> obj =
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = obj->GetIsolate();
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::UnboundScript::GetLineNumber()", return -1);
1616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "UnboundScript::GetLineNumber");
1617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->script()->IsScript()) {
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Script> script(i::Script::cast(obj->script()));
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::Script::GetLineNumber(script, code_pos);
1620b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
1621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return -1;
1622b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
16237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch}
16247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
16257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
1626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Value> UnboundScript::GetScriptName() {
1627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::SharedFunctionInfo> obj =
1628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = obj->GetIsolate();
1630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::UnboundScript::GetName()",
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             return Handle<String>());
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "UnboundScript::GetName");
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->script()->IsScript()) {
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Object* name = i::Script::cast(obj->script())->name();
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<String>();
1638f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke  }
1639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1641f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Value> UnboundScript::GetSourceURL() {
1643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::SharedFunctionInfo> obj =
1644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = obj->GetIsolate();
1646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceURL()",
1647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             return Handle<String>());
1648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "UnboundScript::GetSourceURL");
1649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->script()->IsScript()) {
1650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Object* url = i::Script::cast(obj->script())->source_url();
1651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<String>();
16549ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  }
1655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1657f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Value> UnboundScript::GetSourceMappingURL() {
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::SharedFunctionInfo> obj =
1660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = obj->GetIsolate();
1662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceMappingURL()",
1663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             return Handle<String>());
1664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->script()->IsScript()) {
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<String>();
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> Script::Run() {
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
1676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If execution is terminating, Compile(..)->Run() requires this
1677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // check.
1678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj.is_null()) return Local<Value>();
1679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Handle<i::HeapObject>::cast(obj)->GetIsolate();
1680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Script::Run");
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
1683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
1685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
1686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
1687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
1688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
1689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
1690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, fun, receiver, 0, NULL).ToHandle(&result);
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(scope.CloseAndEscape(result));
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<UnboundScript> Script::GetUnboundScript() {
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this);
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<UnboundScript>(
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<UnboundScript> ScriptCompiler::CompileUnbound(
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* v8_isolate,
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Source* source,
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CompileOptions options) {
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()",
1709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             return Local<UnboundScript>());
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Support the old API for a transition period:
1712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - kProduceToCache -> kProduceParserCache
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - kNoCompileOptions + cached_data != NULL -> kConsumeParserCache
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (options == kProduceDataToCache) {
1715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options = kProduceParserCache;
1716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (options == kNoCompileOptions && source->cached_data) {
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    options = kConsumeParserCache;
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::ScriptData* script_data = NULL;
1721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(source->cached_data);
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // ScriptData takes care of pointer-aligning the data.
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    script_data = new i::ScriptData(source->cached_data->data,
1725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    source->cached_data->length);
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "ScriptCompiler::CompileUnbound");
173044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1731692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  i::SharedFunctionInfo* raw_result = NULL;
1732692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  { i::HandleScope scope(isolate);
1733692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    i::Handle<i::Object> name_obj;
1734692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    int line_offset = 0;
1735692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    int column_offset = 0;
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool is_shared_cross_origin = false;
1737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!source->resource_name.IsEmpty()) {
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      name_obj = Utils::OpenHandle(*(source->resource_name));
1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!source->resource_line_offset.IsEmpty()) {
1741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      line_offset = static_cast<int>(source->resource_line_offset->Value());
1742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!source->resource_column_offset.IsEmpty()) {
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      column_offset =
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<int>(source->resource_column_offset->Value());
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!source->resource_is_shared_cross_origin.IsEmpty()) {
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
1749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_shared_cross_origin =
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          source->resource_is_shared_cross_origin == v8::True(v8_isolate);
1751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXCEPTION_PREAMBLE(isolate);
1753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript(
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        str, name_obj, line_offset, column_offset, is_shared_cross_origin,
1755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate->global_context(), NULL, &script_data, options,
1756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::NOT_NATIVES_CODE);
1757692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    has_pending_exception = result.is_null();
1758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (has_pending_exception && script_data != NULL) {
1759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // This case won't happen during normal operation; we have compiled
1760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // successfully and produced cached data, and but the second compilation
1761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // of the same source code fails.
1762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      delete script_data;
1763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      script_data = NULL;
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>());
1766692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch    raw_result = *result;
1767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((options == kProduceParserCache || options == kProduceCodeCache) &&
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        script_data != NULL) {
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // script_data now contains the data that was generated. source will
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // take the ownership.
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      source->cached_data = new CachedData(
1773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          script_data->data(), script_data->length(), CachedData::BufferOwned);
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      script_data->ReleaseDataOwnership();
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete script_data;
1777692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  }
1778692be65d6b06edd9ff4cfc4c308555b7c99c1191Ben Murdoch  i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<UnboundScript>(result);
1780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Script> ScriptCompiler::Compile(
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* v8_isolate,
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Source* source,
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CompileOptions options) {
1787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "ScriptCompiler::CompiletBound()");
179044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options);
1792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (generic.IsEmpty()) return Local<Script>();
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return generic->BindToCurrentContext();
1794a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1795a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!isolate->global_context().is_null() &&
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !isolate->global_context()->IsNativeContext()) {
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The context chain is non-trivial, and constructing the corresponding
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // non-trivial Scope chain outside the V8 heap is not implemented. Don't
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // stream the script. This will only occur if Harmony scoping is enabled and
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // a previous script has introduced "let" or "const" variables. TODO(marja):
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Implement externalizing ScopeInfos and constructing non-trivial Scope
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // chains independent of the V8 heap so that we can stream also in this
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // case.
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return new i::BackgroundParsingTask(source->impl(), options,
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      i::FLAG_stack_size, isolate);
1813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      StreamedSource* v8_source,
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      Handle<String> full_source_string,
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      const ScriptOrigin& origin) {
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::StreamedSource* source = v8_source->impl();
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "ScriptCompiler::Compile()");
182444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::SharedFunctionInfo* raw_result = NULL;
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
182844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    i::HandleScope scope(isolate);
1829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
1830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Script> script = isolate->factory()->NewScript(str);
1831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!origin.ResourceName().IsEmpty()) {
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!origin.ResourceLineOffset().IsEmpty()) {
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      script->set_line_offset(i::Smi::FromInt(
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<int>(origin.ResourceLineOffset()->Value())));
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!origin.ResourceColumnOffset().IsEmpty()) {
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      script->set_column_offset(i::Smi::FromInt(
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<int>(origin.ResourceColumnOffset()->Value())));
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) {
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      script->set_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin() ==
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         v8::True(v8_isolate));
1845a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    source->info->set_script(script);
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    source->info->SetContext(isolate->global_context());
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
184944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
1850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Do the parsing tasks which need to be done on the main thread. This will
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // also handle parse errors.
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    source->parser->Internalize();
1854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::SharedFunctionInfo> result =
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::SharedFunctionInfo>::null();
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (source->info->function() != NULL) {
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Parsing has succeeded.
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      result =
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          i::Compiler::CompileStreamedScript(source->info.get(), str->length());
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = result.is_null();
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (has_pending_exception) isolate->ReportPendingMessages();
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    raw_result = *result;
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The Handle<Script> will go out of scope soon; make sure CompilationInfo
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // doesn't point to it.
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    source->info->set_script(i::Handle<i::Script>());
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }  // HandleScope goes out of scope.
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (generic.IsEmpty()) {
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Local<Script>();
18756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return generic->BindToCurrentContext();
18776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
18786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
18796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Script> Script::Compile(v8::Handle<String> source,
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              v8::ScriptOrigin* origin) {
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(*source);
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (origin) {
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ScriptCompiler::Source script_source(source, *origin);
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ScriptCompiler::Compile(
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        &script_source);
1888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ScriptCompiler::Source script_source(source);
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ScriptCompiler::Compile(
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
1892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      &script_source);
1893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Script> Script::Compile(v8::Handle<String> source,
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              v8::Handle<String> file_name) {
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ScriptOrigin origin(file_name);
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Compile(source, &origin);
1900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- E x c e p t i o n s ---
1904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::TryCatch::TryCatch()
19073fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    : isolate_(i::Isolate::Current()),
1908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      next_(isolate_->try_catch_handler()),
1909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      is_verbose_(false),
1910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      can_continue_(true),
1911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      capture_message_(true),
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      rethrow_(false),
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      has_terminated_(false) {
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ResetInternal();
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Special handling for simulators which have a separate JS stack.
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  js_stack_comparable_address_ =
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          v8::internal::GetCurrentStackPosition()));
19193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  isolate_->RegisterTryCatchHandler(this);
1920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::TryCatch::~TryCatch() {
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ == i::Isolate::Current());
1925d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (rethrow_) {
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
1927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::HandleScope scope(isolate);
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HasCaught() && capture_message_) {
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // If an exception was caught and rethrow_ is indicated, the saved
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // message, script, and location need to be restored to Isolate TLS
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // for reuse.  capture_message_ needs to be disabled so that DoThrow()
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // does not create a new message.
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->thread_local_top()->rethrowing_message_ = true;
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->RestorePendingMessageFromTryCatch(this);
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
19373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    isolate_->UnregisterTryCatchHandler(this);
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::SimulatorStack::UnregisterCTryCatch();
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
1941d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  } else {
1942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (HasCaught() && isolate_->has_scheduled_exception()) {
1943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // If an exception was caught but is still scheduled because no API call
1944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // promoted it, then it is canceled to prevent it from being propagated.
1945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Note that this will not cancel termination exceptions.
1946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate_->CancelScheduledExceptionFromTryCatch(this);
1947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
19483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    isolate_->UnregisterTryCatchHandler(this);
1949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::internal::SimulatorStack::UnregisterCTryCatch();
1950d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
1951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::TryCatch::HasCaught() const {
1955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::TryCatch::CanContinue() const {
1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return can_continue_;
1961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::TryCatch::HasTerminated() const {
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return has_terminated_;
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1969d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockv8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1970d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (!HasCaught()) return v8::Local<v8::Value>();
1971d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  rethrow_ = true;
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
1973d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
1974d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1975d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<Value> v8::TryCatch::Exception() const {
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ == i::Isolate::Current());
1978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (HasCaught()) {
1979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Check for out of memory exception.
1980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i::Object* exception = reinterpret_cast<i::Object*>(exception_);
19813fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
1982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return v8::Local<Value>();
1984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<Value> v8::TryCatch::StackTrace() const {
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ == i::Isolate::Current());
1990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (HasCaught()) {
1991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!raw_obj->IsJSObject()) return v8::Local<Value>();
19933fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    i::HandleScope scope(isolate_);
19943fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::String> name = isolate_->factory()->stack_string();
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXCEPTION_PREAMBLE(isolate_);
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !maybe.has_value;
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXCEPTION_BAILOUT_CHECK(isolate_, v8::Local<Value>());
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!maybe.value) return v8::Local<Value>();
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> value;
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!i::Object::GetProperty(obj, name).ToHandle(&value)) {
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return v8::Local<Value>();
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
20053fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return v8::Utils::ToLocal(scope.CloseAndEscape(value));
2006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return v8::Local<Value>();
2008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Message> v8::TryCatch::Message() const {
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ == i::Isolate::Current());
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(message->IsJSMessageObject() || message->IsTheHole());
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasCaught() && !message->IsTheHole()) {
20173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
2018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return v8::Local<v8::Message>();
2020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::TryCatch::Reset() {
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate_ == i::Isolate::Current());
2026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If an exception was caught but is still scheduled because no API call
2028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // promoted it, then it is canceled to prevent it from being propagated.
2029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Note that this will not cancel termination exceptions.
2030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->CancelScheduledExceptionFromTryCatch(this);
2031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ResetInternal();
2033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::TryCatch::ResetInternal() {
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Object* the_hole = isolate_->heap()->the_hole_value();
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  exception_ = the_hole;
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  message_obj_ = the_hole;
2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  message_script_ = the_hole;
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  message_start_pos_ = 0;
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  message_end_pos_ = 0;
2043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::TryCatch::SetVerbose(bool value) {
2047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  is_verbose_ = value;
2048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::TryCatch::SetCaptureMessage(bool value) {
2052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  capture_message_ = value;
2053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- M e s s a g e ---
2057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<String> Message::Get() const {
206044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
206144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
206244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
2063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
2066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Local<String> result = Utils::ToLocal(raw_result);
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return scope.Escape(result);
2068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochScriptOrigin Message::GetScriptOrigin() const {
207244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
20731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  i::Handle<i::JSMessageObject> message =
20741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> script_wraper =
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::Object>(message->script(), isolate);
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSValue> script_value =
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::JSValue>::cast(script_wraper);
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Script> script(i::Script::cast(script_value->value()));
2080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Isolate* v8_isolate =
2082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<v8::Isolate*>(script->GetIsolate());
2083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::ScriptOrigin origin(
2084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::ToLocal(scriptName),
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::Integer::New(v8_isolate, script->line_offset()->value()),
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::Integer::New(v8_isolate, script->column_offset()->value()),
2087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Handle<Boolean>(),
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::Integer::New(v8_isolate, script->id()->value()));
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return origin;
2090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2091a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Handle<Value> Message::GetScriptResourceName() const {
2094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetScriptOrigin().ResourceName();
2095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
20983bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochv8::Handle<v8::StackTrace> Message::GetStackTrace() const {
209944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
210044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
21021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  i::Handle<i::JSMessageObject> message =
21031e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
21053bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
21063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  i::Handle<i::JSArray> stackTrace =
21073bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      i::Handle<i::JSArray>::cast(stackFramesObj);
2108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return scope.Escape(Utils::StackTraceToLocal(stackTrace));
21093bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
21103bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
21113bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
2113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* name,
2114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> recv,
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int argc,
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> argv[]) {
211744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> object_fun =
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetProperty(
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate, isolate->js_builtins_object(), name).ToHandleChecked();
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(object_fun);
2122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::Execution::Call(isolate, fun, recv, argc, argv);
2123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
2127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const char* name,
2128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> data) {
21293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::Object> argv[] = { data };
2130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return CallV8HeapFunction(name,
213144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                            i::Isolate::Current()->js_builtins_object(),
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            arraysize(argv),
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            argv);
2134a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Message::GetLineNumber() const {
213844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
213944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
214044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
214144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
21421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
214344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
2145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !CallV8HeapFunction(
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "GetLineNumber", Utils::OpenHandle(this)).ToHandle(&result);
214744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, 0);
2148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return static_cast<int>(result->Number());
2149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Message::GetStartPosition() const {
215344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
215444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
215544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
21561e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  i::Handle<i::JSMessageObject> message =
21571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
21581e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return message->start_position();
2159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Message::GetEndPosition() const {
216344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
216444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
216544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
21661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  i::Handle<i::JSMessageObject> message =
21671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
21681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return message->end_position();
2169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Message::GetStartColumn() const {
217344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Message::GetStartColumn()", return kNoColumnInfo);
217544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
217644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
2177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
217844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> start_col_obj;
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !CallV8HeapFunction(
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
218244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, 0);
2183a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return static_cast<int>(start_col_obj->Number());
2184a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint Message::GetEndColumn() const {
218844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Message::GetEndColumn()", return kNoColumnInfo);
219044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
219144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
2192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
219344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> start_col_obj;
2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !CallV8HeapFunction(
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
219744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, 0);
21981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  i::Handle<i::JSMessageObject> message =
21991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      i::Handle<i::JSMessageObject>::cast(data_obj);
22001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int start = message->start_position();
22011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  int end = message->end_position();
2202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return static_cast<int>(start_col_obj->Number()) + (end - start);
2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Message::IsSharedCrossOrigin() const {
2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSMessageObject> message =
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSValue> script =
2213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                       isolate));
2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::Script::cast(script->value())->is_shared_cross_origin();
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<String> Message::GetSourceLine() const {
222044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
222144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
222244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
222444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
2226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !CallV8HeapFunction(
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "GetSourceLine", Utils::OpenHandle(this)).ToHandle(&result);
222844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
2229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (result->IsString()) {
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
2231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Local<String>();
2233a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
2238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->PrintCurrentStackTrace(out);
2241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2243a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
224425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// --- S t a c k T r a c e ---
224525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
224625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenLocal<StackFrame> StackTrace::GetFrame(uint32_t index) const {
224744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
224844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
225025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  i::Handle<i::JSArray> self = Utils::OpenHandle(this);
2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj =
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetElement(isolate, self, index).ToHandleChecked();
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> jsobj = i::Handle<i::JSObject>::cast(obj);
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return scope.Escape(Utils::StackFrameToLocal(jsobj));
225525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
225625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
225725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
225825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenint StackTrace::GetFrameCount() const {
225944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
226044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
226125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
226225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
226325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
226425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
226525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenLocal<Array> StackTrace::AsArray() {
226644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
226744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
226825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  return Utils::ToLocal(Utils::OpenHandle(this));
226925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
227025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
227125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<StackTrace> StackTrace::CurrentStackTrace(
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int frame_limit,
227525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen    StackTraceOptions options) {
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(dcarney): remove when ScriptDebugServer is fixed.
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  options = static_cast<StackTraceOptions>(
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<int>(options) | kExposeFramesAcrossSecurityOrigins);
22813bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  i::Handle<i::JSArray> stackTrace =
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate->CaptureCurrentStackTrace(frame_limit, options);
22833bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch  return Utils::StackTraceToLocal(stackTrace);
228425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
228525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
228625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
228725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// --- S t a c k F r a m e ---
228825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic int getIntProperty(const StackFrame* f, const char* propertyName,
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          int defaultValue) {
2291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
229244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
229344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
2294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj =
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue;
2298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint StackFrame::GetLineNumber() const {
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo);
230325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
230425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
230525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
230625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenint StackFrame::GetColumn() const {
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return getIntProperty(this, "column", Message::kNoColumnInfo);
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint StackFrame::GetScriptId() const {
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo);
2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Local<String> getStringProperty(const StackFrame* f,
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       const char* propertyName) {
2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
231944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
2320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj =
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->IsString()
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             : Local<String>();
232725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
232825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
232925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
233025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenLocal<String> StackFrame::GetScriptName() const {
2331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return getStringProperty(this, "scriptName");
233225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
233325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
233425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
2335f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochLocal<String> StackFrame::GetScriptNameOrSourceURL() const {
2336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return getStringProperty(this, "scriptNameOrSourceURL");
2337f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
2338f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
2339f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
234025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian MonsenLocal<String> StackFrame::GetFunctionName() const {
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return getStringProperty(this, "functionName");
234225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
234325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
234425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool getBoolProperty(const StackFrame* f, const char* propertyName) {
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
234744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
234844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj =
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->IsTrue();
235325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
235425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
235725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
235825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenbool StackFrame::IsConstructor() const {
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return getBoolProperty(this, "isConstructor");
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --- J S O N ---
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> JSON::Parse(Local<String> json_string) {
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> string = Utils::OpenHandle(*json_string);
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = string->GetIsolate();
236844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
236944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> source = i::String::Flatten(string);
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::MaybeHandle<i::Object> maybe_result =
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      source->IsSeqOneByteString() ? i::JsonParser<true>::Parse(source)
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   : i::JsonParser<false>::Parse(source);
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !maybe_result.ToHandle(&result);
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
238025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen}
238125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
238225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
2383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- D a t a ---
2384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::FullIsUndefined() const {
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool result = Utils::OpenHandle(this)->IsUndefined();
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(result, QuickIsUndefined());
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::FullIsNull() const {
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool result = Utils::OpenHandle(this)->IsNull();
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(result, QuickIsNull());
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsTrue() const {
2400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsTrue();
2401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsFalse() const {
2405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsFalse();
2406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsFunction() const {
2410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsJSFunction();
2411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsName() const {
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsName();
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::FullIsString() const {
2420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result = Utils::OpenHandle(this)->IsString();
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(result, QuickIsString());
2422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
2423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsSymbol() const {
2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsSymbol();
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsArray() const {
2432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsJSArray();
2433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsArrayBuffer() const {
2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsJSArrayBuffer();
2438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsArrayBufferView() const {
2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsJSArrayBufferView();
2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsTypedArray() const {
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsJSTypedArray();
2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size)            \
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Value::Is##Type##Array() const {                                    \
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> obj = Utils::OpenHandle(this);                    \
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return obj->IsJSTypedArray() &&                                        \
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           i::JSTypedArray::cast(*obj)->type() == kExternal##Type##Array;  \
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef VALUE_IS_TYPED_ARRAY
2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsDataView() const {
2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsJSDataView();
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsObject() const {
2469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsJSObject();
2470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsNumber() const {
2474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsNumber();
2475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define VALUE_IS_SPECIFIC_TYPE(Type, Class)                            \
2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Value::Is##Type() const {                                       \
2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> obj = Utils::OpenHandle(this);                \
2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!obj->IsHeapObject()) return false;                            \
2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();     \
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
248444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(StringObject, String)
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(Date, Date)
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(Map, Map)
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(Set, Set)
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochVALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef VALUE_IS_SPECIFIC_TYPE
2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsBoolean() const {
2501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsBoolean();
2502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsExternal() const {
2506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsExternal();
2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::IsInt32() const {
2511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) return true;
2513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsNumber()) {
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::IsInt32Double(obj->Number());
2515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return false;
2517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
25206ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool Value::IsUint32() const {
25216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
25226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
25236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (obj->IsNumber()) {
25246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    double value = obj->Number();
2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !i::IsMinusZero(value) &&
2526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value >= 0 &&
2527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value <= i::kMaxUInt32 &&
2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        value == i::FastUI2D(i::FastD2UI(value));
25296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
25306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return false;
25316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
25326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
25336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
25343fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochstatic bool CheckConstructor(i::Isolate* isolate,
25353fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             i::Handle<i::JSObject> obj,
25363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch                             const char* class_name) {
2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> constr(obj->map()->constructor(), isolate);
2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!constr->IsJSFunction()) return false;
2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(constr);
2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return func->shared()->native() && constr.is_identical_to(
2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetProperty(isolate,
2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             isolate->js_builtins_object(),
2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                             class_name).ToHandleChecked());
25443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
25453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
25463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
25473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochbool Value::IsNativeError() const {
25483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this);
25493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (obj->IsJSObject()) {
25503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
2551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = js_obj->GetIsolate();
25523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return CheckConstructor(isolate, js_obj, "$Error") ||
25533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        CheckConstructor(isolate, js_obj, "$EvalError") ||
25543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        CheckConstructor(isolate, js_obj, "$RangeError") ||
25553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        CheckConstructor(isolate, js_obj, "$ReferenceError") ||
25563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        CheckConstructor(isolate, js_obj, "$SyntaxError") ||
25573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        CheckConstructor(isolate, js_obj, "$TypeError") ||
25583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        CheckConstructor(isolate, js_obj, "$URIError");
25593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  } else {
25603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return false;
25613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
25623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
25633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
25643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2565756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickbool Value::IsRegExp() const {
2566756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2567756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return obj->IsJSRegExp();
2568756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
2569756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
2570756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
2571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<String> Value::ToString() const {
2572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> str;
2574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsString()) {
2575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    str = obj;
2576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
257744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    i::Isolate* isolate = i::Isolate::Current();
257844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToString");
257944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
258044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToString(
2582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&str);
258344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
2584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<String>(str);
2586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<String> Value::ToDetailString() const {
2590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> str;
2592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsString()) {
2593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    str = obj;
2594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
259544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    i::Isolate* isolate = i::Isolate::Current();
259644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToDetailString");
259744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
259844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToDetailString(
2600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&str);
260144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
2602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<String>(str);
2604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<v8::Object> Value::ToObject() const {
2608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> val;
2610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsJSObject()) {
2611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    val = obj;
2612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
261344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    i::Isolate* isolate = i::Isolate::Current();
261444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToObject");
261544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
261644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToObject(
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&val);
261944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
2620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<Object>(val);
2622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Boolean> Value::ToBoolean() const {
2626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2627a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsBoolean()) {
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ToApiHandle<Boolean>(obj);
2629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
263044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    i::Isolate* isolate = i::Isolate::Current();
263144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToBoolean");
263244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> val =
2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate->factory()->ToBoolean(obj->BooleanValue());
2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ToApiHandle<Boolean>(val);
2636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Number> Value::ToNumber() const {
2641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> num;
2643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsNumber()) {
2644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    num = obj;
2645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
264744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToNumber");
264844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
264944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToNumber(
2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&num);
265244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
2653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<Number>(num);
2655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Integer> Value::ToInteger() const {
2659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> num;
2661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
2662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    num = obj;
2663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
266544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToInteger");
266644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
266744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToInteger(
2669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&num);
267044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
2671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<Integer>(num);
2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(isolate != NULL &&
2679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  isolate->IsInitialized() &&
2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  !isolate->IsDead(),
2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::internal::Internals::CheckInitialized()",
2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Isolate is not initialized or V8 has died");
2683a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2684a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2685a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2686a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid External::CheckCast(v8::Value* that) {
2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(),
2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::External::Cast()",
2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to external");
2690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Object::CheckCast(Value* that) {
2694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSObject(),
2696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Object::Cast()",
2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to object");
2698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Function::CheckCast(Value* that) {
2702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSFunction(),
2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Function::Cast()",
2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to function");
2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Name::CheckCast(v8::Value* that) {
2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsName(),
2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Name::Cast()",
2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to name");
2714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::String::CheckCast(v8::Value* that) {
2718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsString(),
2720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::String::Cast()",
2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to string");
2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Symbol::CheckCast(v8::Value* that) {
2726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsSymbol(),
2728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Symbol::Cast()",
2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to symbol");
2730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Number::CheckCast(v8::Value* that) {
2734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsNumber(),
2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Number::Cast()",
2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to number");
2738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Integer::CheckCast(v8::Value* that) {
2742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsNumber(),
2744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Integer::Cast()",
2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to number");
2746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Array::CheckCast(Value* that) {
2750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSArray(),
2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Array::Cast()",
2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to array");
2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Promise::CheckCast(Value* that) {
2758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(that->IsPromise(),
2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Promise::Cast()",
2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to promise");
2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Promise::Resolver::CheckCast(Value* that) {
2765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(that->IsPromise(),
2766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Promise::Resolver::Cast()",
2767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to promise resolver");
2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::ArrayBuffer::CheckCast(Value* that) {
2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSArrayBuffer(),
2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::ArrayBuffer::Cast()",
2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to ArrayBuffer");
2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::ArrayBufferView::CheckCast(Value* that) {
2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSArrayBufferView(),
2782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::ArrayBufferView::Cast()",
2783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to ArrayBufferView");
2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::TypedArray::CheckCast(Value* that) {
2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSTypedArray(),
2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::TypedArray::Cast()",
2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to TypedArray");
2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size)             \
2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void v8::Type##Array::CheckCast(Value* that) {                              \
2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> obj = Utils::OpenHandle(that);                       \
2798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Utils::ApiCheck(obj->IsJSTypedArray() &&                                  \
2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    i::JSTypedArray::cast(*obj)->type() ==                    \
2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        kExternal##Type##Array,                               \
2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "v8::" #Type "Array::Cast()",                             \
2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                    "Could not convert to " #Type "Array");                   \
2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef CHECK_TYPED_ARRAY_CAST
2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::DataView::CheckCast(Value* that) {
2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSDataView(),
2814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::DataView::Cast()",
2815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to DataView");
2816a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2817a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2818a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2819a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Date::CheckCast(v8::Value* that) {
2820a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = NULL;
2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(isolate != NULL &&
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  obj->HasSpecificClassOf(isolate->heap()->Date_string()),
2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::Date::Cast()",
2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to date");
2827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid v8::StringObject::CheckCast(v8::Value* that) {
28313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = NULL;
2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(isolate != NULL &&
2835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  obj->HasSpecificClassOf(isolate->heap()->String_string()),
2836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::StringObject::Cast()",
2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to StringObject");
2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::SymbolObject::CheckCast(v8::Value* that) {
2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = NULL;
2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(isolate != NULL &&
2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::SymbolObject::Cast()",
2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to SymbolObject");
28493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
28503fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
28513fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
28523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid v8::NumberObject::CheckCast(v8::Value* that) {
28533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = NULL;
2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(isolate != NULL &&
2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  obj->HasSpecificClassOf(isolate->heap()->Number_string()),
2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::NumberObject::Cast()",
2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to NumberObject");
28603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
28613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
28623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
28633fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochvoid v8::BooleanObject::CheckCast(v8::Value* that) {
28643fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = NULL;
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(isolate != NULL &&
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::BooleanObject::Cast()",
2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to BooleanObject");
28713fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
28723fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
28733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
2874f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochvoid v8::RegExp::CheckCast(v8::Value* that) {
2875f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(that);
2876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->IsJSRegExp(),
2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::RegExp::Cast()",
2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Could not convert to regular expression");
2879f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
2880f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
2881f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
2882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::BooleanValue() const {
2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->BooleanValue();
2884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdouble Value::NumberValue() const {
2888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> num;
2890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsNumber()) {
2891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    num = obj;
2892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
289444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "NumberValue");
289544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
289644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToNumber(
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&num);
2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    EXCEPTION_BAILOUT_CHECK(isolate, base::OS::nan_value());
2900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return num->Number();
2902a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint64_t Value::IntegerValue() const {
2906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> num;
2908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsNumber()) {
2909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    num = obj;
2910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
291244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "IntegerValue");
291344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
291444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToInteger(
2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&num);
291744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, 0);
2918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (num->IsSmi()) {
2920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return i::Smi::cast(*num)->value();
2921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return static_cast<int64_t>(num->Number());
2923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2925a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Int32> Value::ToInt32() const {
2928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2929a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> num;
2930a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
2931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    num = obj;
2932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
293444f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToInt32");
293544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
293644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
293844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
2939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<Int32>(num);
2941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Uint32> Value::ToUint32() const {
2945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> num;
2947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
2948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    num = obj;
2949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
295144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "ToUInt32");
295244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
295344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToUint32(
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&num);
295644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
2957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<Uint32>(num);
2959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Uint32> Value::ToArrayIndex() const {
2963a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
2965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Local<Uint32>();
2967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
296944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "ToArrayIndex");
297044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
297144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> string_obj;
2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::ToString(
2974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, obj).ToHandle(&string_obj);
297544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
2976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  uint32_t index;
2978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (str->AsArrayIndex(&index)) {
2979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i::Handle<i::Object> value;
2980a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
2982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
298344f0eee88ff00398ff7f715fab053374d808c90dSteve Block      value = isolate->factory()->NewNumber(index);
2984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
2985a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return Utils::Uint32ToLocal(value);
2986a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2987a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Local<Uint32>();
2988a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
2989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2990a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint32_t Value::Int32Value() const {
2992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
2993a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
2994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return i::Smi::cast(*obj)->value();
2995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
299744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "Int32Value (slow)");
299844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
299944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
3000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> num;
3001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
300244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, 0);
3003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (num->IsSmi()) {
3004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return i::Smi::cast(*num)->value();
3005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
3006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return static_cast<int32_t>(num->Number());
3007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
3008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::Equals(Handle<Value> that) const {
301344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Value::Equals()",
3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "Reading from empty handle")) {
3018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
3019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
302044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "Equals");
302144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> other = Utils::OpenHandle(*that);
30231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // If both obj and other are JSObjects, we'd better compare by identity
30241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // immediately when going into JS builtin.  The reason is Invoke
30251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  // would overwrite global object receiver with global proxy.
30261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (obj->IsJSObject() && other->IsJSObject()) {
30271e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return *obj == *other;
30281e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
30293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::Object> args[] = { other };
303044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !CallV8HeapFunction(
3033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "EQUALS", obj, arraysize(args), args).ToHandle(&result);
303444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, false);
3035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return *result == i::Smi::FromInt(i::EQUAL);
3036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Value::StrictEquals(Handle<Value> that) const {
304044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Value::StrictEquals()",
3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "Reading from empty handle")) {
3045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
3046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
304744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "StrictEquals");
3048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> other = Utils::OpenHandle(*that);
3049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Must check HeapNumber first, since NaN !== NaN.
3050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsHeapNumber()) {
3051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!other->IsNumber()) return false;
3052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    double x = obj->Number();
3053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    double y = other->Number();
3054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Must check explicitly for NaN:s on Windows, but -0 works fine.
3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return x == y && !std::isnan(x) && !std::isnan(y);
3056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (*obj == *other) {  // Also covers Booleans.
3057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return true;
3058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (obj->IsSmi()) {
3059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return other->IsNumber() && obj->Number() == other->Number();
3060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (obj->IsString()) {
3061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return other->IsString() &&
3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::String::Equals(i::Handle<i::String>::cast(obj),
3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          i::Handle<i::String>::cast(other));
3064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
3065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return other->IsUndefined() || other->IsUndetectableObject();
3066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
3067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
3068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::SameValue(Handle<Value> that) const {
3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Value::SameValue()",
3076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "Reading from empty handle")) {
3077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
3078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> other = Utils::OpenHandle(*that);
3080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->SameValue(*other);
3081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuint32_t Value::Uint32Value() const {
3085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
3086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
3087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return i::Smi::cast(*obj)->value();
3088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
3089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
309044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    LOG_API(isolate, "Uint32Value");
309144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
309244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_PREAMBLE(isolate);
3093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> num;
3094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToUint32(
3095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&num);
309644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    EXCEPTION_BAILOUT_CHECK(isolate, 0);
3097a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (num->IsSmi()) {
3098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return i::Smi::cast(*num)->value();
3099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
3100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return static_cast<uint32_t>(num->Number());
3101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
3102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) {
310744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
310844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::Set()", return false);
310944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
311044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> self = Utils::OpenHandle(this);
3112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
311444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception =
3116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    i::SLOPPY).is_null();
311844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, false);
3119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
3120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31236ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockbool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
312444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
312544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::Set()", return false);
312644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
312744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
31286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
31296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
313044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = i::JSObject::SetElement(
3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      self, index, value_obj, NONE, i::SLOPPY).is_null();
313344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, false);
31346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return true;
31356ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
31366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
31376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3138a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::ForceSet(v8::Handle<Value> key,
3139a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          v8::Handle<Value> value,
3140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          v8::PropertyAttribute attribs) {
314144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
314244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
314344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
314444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3147a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
314844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = i::Runtime::DefineObjectProperty(
3150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      self,
3151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      key_obj,
3152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      value_obj,
3153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      static_cast<PropertyAttributes>(attribs)).is_null();
315444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, false);
3155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
3156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ForceSet(v8::Handle<Value>(reinterpret_cast<Value*>(*key)),
3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  value, DontEnum);
3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::ForceDelete(v8::Handle<Value> key) {
316644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
316744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
316844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
316944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3172b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // When deleting a property on the global object using ForceDelete
3174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deoptimize all functions as optimized code does not check for the hole
3175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // value with DontDelete properties.  We have to deoptimize all contexts
3176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // because of possible cross-context inlined functions.
3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Deoptimizer::DeoptimizeAll(isolate);
3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
318144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj;
3183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Runtime::DeleteObjectProperty(
3184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, self, key_obj, i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
318544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, false);
3186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return obj->IsTrue();
3187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Value> v8::Object::Get(v8::Handle<Value> key) {
319144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
319244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
319344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> self = Utils::OpenHandle(this);
3195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
319644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception =
3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
320044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
3202a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
32056ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockLocal<Value> v8::Object::Get(uint32_t index) {
320644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
320744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
320844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
32096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
321044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
3212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception =
3213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !i::Object::GetElement(isolate, self, index).ToHandle(&result);
321444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
32156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return Utils::ToLocal(result);
32166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
32176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
32186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
3219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> v8::Object::GetPrivate(v8::Handle<Private> key) {
3220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Get(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
32243fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochPropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
32253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Object::GetPropertyAttributes()",
32273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch             return static_cast<PropertyAttribute>(NONE));
32283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ENTER_V8(isolate);
32293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::HandleScope scope(isolate);
32303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
32313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!key_obj->IsName()) {
32333fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    EXCEPTION_PREAMBLE(isolate);
3234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::ToString(
3235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, key_obj).ToHandle(&key_obj);
32363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
32373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
3238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
3239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Maybe<PropertyAttributes> result =
3241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSReceiver::GetPropertyAttributes(self, key_name);
3242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !result.has_value;
3243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (result.value == ABSENT) return static_cast<PropertyAttribute>(NONE);
3245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<PropertyAttribute>(result.value);
3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) {
3250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyDescriptor()",
3252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             return Local<Value>());
3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
3254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
3256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> args[] = { obj, key_name };
3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
3259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !CallV8HeapFunction(
3260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "ObjectGetOwnPropertyDescriptor",
3261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->undefined_value(),
3262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arraysize(args),
3263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      args).ToHandle(&result);
3264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(result);
32663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
32673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
32683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3269a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Value> v8::Object::GetPrototype() {
327044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Object::GetPrototype()", return Local<v8::Value>());
327244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> self = Utils::OpenHandle(this);
3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::PrototypeIterator iter(isolate, self);
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
3276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3279402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescubool v8::Object::SetPrototype(Handle<Value> value) {
328044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
328144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
328244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3283402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3284402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
32858b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // We do not allow exceptions thrown while setting the prototype
32868b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  // to propagate outside.
32878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  TryCatch try_catch;
328844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::MaybeHandle<i::Object> result =
3290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSObject::SetPrototype(self, value_obj, false);
3291402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  has_pending_exception = result.is_null();
329244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, false);
3293402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return true;
3294402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
3295402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
3296402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
3297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Object> v8::Object::FindInstanceInPrototypeChain(
3298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<FunctionTemplate> tmpl) {
329944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
330044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate,
330144f0eee88ff00398ff7f715fab053374d808c90dSteve Block             "v8::Object::FindInstanceInPrototypeChain()",
3302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             return Local<v8::Object>());
330344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this),
3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            i::PrototypeIterator::START_AT_RECEIVER);
3306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) {
3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    iter.Advance();
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (iter.IsAtEnd()) {
3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Local<Object>();
3311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(
3314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::handle(i::JSObject::cast(iter.GetCurrent()), isolate));
3315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Array> v8::Object::GetPropertyNames() {
331944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
332044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
332144f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return Local<v8::Array>());
332244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
332344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> value;
3327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::JSReceiver::GetKeys(
3328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      self, i::JSReceiver::INCLUDE_PROTOS).ToHandle(&value);
3329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
3330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Because we use caching to speed up enumeration it is important
3331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to never change the result of the basic enumeration function so
3332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // we clone the result.
333344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
333444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Handle<i::JSArray> result =
333544f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewJSArrayWithElements(elms);
333644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return Utils::ToLocal(scope.CloseAndEscape(result));
3337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
33403fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLocal<Array> v8::Object::GetOwnPropertyNames() {
33413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
33423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
33433fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch             return Local<v8::Array>());
33443fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ENTER_V8(isolate);
33453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::HandleScope scope(isolate);
33463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> value;
3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::JSReceiver::GetKeys(
3350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      self, i::JSReceiver::OWN_ONLY).ToHandle(&value);
3351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
33523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Because we use caching to speed up enumeration it is important
33533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // to never change the result of the basic enumeration function so
33543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // we clone the result.
33553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
33563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::JSArray> result =
33573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      isolate->factory()->NewJSArrayWithElements(elms);
33583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return Utils::ToLocal(scope.CloseAndEscape(result));
33593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
33603fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
33613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
3362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<String> v8::Object::ObjectProtoToString() {
3363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
3364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
3365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(i_isolate, "v8::Object::ObjectProtoToString()",
336644f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return Local<v8::String>());
3367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
3368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> name(self->class_name(), i_isolate);
3371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Native implementation of Object.prototype.toString (v8natives.js):
3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  //   var c = %_ClassOf(this);
3374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //   if (c === 'Arguments') c  = 'Object';
3375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  //   return "[object " + c + "]";
3376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!name->IsString()) {
3378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return v8::String::NewFromUtf8(isolate, "[object ]");
3379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
3380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
3381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (i::String::Equals(class_name,
3382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                          i_isolate->factory()->Arguments_string())) {
3383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return v8::String::NewFromUtf8(isolate, "[object Object]");
3384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
3385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      const char* prefix = "[object ";
3386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      Local<String> str = Utils::ToLocal(class_name);
3387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      const char* postfix = "]";
3388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3389d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      int prefix_len = i::StrLength(prefix);
3390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int str_len = str->Utf8Length();
3391d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      int postfix_len = i::StrLength(postfix);
3392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3393d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      int buf_len = prefix_len + str_len + postfix_len;
339425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      i::ScopedVector<char> buf(buf_len);
3395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Write prefix.
339725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen      char* ptr = buf.start();
3398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
3399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ptr += prefix_len;
3400a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Write real content.
3402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      str->WriteUtf8(ptr, str_len);
3403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      ptr += str_len;
3404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Write postfix.
3406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
3407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Copy the buffer into a heap-allocated string and return it.
3409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Local<String> result = v8::String::NewFromUtf8(
3410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate, buf.start(), String::kNormalString, buf_len);
3411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return result;
3412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
3413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34178a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) WangLocal<String> v8::Object::GetConstructorName() {
341844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
341944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
342044f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return Local<v8::String>());
342144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
34228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
34238a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  i::Handle<i::String> name(self->constructor_name());
34248a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return Utils::ToLocal(name);
34258a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
34268a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
34278a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
3428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::Object::Delete(v8::Handle<Value> key) {
342944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
343044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
343144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
343244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj;
3437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Runtime::DeleteObjectProperty(
3438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, self, key_obj, i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
3439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->IsTrue();
3441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::Object::DeletePrivate(v8::Handle<Private> key) {
3445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Delete(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::Object::Has(v8::Handle<Value> key) {
345044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
345144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::Has()", return false);
345244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj;
3457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Runtime::HasObjectProperty(
3458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, self, key_obj).ToHandle(&obj);
3459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->IsTrue();
3461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::Object::HasPrivate(v8::Handle<Private> key) {
3465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): this should use HasOwnProperty, but we'd need to
3466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // generalise that to a (noy yet existant) Name argument first.
3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::Delete(uint32_t index) {
347244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
347344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
347444f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
347544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScope scope(reinterpret_cast<Isolate*>(isolate));
3477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj;
3481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception =
3482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      !i::JSReceiver::DeleteElement(self, index).ToHandle(&obj);
3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->IsTrue();
3485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3486a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3487a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3488a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::Has(uint32_t index) {
348944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
349044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
3491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Maybe<bool> maybe = i::JSReceiver::HasElement(self, index);
3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !maybe.has_value;
3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return maybe.value;
3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename Getter, typename Setter, typename Data>
3501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline bool ObjectSetAccessor(Object* obj,
3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Handle<Name> name,
3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Getter getter,
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Setter setter,
3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Data data,
3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     AccessControl settings,
3507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     PropertyAttribute attributes) {
3508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate();
3509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
3511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
3512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Handle<AccessorSignature> signature;
3513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::AccessorInfo> info = MakeAccessorInfo(
3514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      name, getter, setter, data, settings, attributes, signature);
3515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (info.is_null()) return false;
3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool fast = Utils::OpenHandle(obj)->HasFastProperties();
3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, result,
3520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
3521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false);
3522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (result->IsUndefined()) return false;
3523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (fast) i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0);
3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
3525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3528f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarkebool Object::SetAccessor(Handle<String> name,
3529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         AccessorGetterCallback getter,
3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         AccessorSetterCallback setter,
3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         v8::Handle<Value> data,
3532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         AccessControl settings,
3533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         PropertyAttribute attributes) {
3534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ObjectSetAccessor(
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, getter, setter, data, settings, attributes);
3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Object::SetAccessor(Handle<Name> name,
3540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         AccessorNameGetterCallback getter,
3541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         AccessorNameSetterCallback setter,
3542f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                         v8::Handle<Value> data,
3543f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                         AccessControl settings,
3544f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke                         PropertyAttribute attributes) {
3545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ObjectSetAccessor(
3546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, getter, setter, data, settings, attributes);
3547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Object::SetDeclaredAccessor(Local<Name> name,
3551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Local<DeclaredAccessorDescriptor> descriptor,
3552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 PropertyAttribute attributes,
3553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AccessControl settings) {
3554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void* null = NULL;
3555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ObjectSetAccessor(
3556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      this, name, descriptor, null, null, settings, attributes);
3557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Object::SetAccessorProperty(Local<Name> name,
3561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Local<Function> getter,
3562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 Handle<Function> setter,
3563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 PropertyAttribute attribute,
3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 AccessControl settings) {
3565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(verwaest): Remove |settings|.
3566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(v8::DEFAULT, settings);
356744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Object::SetAccessorProperty()", return);
356944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
357044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
3572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
3573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
3574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::JSObject::DefineAccessor(v8::Utils::OpenHandle(this),
3575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              v8::Utils::OpenHandle(*name),
3576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              getter_i,
3577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              setter_i,
3578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              static_cast<PropertyAttributes>(attribute));
3579f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
3580f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3581f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
3582257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool v8::Object::HasOwnProperty(Handle<String> key) {
3583257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3584257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3585257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch             return false);
3586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Maybe<bool> maybe = i::JSReceiver::HasOwnProperty(Utils::OpenHandle(this),
3588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                    Utils::OpenHandle(*key));
3589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !maybe.has_value;
3590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return maybe.value;
3592257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
3593257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3594257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::HasRealNamedProperty(Handle<String> key) {
359644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
359744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
359844f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
3599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Maybe<bool> maybe = i::JSObject::HasRealNamedProperty(
3601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(this), Utils::OpenHandle(*key));
3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !maybe.has_value;
3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return maybe.value;
3605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::HasRealIndexedProperty(uint32_t index) {
3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
361144f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Maybe<bool> maybe =
3614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSObject::HasRealElementProperty(Utils::OpenHandle(this), index);
3615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !maybe.has_value;
3616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return maybe.value;
3618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
362244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
362344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate,
362444f0eee88ff00398ff7f715fab053374d808c90dSteve Block             "v8::Object::HasRealNamedCallbackProperty()",
362544f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
362644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
3628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Maybe<bool> maybe = i::JSObject::HasRealNamedCallbackProperty(
3629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(this), Utils::OpenHandle(*key));
3630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !maybe.has_value;
3631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
3632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return maybe.value;
3633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::HasNamedLookupInterceptor() {
363744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
363844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
363944f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
3640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->HasNamedInterceptor();
3641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::HasIndexedLookupInterceptor() {
364544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
364644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
364744f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
3648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->HasIndexedInterceptor();
3649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Local<Value> GetPropertyByLookup(i::LookupIterator* it) {
3653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the property being looked up is a callback, it can throw an exception.
3654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(it->isolate());
3655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
3656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Object::GetProperty(it).ToHandle(&result);
3657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(it->isolate(), Local<Value>());
36588b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (it->IsFound()) return Utils::ToLocal(result);
3660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Local<Value>();
36618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
36628b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
36638b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
3665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<String> key) {
366644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
366744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate,
366844f0eee88ff00398ff7f715fab053374d808c90dSteve Block             "v8::Object::GetRealNamedPropertyInPrototypeChain()",
3669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             return Local<Value>());
367044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::PrototypeIterator iter(isolate, self_obj);
3674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (iter.IsAtEnd()) return Local<Value>();
3675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> proto = i::PrototypeIterator::GetCurrent(iter);
3676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::LookupIterator it(self_obj, key_obj, i::Handle<i::JSReceiver>::cast(proto),
3677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetPropertyByLookup(&it);
3679a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3682a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
368344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
368444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
368544f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return Local<Value>());
368644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::LookupIterator it(self_obj, key_obj,
3690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetPropertyByLookup(&it);
3692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Turns on access checks by copying the map and setting the check flag.
3696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Because the object gets a new map, existing inline cache caching
3697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the old map of this object will fail.
3698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Object::TurnOnAccessCheck() {
369944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
370044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
370144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
370244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3705b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // When turning on access checks for a global object deoptimize all functions
3706b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // as optimized code does not always handle access checks.
3707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
3709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Map> new_map = i::Map::Copy(i::Handle<i::Map>(obj->map()));
3710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  new_map->set_is_access_check_needed(true);
3711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::JSObject::MigrateToMap(obj, new_map);
3712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::IsDirty() {
3716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::OpenHandle(this)->IsDirty();
3717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<v8::Object> v8::Object::Clone() {
372144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
372244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
372344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
372544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
3726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
3727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  has_pending_exception = result.is_null();
372844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
3729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
3730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
37338b112d2025046f85ef7f6be087c6129c872ebad2Ben MurdochLocal<v8::Context> v8::Object::CreationContext() {
37348b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
37358b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  ON_BAILOUT(isolate,
37368b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch             "v8::Object::CreationContext()", return Local<v8::Context>());
37378b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  ENTER_V8(isolate);
37388b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Context* context = self->GetCreationContext();
37408b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  return Utils::ToLocal(i::Handle<i::Context>(context));
37418b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch}
37428b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
37438b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch
3744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint v8::Object::GetIdentityHash() {
374544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
374644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
374744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
374844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::JSReceiver::GetOrCreateIdentityHash(self)->value();
3751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                v8::Handle<v8::Value> value) {
375644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
375744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
3758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value.IsEmpty()) return DeleteHiddenValue(key);
375944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
376044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
37623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> key_string =
3764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->InternalizeString(key_obj);
3765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
37663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::Object> result =
3767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSObject::SetHiddenProperty(self, key_string, value_obj);
37683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return *result == *self;
3769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
377344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
377444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
377544f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return Local<v8::Value>());
377644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
3777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> key_string =
3780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->InternalizeString(key_obj);
3781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result(self->GetHiddenProperty(key_string), isolate);
3782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (result->IsTheHole()) return v8::Local<v8::Value>();
3783a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
3784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3787a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
378844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
378944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
379044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
379144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3793a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
3794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> key_string =
3795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->InternalizeString(key_obj);
3796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::JSObject::DeleteHiddenProperty(self, key_string);
37973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return true;
3798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3799a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
380144f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace {
380244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3803589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochstatic i::ElementsKind GetElementsKindFromExternalArrayType(
3804589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ExternalArrayType array_type) {
3805589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  switch (array_type) {
3806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define ARRAY_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size)            \
3807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case kExternal##Type##Array:                                              \
3808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return i::EXTERNAL_##TYPE##_ELEMENTS;
3809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(ARRAY_TYPE_TO_ELEMENTS_KIND)
3811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef ARRAY_TYPE_TO_ELEMENTS_KIND
3812589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
3813589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  UNREACHABLE();
3814589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return i::DICTIONARY_ELEMENTS;
3815589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
3816589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
3817589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
381844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid PrepareExternalArrayElements(i::Handle<i::JSObject> object,
381944f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                  void* data,
382044f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                  ExternalArrayType array_type,
382144f0eee88ff00398ff7f715fab053374d808c90dSteve Block                                  int length) {
382244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = object->GetIsolate();
382344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Handle<i::ExternalArray> array =
382444f0eee88ff00398ff7f715fab053374d808c90dSteve Block      isolate->factory()->NewExternalArray(length, array_type, data);
382544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
38263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::Map> external_array_map =
3827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSObject::GetElementsTransitionMap(
38283ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          object,
38293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          GetElementsKindFromExternalArrayType(array_type));
38303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::JSObject::SetMapAndElements(object, external_array_map, array);
383244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
383344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
383444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}  // namespace
383544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
383644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
3837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
383844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
383944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
384044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
384144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(length >= 0 &&
3843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       length <= i::ExternalUint8ClampedArray::kMaxLength,
3844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Object::SetIndexedPropertiesToPixelData()",
3845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "length exceeds max acceptable value")) {
3846a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
3847a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(!self->IsJSArray(),
3850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Object::SetIndexedPropertiesToPixelData()",
3851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "JSArray is not supported")) {
3852a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return;
3853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PrepareExternalArrayElements(self, data, kExternalUint8ClampedArray, length);
3855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
3856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
38589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenbool v8::Object::HasIndexedPropertiesInPixelData() {
38599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
386044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
386144f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
3862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return self->HasExternalUint8ClampedElements();
38639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
38649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
38659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
38669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenuint8_t* v8::Object::GetIndexedPropertiesPixelData() {
38679dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
386844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
386944f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return NULL);
3870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (self->HasExternalUint8ClampedElements()) {
3871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::ExternalUint8ClampedArray::cast(self->elements())->
3872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        external_uint8_clamped_pointer();
38739dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  } else {
38749dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    return NULL;
38759dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
38769dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
38779dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
38789dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
38799dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenint v8::Object::GetIndexedPropertiesPixelDataLength() {
38809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
388144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
388244f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return -1);
3883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (self->HasExternalUint8ClampedElements()) {
3884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::ExternalUint8ClampedArray::cast(self->elements())->length();
38859dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  } else {
38869dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    return -1;
38879dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
38889dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
38899dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
3890589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
38913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Blockvoid v8::Object::SetIndexedPropertiesToExternalArrayData(
38923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    void* data,
38933ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    ExternalArrayType array_type,
38943ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    int length) {
389544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
389644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
389744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
389844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
3899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
3900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "length exceeds max acceptable value")) {
39023ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return;
39033ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
39043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(!self->IsJSArray(),
3906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "JSArray is not supported")) {
39083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    return;
39093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
391044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  PrepareExternalArrayElements(self, data, array_type, length);
39113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
39123ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
39133ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
39149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenbool v8::Object::HasIndexedPropertiesInExternalArrayData() {
39159dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
391644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(self->GetIsolate(),
391744f0eee88ff00398ff7f715fab053374d808c90dSteve Block             "v8::HasIndexedPropertiesInExternalArrayData()",
391844f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
39199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return self->HasExternalArrayElements();
39209dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
39219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
39229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
39239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenvoid* v8::Object::GetIndexedPropertiesExternalArrayData() {
39249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
392544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(self->GetIsolate(),
392644f0eee88ff00398ff7f715fab053374d808c90dSteve Block             "v8::GetIndexedPropertiesExternalArrayData()",
392744f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return NULL);
39289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  if (self->HasExternalArrayElements()) {
39299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    return i::ExternalArray::cast(self->elements())->external_pointer();
39309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  } else {
39319dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    return NULL;
39329dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
39339dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
39349dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
39359dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
39369dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
39379dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
393844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(self->GetIsolate(),
393944f0eee88ff00398ff7f715fab053374d808c90dSteve Block             "v8::GetIndexedPropertiesExternalArrayDataType()",
394044f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return static_cast<ExternalArrayType>(-1));
39419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  switch (self->elements()->map()->instance_type()) {
3942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size)            \
3943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case i::EXTERNAL_##TYPE##_ARRAY_TYPE:                                     \
3944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return kExternal##Type##Array;
3945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
3946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef INSTANCE_TYPE_TO_ARRAY_TYPE
39479dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    default:
39489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen      return static_cast<ExternalArrayType>(-1);
39499dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
39509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
39519dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
39529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
39539dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenint v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
39549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
395544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(self->GetIsolate(),
395644f0eee88ff00398ff7f715fab053374d808c90dSteve Block             "v8::GetIndexedPropertiesExternalArrayDataLength()",
395744f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return 0);
39589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  if (self->HasExternalArrayElements()) {
39599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    return i::ExternalArray::cast(self->elements())->length();
39609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  } else {
39619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    return -1;
39629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
39639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
39649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
39659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
3966257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochbool v8::Object::IsCallable() {
3967257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3968257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3969257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ENTER_V8(isolate);
3970257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::HandleScope scope(isolate);
3971257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj->IsCallable();
3973257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
3974257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3975257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
3976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
39773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        int argc,
3978257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                        v8::Handle<v8::Value> argv[]) {
3979257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3980257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3981257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch             return Local<v8::Value>());
3982257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LOG_API(isolate, "Object::CallAsFunction");
3983257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ENTER_V8(isolate);
3984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
3985257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::HandleScope scope(isolate);
3986257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3987257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3988257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
39893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
3990257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3991257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (obj->IsJSFunction()) {
3992257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    fun = i::Handle<i::JSFunction>::cast(obj);
3993257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  } else {
3994257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    EXCEPTION_PREAMBLE(isolate);
3995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> delegate;
3996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::TryGetFunctionDelegate(
3997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, obj).ToHandle(&delegate);
3998257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3999257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    fun = i::Handle<i::JSFunction>::cast(delegate);
4000257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    recv_obj = obj;
4001257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
4002257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  EXCEPTION_PREAMBLE(isolate);
4003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> returned;
4004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
4005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
40063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
4007257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Utils::ToLocal(scope.CloseAndEscape(returned));
4008257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
4009257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4010257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4011257744e915dfc84d6d07a6b2accf8402d9ffc708Ben MurdochLocal<v8::Value> Object::CallAsConstructor(int argc,
4012257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch                                           v8::Handle<v8::Value> argv[]) {
4013257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4014257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
4015257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch             return Local<v8::Object>());
4016257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  LOG_API(isolate, "Object::CallAsConstructor");
4017257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ENTER_V8(isolate);
4018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4019257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::HandleScope scope(isolate);
4020257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4021257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
40223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4023257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (obj->IsJSFunction()) {
4024257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
4025257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    EXCEPTION_PREAMBLE(isolate);
4026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> returned;
4027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::New(
4028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        fun, argc, args).ToHandle(&returned);
40293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
4030257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Utils::ToLocal(scope.CloseAndEscape(
4031257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        i::Handle<i::JSObject>::cast(returned)));
4032257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
4033257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  EXCEPTION_PREAMBLE(isolate);
4034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> delegate;
4035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::TryGetConstructorDelegate(
4036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, obj).ToHandle(&delegate);
4037257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
4038257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!delegate->IsUndefined()) {
4039257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
4040257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    EXCEPTION_PREAMBLE(isolate);
4041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> returned;
4042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = !i::Execution::Call(
4043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate, fun, obj, argc, args).ToHandle(&returned);
40443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
4045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!delegate->IsUndefined());
4046257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    return Utils::ToLocal(scope.CloseAndEscape(returned));
4047257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
4048257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  return Local<v8::Object>();
4049257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
4050257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4051257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
4052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Function> Function::New(Isolate* v8_isolate,
4053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              FunctionCallback callback,
4054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Local<Value> data,
4055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              int length) {
4056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
4057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Function::New");
4058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
4059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return FunctionTemplateNew(
4060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, callback, data, Local<Signature>(), length, true)->
4061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GetFunction();
4062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<v8::Object> Function::NewInstance() const {
4066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return NewInstance(0, NULL);
4067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4069a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<v8::Object> Function::NewInstance(int argc,
4071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                        v8::Handle<v8::Value> argv[]) const {
407244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
407344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Function::NewInstance()",
407444f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return Local<v8::Object>());
407544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "Function::NewInstance");
407644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
4077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
4079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
4080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
40813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
408244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
4083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> returned;
4084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::New(
4085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      function, argc, args).ToHandle(&returned);
40863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
4087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return scope.Escape(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
4088a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4090a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
4092a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                v8::Handle<v8::Value> argv[]) {
409344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
409444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
409544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "Function::Call");
409644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
4097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
4099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
4100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
4102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
4104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> returned;
4105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
4106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
4107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
4108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(scope.CloseAndEscape(returned));
4109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Function::SetName(v8::Handle<v8::String> name) {
411344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
411444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
41153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  USE(isolate);
4116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  func->shared()->set_name(*Utils::OpenHandle(*name));
4118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> Function::GetName() const {
4122a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name(),
4124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             func->GetIsolate()));
4125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
41283ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochHandle<Value> Function::GetInferredName() const {
41293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                             func->GetIsolate()));
4132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Value> Function::GetDisplayName() const {
4136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Function::GetDisplayName()",
4138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             return ToApiHandle<Primitive>(
4139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 isolate->factory()->undefined_value()));
4140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
4141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> property_name =
4143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->InternalizeOneByteString(
4144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          STATIC_CHAR_VECTOR("displayName"));
4145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> value =
4147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSObject::GetDataProperty(func, property_name);
4148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value->IsString()) {
4149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::String> name = i::Handle<i::String>::cast(value);
4150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (name->length() > 0) return Utils::ToLocal(name);
4151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
41543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
41553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
41563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4157402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei PopescuScriptOrigin Function::GetScriptOrigin() const {
4158402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4159402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  if (func->shared()->script()->IsScript()) {
4160402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> scriptName = i::Script::GetNameOrSourceURL(script);
4162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(func->GetIsolate());
4163402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    v8::ScriptOrigin origin(
4164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Utils::ToLocal(scriptName),
4165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::Integer::New(isolate, script->line_offset()->value()),
4166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        v8::Integer::New(isolate, script->column_offset()->value()));
4167402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu    return origin;
4168402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
4169402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  return v8::ScriptOrigin(Handle<Value>());
4170402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu}
4171402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst int Function::kLineOffsetNotFound = -1;
4174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Function::GetScriptLineNumber() const {
4177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (func->shared()->script()->IsScript()) {
4179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::Script::GetLineNumber(script, func->shared()->start_position());
4181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kLineOffsetNotFound;
4183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Function::GetScriptColumnNumber() const {
4187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (func->shared()->script()->IsScript()) {
4189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return i::Script::GetColumnNumber(script, func->shared()->start_position());
4191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return kLineOffsetNotFound;
4193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Function::IsBuiltin() const {
4197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return func->IsBuiltin();
4199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint Function::ScriptId() const {
4203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!func->shared()->script()->IsScript()) {
4205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return v8::UnboundScript::kNoScriptId;
4206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return script->id()->value();
4209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Value> Function::GetBoundFunction() const {
4213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!func->shared()->bound()) {
4215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return v8::Undefined(reinterpret_cast<v8::Isolate*>(func->GetIsolate()));
4216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> bound_args = i::Handle<i::FixedArray>(
4218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::FixedArray::cast(func->function_bindings()));
4219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> original(
4220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bound_args->get(i::JSFunction::kBoundFunctionIndex),
4221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      func->GetIsolate());
4222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::Handle<i::JSFunction>::cast(original));
4223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint String::Length() const {
4227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(this);
4228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return str->length();
4229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool String::IsOneByte() const {
4233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(this);
4234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return str->HasOnlyOneByteChars();
4235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Helpers for ContainsOnlyOneByteHelper
4239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<size_t size> struct OneByteMask;
4240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<> struct OneByteMask<4> {
4241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const uint32_t value = 0xFF00FF00;
4242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<> struct OneByteMask<8> {
4244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline bool Unaligned(const uint16_t* chars) {
4249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline const uint16_t* Align(const uint16_t* chars) {
4254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<uint16_t*>(
4255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ContainsOnlyOneByteHelper {
4259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool Check(i::String* string) {
4262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (cons_string == NULL) return is_one_byte_;
4264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return CheckCons(cons_string);
4265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitOneByteString(const uint8_t* chars, int length) {
4267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Nothing to do.
4268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void VisitTwoByteString(const uint16_t* chars, int length) {
4270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Accumulated bits.
4271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uintptr_t acc = 0;
4272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Align to uintptr_t.
4273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const uint16_t* end = chars + length;
4274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (Unaligned(chars) && chars != end) {
4275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      acc |= *chars++;
4276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read word aligned in blocks,
4278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // checking the return value at the end of each block.
4279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const uint16_t* aligned_end = Align(end);
4280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const int inner_loops = 16;
4282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (chars + inner_loops*increment < aligned_end) {
4283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i = 0; i < inner_loops; i++) {
4284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        acc |= *reinterpret_cast<const uintptr_t*>(chars);
4285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        chars += increment;
4286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Check for early return.
4288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if ((acc & kOneByteMask) != 0) {
4289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        is_one_byte_ = false;
4290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return;
4291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Read the rest.
4294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (chars != end) {
4295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      acc |= *chars++;
4296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Check result.
4298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
4299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool CheckCons(i::ConsString* cons_string) {
4303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (true) {
4304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Check left side if flat.
4305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::String* left = cons_string->first();
4306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::ConsString* left_as_cons =
4307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          i::String::VisitFlat(this, left, 0);
4308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!is_one_byte_) return false;
4309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Check right side if flat.
4310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::String* right = cons_string->second();
4311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::ConsString* right_as_cons =
4312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          i::String::VisitFlat(this, right, 0);
4313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!is_one_byte_) return false;
4314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Standard recurse/iterate trick.
4315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (left_as_cons != NULL && right_as_cons != NULL) {
4316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (left->length() < right->length()) {
4317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckCons(left_as_cons);
4318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          cons_string = right_as_cons;
4319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
4320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          CheckCons(right_as_cons);
4321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          cons_string = left_as_cons;
4322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
4323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Check fast return.
4324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!is_one_byte_) return false;
4325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue;
4326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Descend left in place.
4328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (left_as_cons != NULL) {
4329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        cons_string = left_as_cons;
4330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue;
4331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Descend right in place.
4333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (right_as_cons != NULL) {
4334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        cons_string = right_as_cons;
4335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue;
4336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Terminate.
4338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
4339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return is_one_byte_;
4341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_one_byte_;
4343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool String::ContainsOnlyOneByte() const {
4348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(this);
4349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (str->HasOnlyOneByteChars()) return true;
4350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ContainsOnlyOneByteHelper helper;
4351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return helper.Check(*str);
4352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Utf8LengthHelper : public i::AllStatic {
4356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum State {
4358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kEndsWithLeadingSurrogate = 1 << 0,
4359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kStartsWithTrailingSurrogate = 1 << 1,
4360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kLeftmostEdgeIsCalculated = 1 << 2,
4361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kRightmostEdgeIsCalculated = 1 << 3,
4362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kLeftmostEdgeIsSurrogate = 1 << 4,
4363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kRightmostEdgeIsSurrogate = 1 << 5
4364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
4365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static const uint8_t kInitialState = 0;
4367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool EndsWithSurrogate(uint8_t state) {
4369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return state & kEndsWithLeadingSurrogate;
4370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline bool StartsWithSurrogate(uint8_t state) {
4373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return state & kStartsWithTrailingSurrogate;
4374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  class Visitor {
4377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   public:
4378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Visitor() : utf8_length_(0), state_(kInitialState) {}
4379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void VisitOneByteString(const uint8_t* chars, int length) {
4381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int utf8_length = 0;
4382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Add in length 1 for each non-Latin1 character.
4383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i = 0; i < length; i++) {
4384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        utf8_length += *chars++ >> 7;
4385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Add in length 1 for each character.
4387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      utf8_length_ = utf8_length + length;
4388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      state_ = kInitialState;
4389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    void VisitTwoByteString(const uint16_t* chars, int length) {
4392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int utf8_length = 0;
4393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int last_character = unibrow::Utf16::kNoPreviousCharacter;
4394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (int i = 0; i < length; i++) {
4395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        uint16_t c = chars[i];
4396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        utf8_length += unibrow::Utf8::Length(c, last_character);
4397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        last_character = c;
4398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      utf8_length_ = utf8_length;
4400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint8_t state = 0;
4401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        state |= kStartsWithTrailingSurrogate;
4403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        state |= kEndsWithLeadingSurrogate;
4406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      state_ = state;
4408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    static i::ConsString* VisitFlat(i::String* string,
4411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    int* length,
4412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    uint8_t* state) {
4413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Visitor visitor;
4414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *length = visitor.utf8_length_;
4416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *state = visitor.state_;
4417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return cons_string;
4418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4419402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch   private:
4421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int utf8_length_;
4422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint8_t state_;
4423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DISALLOW_COPY_AND_ASSIGN(Visitor);
4424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
4425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline void MergeLeafLeft(int* length,
4427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   uint8_t* state,
4428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   uint8_t leaf_state) {
4429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool edge_surrogate = StartsWithSurrogate(leaf_state);
4430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!(*state & kLeftmostEdgeIsCalculated)) {
4431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!(*state & kLeftmostEdgeIsSurrogate));
4432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *state |= kLeftmostEdgeIsCalculated
4433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (EndsWithSurrogate(leaf_state)) {
4438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *state |= kEndsWithLeadingSurrogate;
4439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
4440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *state &= ~kEndsWithLeadingSurrogate;
4441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4443402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline void MergeLeafRight(int* length,
4445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    uint8_t* state,
4446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    uint8_t leaf_state) {
4447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool edge_surrogate = EndsWithSurrogate(leaf_state);
4448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!(*state & kRightmostEdgeIsCalculated)) {
4449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!(*state & kRightmostEdgeIsSurrogate));
4450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *state |= (kRightmostEdgeIsCalculated
4451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (StartsWithSurrogate(leaf_state)) {
4456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *state |= kStartsWithTrailingSurrogate;
4457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
4458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *state &= ~kStartsWithTrailingSurrogate;
4459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4460402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  }
4461402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline void MergeTerminal(int* length,
4463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   uint8_t state,
4464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   uint8_t* state_out) {
4465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK((state & kLeftmostEdgeIsCalculated) &&
4466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           (state & kRightmostEdgeIsCalculated));
4467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    *state_out = kInitialState |
4471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int Calculate(i::ConsString* current, uint8_t* state_out) {
4476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using namespace internal;
4477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int total_length = 0;
4478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint8_t state = kInitialState;
4479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (true) {
4480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::String* left = current->first();
4481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::String* right = current->second();
4482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint8_t right_leaf_state;
4483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint8_t left_leaf_state;
4484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int leaf_length;
4485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ConsString* left_as_cons =
4486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (left_as_cons == NULL) {
4488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        total_length += leaf_length;
4489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        MergeLeafLeft(&total_length, &state, left_leaf_state);
4490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ConsString* right_as_cons =
4492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (right_as_cons == NULL) {
4494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        total_length += leaf_length;
4495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        MergeLeafRight(&total_length, &state, right_leaf_state);
4496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (left_as_cons != NULL) {
4497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // 1 Leaf node. Descend in place.
4498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          current = left_as_cons;
4499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          continue;
4500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
4501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // Terminal node.
4502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          MergeTerminal(&total_length, state, state_out);
4503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return total_length;
4504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
4505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (left_as_cons == NULL) {
4506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // 1 Leaf node. Descend in place.
4507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        current = right_as_cons;
4508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue;
4509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Both strings are ConsStrings.
4511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Recurse on smallest.
4512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (left->length() < right->length()) {
4513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        total_length += Calculate(left_as_cons, &left_leaf_state);
4514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        MergeLeafLeft(&total_length, &state, left_leaf_state);
4515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        current = right_as_cons;
4516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
4517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        total_length += Calculate(right_as_cons, &right_leaf_state);
4518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        MergeLeafRight(&total_length, &state, right_leaf_state);
4519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        current = left_as_cons;
4520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
4523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return 0;
4524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4525402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
4526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static inline int Calculate(i::ConsString* current) {
4527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    uint8_t state = kInitialState;
4528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Calculate(current, &state);
45293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
45303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
4533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
45343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic int Utf8Length(i::String* str, i::Isolate* isolate) {
4537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length = str->length();
4538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0) return 0;
4539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint8_t state;
4540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::ConsString* cons_string =
4541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (cons_string == NULL) return length;
4543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utf8LengthHelper::Calculate(cons_string);
4544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint String::Utf8Length() const {
454844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Handle<i::String> str = Utils::OpenHandle(this);
4549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = str->GetIsolate();
4550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return v8::Utf8Length(*str, isolate);
4551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Utf8WriterVisitor {
4555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
4556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utf8WriterVisitor(
4557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      char* buffer,
4558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int capacity,
4559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool skip_capacity_check,
4560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      bool replace_invalid_utf8)
4561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : early_termination_(false),
4562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      last_character_(unibrow::Utf16::kNoPreviousCharacter),
4563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      buffer_(buffer),
4564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      start_(buffer),
4565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      capacity_(capacity),
4566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      skip_capacity_check_(capacity == -1 || skip_capacity_check),
4567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      replace_invalid_utf8_(replace_invalid_utf8),
4568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      utf16_chars_read_(0) {
4569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int WriteEndCharacter(uint16_t character,
4572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int last_character,
4573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int remaining,
4574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               char* const buffer,
4575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               bool replace_invalid_utf8) {
4576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using namespace unibrow;
4577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(remaining > 0);
4578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We can't use a local buffer here because Encode needs to modify
4579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // previous characters in the stream.  We know, however, that
4580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // exactly one character will be advanced.
4581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (Utf16::IsSurrogatePair(last_character, character)) {
4582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int written = Utf8::Encode(buffer,
4583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 character,
4584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 last_character,
4585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 replace_invalid_utf8);
4586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(written == 1);
4587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return written;
45883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Use a scratch buffer to check the required characters.
4590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    char temp_buffer[Utf8::kMaxEncodedSize];
4591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Can't encode using last_character as gcc has array bounds issues.
4592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int written = Utf8::Encode(temp_buffer,
4593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               character,
4594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Utf16::kNoPreviousCharacter,
4595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               replace_invalid_utf8);
4596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Won't fit.
4597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (written > remaining) return 0;
4598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Copy over the character from temp_buffer.
4599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int j = 0; j < written; j++) {
4600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      buffer[j] = temp_buffer[j];
4601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return written;
4603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Visit writes out a group of code units (chars) of a v8::String to the
4606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // internal buffer_. This is done in two phases. The first phase calculates a
4607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // pesimistic estimate (writable_length) on how many code units can be safely
4608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // written without exceeding the buffer capacity and without writing the last
4609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // code unit (it could be a lead surrogate). The estimated number of code
4610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // units is then written out in one go, and the reported byte usage is used
4611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to correct the estimate. This is repeated until the estimate becomes <= 0
4612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // or all code units have been written out. The second phase writes out code
4613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // units until the buffer capacity is reached, would be exceeded by the next
4614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // unit, or all units have been written out.
4615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  template<typename Char>
4616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Visit(const Char* chars, const int length) {
4617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    using namespace unibrow;
4618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!early_termination_);
4619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (length == 0) return;
4620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Copy state to stack.
4621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    char* buffer = buffer_;
4622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int last_character =
4623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        sizeof(Char) == 1 ? Utf16::kNoPreviousCharacter : last_character_;
4624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int i = 0;
4625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Do a fast loop where there is no exit capacity check.
4626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (true) {
4627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int fast_length;
4628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (skip_capacity_check_) {
4629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        fast_length = length;
4630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
4631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Need enough space to write everything but one character.
4633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        STATIC_ASSERT(Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
4634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int max_size_per_char =  sizeof(Char) == 1 ? 2 : 3;
4635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int writable_length =
4636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            (remaining_capacity - max_size_per_char)/max_size_per_char;
4637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Need to drop into slow loop.
4638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (writable_length <= 0) break;
4639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        fast_length = i + writable_length;
4640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (fast_length > length) fast_length = length;
46413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Write the characters to the stream.
4643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (sizeof(Char) == 1) {
4644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (; i < fast_length; i++) {
4645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          buffer +=
4646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
4647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
4648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
4649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
4650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        for (; i < fast_length; i++) {
4651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          uint16_t character = *chars++;
4652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          buffer += Utf8::Encode(buffer,
4653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 character,
4654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 last_character,
4655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                 replace_invalid_utf8_);
4656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          last_character = character;
4657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
46583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
46593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Array is fully written. Exit.
4661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (fast_length == length) {
4662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Write state back out to object.
4663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        last_character_ = last_character;
4664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        buffer_ = buffer;
4665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        utf16_chars_read_ += length;
4666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return;
46673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!skip_capacity_check_);
4670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Slow loop. Must check capacity on each iteration.
4671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(remaining_capacity >= 0);
4673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (; i < length && remaining_capacity > 0; i++) {
4674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      uint16_t character = *chars++;
4675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // remaining_capacity is <= 3 bytes at this point, so we do not write out
4676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // an umatched lead surrogate.
4677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (replace_invalid_utf8_ && Utf16::IsLeadSurrogate(character)) {
4678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        early_termination_ = true;
4679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
46803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
4681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int written = WriteEndCharacter(character,
4682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      last_character,
4683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      remaining_capacity,
4684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      buffer,
4685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      replace_invalid_utf8_);
4686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (written == 0) {
4687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        early_termination_ = true;
4688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
4689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      buffer += written;
4691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      remaining_capacity -= written;
4692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      last_character = character;
46933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
4694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Write state back out to object.
4695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_character_ = last_character;
4696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    buffer_ = buffer;
4697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    utf16_chars_read_ += i;
46983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
46993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline bool IsDone() {
4701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return early_termination_;
4702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
47033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
4704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void VisitOneByteString(const uint8_t* chars, int length) {
4705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Visit(chars, length);
4706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  inline void VisitTwoByteString(const uint16_t* chars, int length) {
4709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Visit(chars, length);
4710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
4713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Write out number of utf16 characters written to the stream.
4714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (utf16_chars_read_out != NULL) {
4715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *utf16_chars_read_out = utf16_chars_read_;
4716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Only null terminate if all of the string was written and there's space.
4718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (write_null &&
4719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        !early_termination_ &&
4720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
4721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *buffer_++ = '\0';
4722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
4723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return static_cast<int>(buffer_ - start_);
4724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
4727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool early_termination_;
4728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last_character_;
4729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  char* buffer_;
4730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  char* const start_;
4731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int capacity_;
4732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool const skip_capacity_check_;
4733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool const replace_invalid_utf8_;
4734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int utf16_chars_read_;
4735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
4736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
4737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool RecursivelySerializeToUtf8(i::String* current,
4740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       Utf8WriterVisitor* writer,
4741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                       int recursion_budget) {
4742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!writer->IsDone()) {
4743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::ConsString* cons_string = i::String::VisitFlat(writer, current);
4744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (cons_string == NULL) return true;  // Leaf node.
4745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (recursion_budget <= 0) return false;
4746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Must write the left branch first.
4747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::String* first = cons_string->first();
4748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool success = RecursivelySerializeToUtf8(first,
4749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              writer,
4750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              recursion_budget - 1);
4751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!success) return false;
4752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Inline tail recurse for right branch.
4753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = cons_string->second();
47543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
4755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
4756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
47596ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockint String::WriteUtf8(char* buffer,
47606ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                      int capacity,
47616ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                      int* nchars_ref,
476269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch                      int options) const {
476344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
476444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "String::WriteUtf8");
476544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
476685b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(this);
4767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (options & HINT_MANY_WRITES_EXPECTED) {
4768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    str = i::String::Flatten(str);  // Flatten the string for efficiency.
4769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
4770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const int string_length = str->length();
4771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool write_null = !(options & NO_NULL_TERMINATION);
4772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
4773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
4774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // First check if we can just write the string without checking capacity.
4775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
4776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
47773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const int kMaxRecursion = 100;
4778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
4779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (success) return writer.CompleteWrite(write_null, nchars_ref);
47803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (capacity >= string_length) {
4781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // First check that the buffer is large enough.
4782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
47833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (utf8_bytes <= capacity) {
4784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // one-byte fast path.
4785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (utf8_bytes == string_length) {
4786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
4787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (nchars_ref != NULL) *nchars_ref = string_length;
4788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (write_null && (utf8_bytes+1 <= capacity)) {
4789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          return string_length + 1;
47903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        }
4791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        return string_length;
4792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
4793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (write_null && (utf8_bytes+1 > capacity)) {
4794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        options |= NO_NULL_TERMINATION;
4795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
4796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Recurse once without a capacity limit.
4797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // This will get into the first branch above.
4798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
4799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return WriteUtf8(buffer, -1, nchars_ref, options);
4800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
4801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Recursive slow path can potentially be unreasonable slow. Flatten.
4803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  str = i::String::Flatten(str);
4804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
4805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::String::VisitFlat(&writer, *str);
4806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return writer.CompleteWrite(write_null, nchars_ref);
4807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename CharType>
4811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline int WriteHelper(const String* string,
4812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              CharType* buffer,
4813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              int start,
4814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              int length,
4815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              int options) {
4816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
481744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "String::Write");
481844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
4819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(start >= 0 && length >= -1);
4820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(string);
482144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->string_tracker()->RecordWrite(str);
4822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (options & String::HINT_MANY_WRITES_EXPECTED) {
48236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    // Flatten the string for efficiency.  This applies whether we are
4824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // using StringCharacterStream or Get(i) to access the characters.
4825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    str = i::String::Flatten(str);
48266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
4827b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  int end = start + length;
4828b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if ((length == -1) || (length > str->length() - start) )
4829b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    end = str->length();
4830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (end < 0) return 0;
4831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::String::WriteToFlat(*str, buffer, start, end);
4832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!(options & String::NO_NULL_TERMINATION) &&
483369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch      (length == -1 || end - start < length)) {
4834b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    buffer[end - start] = '\0';
4835b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
4836b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return end - start;
4837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4839a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint String::WriteOneByte(uint8_t* buffer,
4841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int start,
4842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int length,
4843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         int options) const {
4844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return WriteHelper(this, buffer, start, length, options);
4845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint String::Write(uint16_t* buffer,
4849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  int start,
4850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  int length,
4851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  int options) const {
4852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return WriteHelper(this, buffer, start, length, options);
4853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4856a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::String::IsExternal() const {
4857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> str = Utils::OpenHandle(this);
4858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return i::StringShape(*str).IsExternalTwoByte();
4859a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4860a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4861a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::String::IsExternalOneByte() const {
4863a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> str = Utils::OpenHandle(this);
4864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::StringShape(*str).IsExternalOneByte();
4865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4866a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::String::VerifyExternalStringResource(
4869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::String::ExternalStringResource* value) const {
4870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> str = Utils::OpenHandle(this);
48713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  const v8::String::ExternalStringResource* expected;
4872a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (i::StringShape(*str).IsExternalTwoByte()) {
48733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const void* resource =
48743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
48753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    expected = reinterpret_cast<const ExternalStringResource*>(resource);
4876a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    expected = NULL;
4878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4879a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CHECK_EQ(expected, value);
4880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4881a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::String::VerifyExternalStringResourceBase(
4883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
4884a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> str = Utils::OpenHandle(this);
4885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const v8::String::ExternalStringResourceBase* expected;
4886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Encoding expectedEncoding;
4887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::StringShape(*str).IsExternalOneByte()) {
4888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const void* resource =
4889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::ExternalOneByteString>::cast(str)->resource();
4890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expectedEncoding = ONE_BYTE_ENCODING;
4892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (i::StringShape(*str).IsExternalTwoByte()) {
4893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const void* resource =
4894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expectedEncoding = TWO_BYTE_ENCODING;
4897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
4898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expected = NULL;
4899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    expectedEncoding =
4900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
490144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
4902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_EQ(expected, value);
4903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK_EQ(expectedEncoding, encoding);
4904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst v8::String::ExternalOneByteStringResource*
4907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::String::GetExternalOneByteStringResource() const {
4908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> str = Utils::OpenHandle(this);
4909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::StringShape(*str).IsExternalOneByte()) {
49103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    const void* resource =
4911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Handle<i::ExternalOneByteString>::cast(str)->resource();
4912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
4913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return NULL;
4915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> Symbol::Name() const {
4920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
4921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
4922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(name);
4923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> Private::Name() const {
4927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const Symbol*>(this)->Name();
4928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4931a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockdouble Number::Value() const {
4932a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
4933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return obj->Number();
4934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4936a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4937a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool Boolean::Value() const {
4938a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
4939a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return obj->IsTrue();
4940a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4943a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint64_t Integer::Value() const {
4944a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
4945a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
4946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return i::Smi::cast(*obj)->value();
4947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return static_cast<int64_t>(obj->Number());
4949a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4950a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4951a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint32_t Int32::Value() const {
4954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
4955a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (obj->IsSmi()) {
4956a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return i::Smi::cast(*obj)->value();
4957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
4958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return static_cast<int32_t>(obj->Number());
4959a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
4960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
49636ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockuint32_t Uint32::Value() const {
49646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
49656ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (obj->IsSmi()) {
49666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return i::Smi::cast(*obj)->value();
49676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
49686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return static_cast<uint32_t>(obj->Number());
49696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
49706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
49716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
49726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint v8::Object::InternalFieldCount() {
4974a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4975a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return obj->GetInternalFieldCount();
4976a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4977a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4978a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic bool InternalFieldOK(i::Handle<i::JSObject> obj,
4980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            int index,
4981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            const char* location) {
4982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ApiCheck(index < obj->GetInternalFieldCount(),
4983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         location,
4984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         "Internal field out of bounds");
4985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
4986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
4988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Value> v8::Object::SlowGetInternalField(int index) {
4989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Object::GetInternalField()";
4991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!InternalFieldOK(obj, index, location)) return Local<Value>();
4992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
4993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(value);
4994a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
4995a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4997a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
4998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Object::SetInternalField()";
5000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!InternalFieldOK(obj, index, location)) return;
5001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> val = Utils::OpenHandle(*value);
5002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  obj->SetInternalField(index, *val);
5003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(value, GetInternalField(index));
5004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
5009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!InternalFieldOK(obj, index, location)) return NULL;
5011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return DecodeSmiToAligned(obj->GetInternalField(index), location);
5012b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
5013b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5014b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
5017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!InternalFieldOK(obj, index, location)) return;
5019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
5020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
5021b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
5022b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5023b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic void* ExternalValue(i::Object* obj) {
5025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Obscure semantics for undefined, but somehow checked in our unit tests...
5026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsUndefined()) return NULL;
5027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
5028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::Foreign::cast(foreign)->foreign_address();
5029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// --- E n v i r o n m e n t ---
5033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
503444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
5035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::V8::InitializePlatform(Platform* platform) {
5036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::V8::InitializePlatform(platform);
5037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::V8::ShutdownPlatform() {
5041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::V8::ShutdownPlatform();
5042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::V8::Initialize() {
5046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::V8::Initialize();
5047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
5048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::V8::SetEntropySource(EntropySource entropy_source) {
5052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  base::RandomNumberGenerator::SetEntropySource(entropy_source);
50533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
50543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
50553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
50563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid v8::V8::SetReturnAddressLocationResolver(
5057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ReturnAddressLocationResolver return_address_resolver) {
50583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::V8::SetReturnAddressLocationResolver(return_address_resolver);
50593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
50603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::V8::SetArrayBufferAllocator(
5062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ArrayBuffer::Allocator* allocator) {
5063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(i::V8::ArrayBufferAllocator() == NULL,
5064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::V8::SetArrayBufferAllocator",
5065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "ArrayBufferAllocator might only be set once"))
5066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
5067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::V8::SetArrayBufferAllocator(allocator);
5068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5071a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::V8::Dispose() {
5072a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::V8::TearDown();
5073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
5074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
507790bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell BrennerHeapStatistics::HeapStatistics(): total_heap_size_(0),
507890bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner                                  total_heap_size_executable_(0),
5079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  total_physical_size_(0),
5080b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                  used_heap_size_(0),
5081b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch                                  heap_size_limit_(0) { }
50823ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
50833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
50843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvoid v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
50853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
50863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  isolate->heap()->VisitExternalResources(visitor);
50873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
50883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
50893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass VisitorAdapter : public i::ObjectVisitor {
5091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
5092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  explicit VisitorAdapter(PersistentHandleVisitor* visitor)
5093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      : visitor_(visitor) {}
5094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void VisitPointers(i::Object** start, i::Object** end) {
5095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
5096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
5098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Value* value = ToApi<Value>(i::Handle<i::Object>(p));
5099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    visitor_->VisitPersistentHandle(
5100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        reinterpret_cast<Persistent<Value>*>(&value), class_id);
5101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private:
5103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PersistentHandleVisitor* visitor_;
5104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
5105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
510844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
5109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DisallowHeapAllocation no_allocation;
5110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitorAdapter visitor_adapter(visitor);
5112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
5113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::V8::VisitHandlesForPartialDependence(
5117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
5118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
5119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(isolate == i::Isolate::Current());
5120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DisallowHeapAllocation no_allocation;
5121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VisitorAdapter visitor_adapter(visitor);
5123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
5124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      &visitor_adapter);
51256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
51266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
51276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::V8::InitializeICU(const char* icu_data_file) {
5129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::InitializeICU(icu_data_file);
5130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5132a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* v8::V8::GetVersion() {
5134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::Version::GetVersion();
5135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5137a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::Context> CreateEnvironment(
5139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
5140a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::ExtensionConfiguration* extensions,
5141a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<ObjectTemplate> global_template,
5142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Value> maybe_global_proxy) {
5143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> env;
5144a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5145a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Enter V8 via an ENTER_V8 scope.
5146a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
514744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ENTER_V8(isolate);
5148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v8::Handle<ObjectTemplate> proxy_template = global_template;
5149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    i::Handle<i::FunctionTemplateInfo> global_constructor;
5151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!global_template.IsEmpty()) {
5153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Make sure that the global_template has a constructor.
5154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      global_constructor = EnsureConstructor(isolate, *global_template);
5155a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Create a fresh template for the global proxy object.
5157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      proxy_template = ObjectTemplate::New(
5158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          reinterpret_cast<v8::Isolate*>(isolate));
5159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      proxy_constructor = EnsureConstructor(isolate, *proxy_template);
5160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Set the global template to be the prototype template of
5162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // global proxy template.
5163a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      proxy_constructor->set_prototype_template(
5164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          *Utils::OpenHandle(*global_template));
5165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Migrate security handlers from global_template to
5167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // proxy_template.  Temporarily removing access check
5168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // information from the global template.
5169a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (!global_constructor->access_check_info()->IsUndefined()) {
5170a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        proxy_constructor->set_access_check_info(
5171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            global_constructor->access_check_info());
5172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        proxy_constructor->set_needs_access_check(
5173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block            global_constructor->needs_access_check());
5174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        global_constructor->set_needs_access_check(false);
517544f0eee88ff00398ff7f715fab053374d808c90dSteve Block        global_constructor->set_access_check_info(
517644f0eee88ff00398ff7f715fab053374d808c90dSteve Block            isolate->heap()->undefined_value());
5177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
5178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
5179a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> proxy = Utils::OpenHandle(*maybe_global_proxy, true);
5181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
5182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!proxy.is_null()) {
5183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(proxy);
5184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
5185a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Create the environment.
518644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    env = isolate->bootstrapper()->CreateEnvironment(
5187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        maybe_proxy, proxy_template, extensions);
5188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Restore the access check info on the global template.
5190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (!global_template.IsEmpty()) {
5191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!global_constructor.is_null());
5192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!proxy_constructor.is_null());
5193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      global_constructor->set_access_check_info(
5194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          proxy_constructor->access_check_info());
5195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      global_constructor->set_needs_access_check(
5196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block          proxy_constructor->needs_access_check());
5197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
5198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
5199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Leave V8.
5200a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return env;
5202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Context> v8::Context::New(
5205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Isolate* external_isolate,
5206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::ExtensionConfiguration* extensions,
5207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<ObjectTemplate> global_template,
5208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<Value> global_object) {
5209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Context::New");
5211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
5212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
5213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExtensionConfiguration no_extensions;
5214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (extensions == NULL) extensions = &no_extensions;
5215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> env =
5216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      CreateEnvironment(isolate, extensions, global_template, global_object);
5217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (env.is_null()) return Local<Context>();
5218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(scope.CloseAndEscape(env));
5219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Context::SetSecurityToken(Handle<Value> token) {
522344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
522444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
5225a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Context> env = Utils::OpenHandle(this);
5226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
5227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  env->set_security_token(*token_handle);
5228a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid v8::Context::UseDefaultSecurityToken() {
523244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
523344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
5234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Context> env = Utils::OpenHandle(this);
5235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  env->set_security_token(env->global_object());
5236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5237a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5238a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5239a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockHandle<Value> v8::Context::GetSecurityToken() {
524044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
5241a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Context> env = Utils::OpenHandle(this);
5242a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Object* security_token = env->security_token();
5243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> token_handle(security_token, isolate);
5244a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(token_handle);
5245a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5246a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5247a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Isolate* Context::GetIsolate() {
5249a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Context> env = Utils::OpenHandle(this);
5250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<Isolate*>(env->GetIsolate());
5251a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5253a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5254a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockv8::Local<v8::Object> Context::Global() {
5255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> context = Utils::OpenHandle(this);
5256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = context->GetIsolate();
5257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> global(context->global_proxy(), isolate);
5258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(dcarney): This should always return the global proxy
5259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // but can't presently as calls to GetProtoype will return the wrong result.
5260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::Handle<i::JSGlobalProxy>::cast(
5261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          global)->IsDetachedFrom(context->global_object())) {
5262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    global = i::Handle<i::Object>(context->global_object(), isolate);
526344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
5264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5268a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid Context::DetachGlobal() {
5269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> context = Utils::OpenHandle(this);
5270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = context->GetIsolate();
527144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
527244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->bootstrapper()->DetachGlobal(context);
5273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5274a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5275a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5276257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdochvoid Context::AllowCodeGenerationFromStrings(bool allow) {
5277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> context = Utils::OpenHandle(this);
5278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = context->GetIsolate();
5279257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  ENTER_V8(isolate);
5280257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  context->set_allow_code_gen_from_strings(
5281257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5282257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
5283257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
5284257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
52853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochbool Context::IsCodeGenerationFromStringsAllowed() {
5286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> context = Utils::OpenHandle(this);
52873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return !context->allow_code_gen_from_strings()->IsFalse();
52883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
52893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
52903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Context::SetErrorMessageForCodeGenerationFromStrings(
5292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<String> error) {
5293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Context> context = Utils::OpenHandle(this);
5294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
5295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  context->set_error_message_for_code_gen_from_strings(*error_handle);
529674b3c146906ea120f97974b0e16aec75c17ebf66Andrei Popescu}
529774b3c146906ea120f97974b0e16aec75c17ebf66Andrei Popescu
529874b3c146906ea120f97974b0e16aec75c17ebf66Andrei Popescu
5299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<v8::Object> ObjectTemplate::NewInstance() {
530044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
530144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
530244f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return Local<v8::Object>());
530344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "ObjectTemplate::NewInstance");
530444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
530544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
5306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj;
5307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::InstantiateObject(
5308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(this)).ToHandle(&obj);
530944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
5310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
5311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<v8::Function> FunctionTemplate::GetFunction() {
531544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
531644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
5317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block             return Local<v8::Function>());
531844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "FunctionTemplate::GetFunction");
531944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
532044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
5321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj;
5322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::InstantiateFunction(
5323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(this)).ToHandle(&obj);
532444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
5325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
5326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
533044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
533144f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return false);
5332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Object* obj = *Utils::OpenHandle(*value);
5333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->IsTemplateFor(obj);
5334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<External> v8::External::New(Isolate* isolate, void* value) {
5338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
5339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "External::New");
5341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
5343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ExternalToLocal(external);
5344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid* External::Value() const {
5348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ExternalValue(*Utils::OpenHandle(this));
5349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5351b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// anonymous namespace for string creation helper functions
5353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace {
5354b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
5355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline int StringLength(const char* string) {
5356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::StrLength(string);
5357a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5359a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline int StringLength(const uint8_t* string) {
5361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::StrLength(reinterpret_cast<const char*>(string));
53623ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
53633ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
53643ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
5365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline int StringLength(const uint16_t* string) {
5366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int length = 0;
5367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (string[length] != '\0')
5368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    length++;
5369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return length;
5370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMUST_USE_RESULT
5374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           String::NewStringType type,
5376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           i::Vector<const char> string) {
5377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == String::kInternalizedString) {
5378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return factory->InternalizeUtf8String(string);
5379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return factory->NewStringFromUtf8(string);
5381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMUST_USE_RESULT
5385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           String::NewStringType type,
5387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           i::Vector<const uint8_t> string) {
5388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == String::kInternalizedString) {
5389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return factory->InternalizeOneByteString(string);
5390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return factory->NewStringFromOneByte(string);
5392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochMUST_USE_RESULT
5396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           String::NewStringType type,
5398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           i::Vector<const uint16_t> string) {
5399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == String::kInternalizedString) {
5400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return factory->InternalizeTwoByteString(string);
5401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return factory->NewStringFromTwoByte(string);
5403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename Char>
5407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochinline Local<String> NewString(Isolate* v8_isolate,
5408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               const char* location,
5409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               const char* env,
5410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               const Char* data,
5411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               String::NewStringType type,
5412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               int length) {
5413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
5414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, env);
5415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == 0 && type != String::kUndetectableString) {
5416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return String::Empty(v8_isolate);
5417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
541844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
5419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (length == -1) length = StringLength(data);
5420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not expect this to fail. Change this if it does.
5421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> result = NewString(
5422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory(),
5423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      type,
5424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Vector<const Char>(data, length)).ToHandleChecked();
5425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == String::kUndetectableString) {
5426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->MarkAsUndetectable();
5427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
5429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}  // anonymous namespace
54323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
54333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
5434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<String> String::NewFromUtf8(Isolate* isolate,
5435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  const char* data,
5436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  NewStringType type,
5437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int length) {
5438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewString(isolate,
5439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "v8::String::NewFromUtf8()",
5440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "String::NewFromUtf8",
5441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   data,
5442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   type,
5443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   length);
5444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5446a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<String> String::NewFromOneByte(Isolate* isolate,
5448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     const uint8_t* data,
5449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     NewStringType type,
5450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     int length) {
5451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewString(isolate,
5452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "v8::String::NewFromOneByte()",
5453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "String::NewFromOneByte",
5454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   data,
5455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   type,
5456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   length);
5457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<String> String::NewFromTwoByte(Isolate* isolate,
5461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     const uint16_t* data,
5462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     NewStringType type,
5463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     int length) {
5464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return NewString(isolate,
5465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "v8::String::NewFromTwoByte()",
5466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   "String::NewFromTwoByte",
5467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   data,
5468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   type,
5469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   length);
5470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
5474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> left_string = Utils::OpenHandle(*left);
5475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = left_string->GetIsolate();
5476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "String::New(char)");
547744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
5478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> right_string = Utils::OpenHandle(*right);
5479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not expect this to fail. Change this if it does.
5480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> result = isolate->factory()->NewConsString(
5481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      left_string, right_string).ToHandleChecked();
5482a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
5483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::String> NewExternalStringHandle(
5487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
5488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::String::ExternalStringResource* resource) {
5489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not expect this to fail. Change this if it does.
5490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->factory()->NewExternalStringFromTwoByte(
5491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      resource).ToHandleChecked();
5492a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::String> NewExternalOneByteStringHandle(
5496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We do not expect this to fail. Change this if it does.
5498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->factory()
5499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ->NewExternalStringFromOneByte(resource)
5500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      .ToHandleChecked();
5501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<String> v8::String::NewExternal(
5505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
5506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::String::ExternalStringResource* resource) {
5507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "String::NewExternal");
5509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(resource && resource->data());
5511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource);
5512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->heap()->external_string_table()->AddString(*result);
5513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
5514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
5518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> obj = Utils::OpenHandle(this);
551944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = obj->GetIsolate();
5520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::StringShape(*obj).IsExternal()) {
552144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return false;  // Already an external string.
552244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
552344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
552444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
552544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return false;
552644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
55273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (isolate->heap()->IsInGCPostProcessing()) {
55283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return false;
55293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
5530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(resource && resource->data());
5531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result = obj->MakeExternal(resource);
5533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!CanMakeExternal() || result);
5535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (result) {
5536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(obj->IsExternalString());
553744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->heap()->external_string_table()->AddString(*obj);
5538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
5539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
5540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5543a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<String> v8::String::NewExternal(
5544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "String::NewExternal");
5547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(resource && resource->data());
5549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> result =
5550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      NewExternalOneByteStringHandle(i_isolate, resource);
5551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->heap()->external_string_table()->AddString(*result);
5552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
5553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5556a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::String::MakeExternal(
5557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::String::ExternalOneByteStringResource* resource) {
5558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> obj = Utils::OpenHandle(this);
555944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = obj->GetIsolate();
5560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::StringShape(*obj).IsExternal()) {
556144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return false;  // Already an external string.
556244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
556344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
556444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
556544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return false;
556644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
55673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  if (isolate->heap()->IsInGCPostProcessing()) {
55683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch    return false;
55693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  }
5570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(resource && resource->data());
5571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool result = obj->MakeExternal(resource);
5573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!CanMakeExternal() || result);
5575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (result) {
5576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(obj->IsExternalString());
557744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    isolate->heap()->external_string_table()->AddString(*obj);
5578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
5579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return result;
5580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool v8::String::CanMakeExternal() {
55843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!internal::FLAG_clever_optimizations) return false;
5585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::String> obj = Utils::OpenHandle(this);
558644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = obj->GetIsolate();
5587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
55883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
5589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size = obj->Size();  // Byte size of the original string.
55903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (size < i::ExternalString::kShortSize) return false;
5591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::StringShape shape(*obj);
5592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return !shape.IsExternal();
5593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Object> v8::Object::New(Isolate* isolate) {
5597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "Object::New");
5599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSObject> obj =
5601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate->factory()->NewJSObject(i_isolate->object_function());
5602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(obj);
5603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
5607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "NumberObject::New");
5609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
5611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj =
5612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::ToObject(i_isolate, number).ToHandleChecked();
56133fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return Utils::ToLocal(obj);
56143fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
56153fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56163fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdouble v8::NumberObject::ValueOf() const {
56183fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this);
56193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = jsvalue->GetIsolate();
5621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "NumberObject::NumberValue");
56223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return jsvalue->value()->Number();
56233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
56243fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56253fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56263fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLocal<v8::Value> v8::BooleanObject::New(bool value) {
56273fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Isolate* isolate = i::Isolate::Current();
56283fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LOG_API(isolate, "BooleanObject::New");
56293fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ENTER_V8(isolate);
5630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> boolean(value
5631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               ? isolate->heap()->true_value()
5632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               : isolate->heap()->false_value(),
5633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               isolate);
5634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj =
5635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::ToObject(isolate, boolean).ToHandleChecked();
56363fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return Utils::ToLocal(obj);
56373fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
56383fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56393fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::BooleanObject::ValueOf() const {
56413fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this);
56423fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = jsvalue->GetIsolate();
5644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "BooleanObject::BooleanValue");
56453fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return jsvalue->value()->IsTrue();
56463fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
56473fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56493fb3ca8c7ca439d408449a395897395c0faae8d1Ben MurdochLocal<v8::Value> v8::StringObject::New(Handle<String> value) {
5650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> string = Utils::OpenHandle(*value);
5651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = string->GetIsolate();
56523fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  LOG_API(isolate, "StringObject::New");
56533fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  ENTER_V8(isolate);
56543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj =
5655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::ToObject(isolate, string).ToHandleChecked();
56563fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return Utils::ToLocal(obj);
56573fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
56583fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56593fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::String> v8::StringObject::ValueOf() const {
56613fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this);
56623fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = jsvalue->GetIsolate();
5664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "StringObject::StringValue");
56653fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return Utils::ToLocal(
56663fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch      i::Handle<i::String>(i::String::cast(jsvalue->value())));
56673fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
56683fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
56693fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
5670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
5671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "SymbolObject::New");
5673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = i::Object::ToObject(
5675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
5676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(obj);
5677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Symbol> v8::SymbolObject::ValueOf() const {
5681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(this);
5682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = jsvalue->GetIsolate();
5684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "SymbolObject::SymbolValue");
5685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(
5686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
5687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Value> v8::Date::New(Isolate* isolate, double time) {
5691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "Date::New");
5693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (std::isnan(time)) {
5694d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    time = base::OS::nan_value();
5696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(i_isolate);
5699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj;
5700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::NewDate(
5701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate, time).ToHandle(&obj);
5702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::Value>());
5703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(obj);
5704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdouble v8::Date::ValueOf() const {
5708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::Object> obj = Utils::OpenHandle(this);
57093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
5710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = jsdate->GetIsolate();
5711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Date::NumberValue");
57123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return jsdate->value()->Number();
5713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
5717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!i_isolate->IsInitialized()) return;
5719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
572044f0eee88ff00398ff7f715fab053374d808c90dSteve Block             return);
5721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
5722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
5723b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->date_cache()->ResetDateCache();
57253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!i_isolate->eternal_handles()->Exists(
5727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          i::EternalHandles::DATE_CACHE_VERSION)) {
5728b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    return;
5729b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
5730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::FixedArray> date_cache_version =
5731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
5732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          i::EternalHandles::DATE_CACHE_VERSION));
5733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_EQ(1, date_cache_version->length());
5734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(date_cache_version->get(0)->IsSmi());
5735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  date_cache_version->set(
5736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0,
5737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1));
5738b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
5739b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5740b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5741f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochstatic i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
5742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
5743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  uint8_t flags_buf[3];
5744f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  int num_flags = 0;
5745f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
5746f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
5747f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
5748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(num_flags <= static_cast<int>(arraysize(flags_buf)));
5749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->factory()->InternalizeOneByteString(
5750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Vector<const uint8_t>(flags_buf, num_flags));
5751f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
5752f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5753f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5754f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochLocal<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
5755f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch                                  Flags flags) {
575644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
575744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  LOG_API(isolate, "RegExp::New");
575844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
575944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
5760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSRegExp> obj;
5761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::NewJSRegExp(
5762f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch      Utils::OpenHandle(*pattern),
5763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      RegExpFlagsToString(flags)).ToHandle(&obj);
576444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
5765f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
5766f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
5767f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5768f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5769f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochLocal<v8::String> v8::RegExp::GetSource() const {
5770f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5771f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
5772f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
5773f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5774f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5775f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch// Assert that the static flags cast in GetFlags is valid.
5776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag)          \
5777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) ==       \
5778f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch                static_cast<int>(i::JSRegExp::internal_flag))
5779f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochREGEXP_FLAG_ASSERT_EQ(kNone, NONE);
5780f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochREGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
5781f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochREGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
5782f87a203d89e1bbb6708282e0b64dbd13d59b723dBen MurdochREGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
5783f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#undef REGEXP_FLAG_ASSERT_EQ
5784f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5785f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdochv8::RegExp::Flags v8::RegExp::GetFlags() const {
5786f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5787f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  return static_cast<RegExp::Flags>(obj->GetFlags().value());
5788f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch}
5789f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5790f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
5791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<v8::Array> v8::Array::New(Isolate* isolate, int length) {
5792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "Array::New");
5794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
579544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  int real_length = length > 0 ? length : 0;
5796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
57978b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  i::Handle<i::Object> length_obj =
5798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate->factory()->NewNumberFromInt(real_length);
57998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  obj->set_length(*length_obj);
5800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(obj);
5801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5802a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5804a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockuint32_t v8::Array::Length() const {
5805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
5806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  i::Object* length = obj->length();
5807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (length->IsSmi()) {
5808a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return i::Smi::cast(length)->value();
5809a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
5810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return static_cast<uint32_t>(length->Number());
5811a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
5812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
5813a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5814a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Object> Array::CloneElementAt(uint32_t index) {
5816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
5817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
5818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> self = Utils::OpenHandle(this);
5819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!self->HasFastObjectElements()) {
5820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Local<Object>();
5821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::FixedArray* elms = i::FixedArray::cast(self->elements());
5823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Object* paragon = elms->get(index);
5824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!paragon->IsJSObject()) {
5825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Local<Object>();
5826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
5827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
5828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> result =
5831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->CopyJSObject(paragon_handle);
5832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = result.is_null();
5833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
5834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(result);
5835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Value::IsPromise() const {
5839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> val = Utils::OpenHandle(this);
5840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!val->IsJSObject()) return false;
5841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> obj = i::Handle<i::JSObject>::cast(val);
5842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = obj->GetIsolate();
5843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "IsPromise");
5844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> argv[] = { obj };
5847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> b;
5848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
5849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate,
5850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->is_promise(),
5851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->undefined_value(),
5852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arraysize(argv), argv,
5853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false).ToHandle(&b);
5854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, false);
5855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return b->BooleanValue();
5856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Promise::Resolver> Promise::Resolver::New(Isolate* v8_isolate) {
5860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Promise::Resolver::New");
5862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
5865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
5866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate,
5867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->promise_create(),
5868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->undefined_value(),
5869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      0, NULL,
5870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false).ToHandle(&result);
5871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise::Resolver>());
5872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Local<Promise::Resolver>::Cast(Utils::ToLocal(result));
5873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Promise> Promise::Resolver::GetPromise() {
5877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Local<Promise>::Cast(Utils::ToLocal(promise));
5879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Promise::Resolver::Resolve(Handle<Value> value) {
5883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = promise->GetIsolate();
5885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Promise::Resolver::Resolve");
5886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
5889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = i::Execution::Call(
5890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate,
5891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->promise_resolve(),
5892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->undefined_value(),
5893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arraysize(argv), argv,
5894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false).is_null();
5895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
5896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Promise::Resolver::Reject(Handle<Value> value) {
5900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = promise->GetIsolate();
5902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Promise::Resolver::Reject");
5903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
5906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = i::Execution::Call(
5907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate,
5908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->promise_reject(),
5909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->undefined_value(),
5910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arraysize(argv), argv,
5911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false).is_null();
5912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
5913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Promise> Promise::Chain(Handle<Function> handler) {
5917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = promise->GetIsolate();
5919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Promise::Chain");
5920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
5924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
5925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate,
5926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->promise_chain(),
5927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      promise,
5928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arraysize(argv), argv,
5929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false).ToHandle(&result);
5930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
5931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Local<Promise>::Cast(Utils::ToLocal(result));
5932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Promise> Promise::Catch(Handle<Function> handler) {
5936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = promise->GetIsolate();
5938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Promise::Catch");
5939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
5943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
5944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate,
5945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->promise_catch(),
5946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      promise,
5947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arraysize(argv), argv,
5948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false).ToHandle(&result);
5949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
5950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Local<Promise>::Cast(Utils::ToLocal(result));
5951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Promise> Promise::Then(Handle<Function> handler) {
5955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = promise->GetIsolate();
5957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "Promise::Then");
5958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
5959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_PREAMBLE(isolate);
5960b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
5962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !i::Execution::Call(
5963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate,
5964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->promise_then(),
5965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      promise,
5966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      arraysize(argv), argv,
5967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false).ToHandle(&result);
5968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
5969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Local<Promise>::Cast(Utils::ToLocal(result));
5970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::ArrayBuffer::IsExternal() const {
5974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::OpenHandle(this)->is_external();
5975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
5979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(!obj->is_external(),
5981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::ArrayBuffer::Externalize",
5982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "ArrayBuffer already externalized");
5983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_is_external(true);
5984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
5985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Contents contents;
5986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  contents.data_ = obj->backing_store();
5987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  contents.byte_length_ = byte_length;
5988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return contents;
5989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
5990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::ArrayBuffer::Neuter() {
5993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = obj->GetIsolate();
5995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(obj->is_external(),
5996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::ArrayBuffer::Neuter",
5997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Only externalized ArrayBuffers can be neutered");
5998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
5999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
6000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Runtime::NeuterArrayBuffer(obj);
6001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t v8::ArrayBuffer::ByteLength() const {
6005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<size_t>(obj->byte_length()->Number());
6007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
6011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
6013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
6014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> obj =
6015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate->factory()->NewJSArrayBuffer();
6016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length);
6017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(obj);
6018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
6022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        size_t byte_length) {
6023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
6025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
6026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> obj =
6027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i_isolate->factory()->NewJSArrayBuffer();
6028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
6029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(obj);
6030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<ArrayBuffer> v8::ArrayBufferView::Buffer() {
6034b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> buffer;
6036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj->IsJSDataView()) {
6037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj));
6038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(data_view->buffer()->IsJSArrayBuffer());
6039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()));
6040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
6041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(obj->IsJSTypedArray());
6042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    buffer = i::JSTypedArray::cast(*obj)->GetBuffer();
6043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(buffer);
6045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t v8::ArrayBufferView::ByteOffset() {
6049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<size_t>(obj->byte_offset()->Number());
6051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t v8::ArrayBufferView::ByteLength() {
6055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<size_t>(obj->byte_length()->Number());
6057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t v8::TypedArray::Length() {
6061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
6062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<size_t>(obj->length()->Number());
6063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline void SetupArrayBufferView(
6067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
6068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::JSArrayBufferView> obj,
6069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::JSArrayBuffer> buffer,
6070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size_t byte_offset,
6071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    size_t byte_length) {
6072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(byte_offset + byte_length <=
6073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         static_cast<size_t>(buffer->byte_length()->Number()));
6074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_buffer(*buffer);
6076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_weak_next(buffer->weak_first_view());
6078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  buffer->set_weak_first_view(*obj);
6079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6080b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> byte_offset_object =
6081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewNumberFromSize(byte_offset);
6082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_byte_offset(*byte_offset_object);
6083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> byte_length_object =
6085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewNumberFromSize(byte_length);
6086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_byte_length(*byte_length_object);
6087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochtemplate<typename ElementType,
6090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         ExternalArrayType array_type,
6091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         i::ElementsKind elements_kind>
6092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochi::Handle<i::JSTypedArray> NewTypedArray(
6093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate,
6094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
6095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSTypedArray> obj =
6096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewJSTypedArray(array_type);
6097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(byte_offset % sizeof(ElementType) == 0);
6100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
6102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(length <= static_cast<size_t>(i::Smi::kMaxValue));
6103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t byte_length = length * sizeof(ElementType);
6104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetupArrayBufferView(
6105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, obj, buffer, byte_offset, byte_length);
6106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> length_object =
6108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewNumberFromSize(length);
6109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj->set_length(*length_object);
6110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::ExternalArray> elements =
6112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->NewExternalArray(
6113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<int>(length), array_type,
6114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
6115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Map> map =
6116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::JSObject::GetElementsTransitionMap(obj, elements_kind);
6117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::JSObject::SetMapAndElements(obj, map, elements);
6118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return obj;
6119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size)                       \
6123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer,      \
6124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    size_t byte_offset, size_t length) {     \
6125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate();    \
6126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOG_API(isolate,                                                         \
6127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)");     \
6128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ENTER_V8(isolate);                                                       \
6129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue),   \
6130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)",  \
6131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            "length exceeds max allowed value")) {                           \
6132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return Local<Type##Array>();                                          \
6133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }                                                                        \
6134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::JSTypedArray> obj =                                         \
6135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        NewTypedArray<ctype, v8::kExternal##Type##Array,                     \
6136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      i::EXTERNAL_##TYPE##_ELEMENTS>(                        \
6137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            isolate, array_buffer, byte_offset, length);                     \
6138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Utils::ToLocal##Type##Array(obj);                                 \
6139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochTYPED_ARRAYS(TYPED_ARRAY_NEW)
6143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef TYPED_ARRAY_NEW
6144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
6146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              size_t byte_offset, size_t byte_length) {
6147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = buffer->GetIsolate();
6149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
6150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
6151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
6152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetupArrayBufferView(
6153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate, obj, buffer, byte_offset, byte_length);
6154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(obj);
6155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
6159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "Symbol::New()");
6161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
6162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
6164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(result);
6165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
6169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      i::Handle<i::String> name,
6170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                      i::Handle<i::String> part) {
6171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
6172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> symbols =
6173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::JSObject>::cast(
6174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> symbol =
6176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
6177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!symbol->IsSymbol()) {
6178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(symbol->IsUndefined());
6179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    symbol = isolate->factory()->NewSymbol();
6180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
6181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert();
6182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return i::Handle<i::Symbol>::cast(symbol);
6184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
6188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> part = i_isolate->factory()->for_string();
6191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
6196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> part = i_isolate->factory()->for_api_string();
6199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic Local<Symbol> GetWellKnownSymbol(Isolate* isolate, const char* name) {
6204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> i_name =
6206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Utils::OpenHandle(*String::NewFromUtf8(isolate, name));
6207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> part = i_isolate->factory()->for_intern_string();
6208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
6213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetWellKnownSymbol(isolate, "Symbol.iterator");
6214a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6215a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6216a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
6218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return GetWellKnownSymbol(isolate, "Symbol.unscopables");
6219a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6220a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6221a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
6223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LOG_API(i_isolate, "Private::New()");
6225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(i_isolate);
6226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
6227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
6228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<Symbol> result = Utils::ToLocal(symbol);
6229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
6230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
6234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
6237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> part = i_isolate->factory()->private_api_string();
6238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::JSObject> privates =
6239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::JSObject>::cast(
6240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> symbol =
6242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Object::GetPropertyOrElement(privates, i_name).ToHandleChecked();
6243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!symbol->IsSymbol()) {
6244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(symbol->IsUndefined());
6245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    symbol = i_isolate->factory()->NewPrivateSymbol();
6246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
6247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::JSObject::SetProperty(privates, i_name, symbol, i::STRICT).Assert();
6248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<Symbol> result = Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
6250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
6251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Number> v8::Number::New(Isolate* isolate, double value) {
6255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(internal_isolate->IsInitialized());
6257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (std::isnan(value)) {
6258d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    value = base::OS::nan_value();
6260d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
6261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(internal_isolate);
6262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
6263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::NumberToLocal(result);
6264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
6268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(internal_isolate->IsInitialized());
6270a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (i::Smi::IsValid(value)) {
627144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
6272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                      internal_isolate));
6273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(internal_isolate);
6275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
6276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::IntegerToLocal(result);
6277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLocal<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
6281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(internal_isolate->IsInitialized());
62833ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  bool fits_into_int32_t = (value & (1 << 31)) == 0;
62843ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  if (fits_into_int32_t) {
6285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Integer::New(isolate, static_cast<int32_t>(value));
62863ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
6287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(internal_isolate);
6288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
62893ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  return Utils::IntegerToLocal(result);
62903ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block}
62913ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
62923ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockbool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
629444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
629544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
629644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
629744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
629844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  NeanderArray listeners(isolate->factory()->message_listeners());
6299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NeanderObject obj(isolate, 2);
6300257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
6301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
6302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : *Utils::OpenHandle(*data));
6303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  listeners.add(obj.value());
6304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return true;
6305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid V8::RemoveMessageListeners(MessageCallback that) {
630944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
631044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
631144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
631244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
631344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  NeanderArray listeners(isolate->factory()->message_listeners());
6314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = 0; i < listeners.length(); i++) {
6315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (listeners.get(i)->IsUndefined()) continue;  // skip deleted ones
6316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    NeanderObject listener(i::JSObject::cast(listeners.get(i)));
6318257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
63193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
632044f0eee88ff00398ff7f715fab053374d808c90dSteve Block      listeners.set(i, isolate->heap()->undefined_value());
6321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
6322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
63263bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochvoid V8::SetCaptureStackTraceForUncaughtExceptions(
6327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool capture,
6328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int frame_limit,
6329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    StackTrace::StackTraceOptions options) {
633044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
63313bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      capture,
63323bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      frame_limit,
63333bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch      options);
63343bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
63353bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
63363bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
6337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::SetFailedAccessCheckCallbackFunction(
6338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    FailedAccessCheckCallback callback) {
6339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
6340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->SetFailedAccessCheckCallback(callback);
6341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::CollectAllGarbage(const char* gc_reason) {
6345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
6346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Heap::kNoGCFlags, gc_reason);
6347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHeapProfiler* Isolate::GetHeapProfiler() {
6351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HeapProfiler* heap_profiler =
6352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::Isolate*>(this)->heap_profiler();
6353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<HeapProfiler*>(heap_profiler);
6354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCpuProfiler* Isolate::GetCpuProfiler() {
6358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::CpuProfiler* cpu_profiler =
6359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
6360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<CpuProfiler*>(cpu_profiler);
6361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Isolate::InContext() {
6365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->context() != NULL;
636744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
636844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Local<v8::Context> Isolate::GetCurrentContext() {
6371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Context* context = isolate->context();
6373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (context == NULL) return Local<Context>();
6374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Context* native_context = context->native_context();
6375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (native_context == NULL) return Local<Context>();
6376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::Handle<i::Context>(native_context));
6377a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Local<v8::Context> Isolate::GetCallingContext() {
6381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
6383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (calling.is_null()) return Local<Context>();
6384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
6385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6387a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Local<v8::Context> Isolate::GetEnteredContext() {
6389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> last =
6391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->handle_scope_implementer()->LastEnteredContext();
6392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (last.is_null()) return Local<Context>();
6393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::Handle<i::Context>::cast(last));
6394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochv8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
6398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
6400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If we're passed an empty handle, we throw an undefined exception
6401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to deal more gracefully with out of memory situations.
6402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (value.IsEmpty()) {
6403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->ScheduleThrow(isolate->heap()->undefined_value());
6404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
6405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->ScheduleThrow(*Utils::OpenHandle(*value));
640644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
6407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
6408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
6412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_isolate->global_handles()->SetObjectGroupId(
6414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::Object>(object).location(),
6415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      id);
6416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
6420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_isolate->global_handles()->SetReferenceFromGroup(
6422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      id,
6423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::Object>(object).location());
6424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetReference(internal::Object** parent,
6428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                           internal::Object** child) {
6429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Object** parent_location =
6431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::Object>(parent).location();
6432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_isolate->global_handles()->SetReference(
6433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::HeapObject**>(parent_location),
6434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v8::internal::Handle<v8::internal::Object>(child).location());
6435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
6439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    GCType gc_type) {
6440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->AddGCPrologueCallback(callback, gc_type);
6442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
6446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->RemoveGCPrologueCallback(callback);
6448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
6452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                    GCType gc_type) {
6453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
6455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
6459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->RemoveGCEpilogueCallback(callback);
6461a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64646ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
646544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->AddGCPrologueCallback(
6467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
6468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_type,
6469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false);
64706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
64716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64736ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
647444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->RemoveGCPrologueCallback(
6476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
64776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
64786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64796ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64806ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
648144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->AddGCEpilogueCallback(
6483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
6484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      gc_type,
6485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      false);
64866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
64876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64896ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockvoid V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
649044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->heap()->RemoveGCEpilogueCallback(
6492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
64936ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
64946ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64956ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
64969ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrickvoid V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
64979ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                                     ObjectSpace space,
64989ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                                     AllocationAction action) {
649944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
650044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->memory_allocator()->AddMemoryAllocationCallback(
650144f0eee88ff00398ff7f715fab053374d808c90dSteve Block      callback, space, action);
65029ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick}
65039ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
65049ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
65059ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrickvoid V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
650644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
650744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  isolate->memory_allocator()->RemoveMemoryAllocationCallback(
650844f0eee88ff00398ff7f715fab053374d808c90dSteve Block      callback);
65099ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick}
65109ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
65119ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick
6512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::TerminateExecution(Isolate* isolate) {
6513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->stack_guard()->RequestTerminateExecution();
65153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
65163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool V8::IsExecutionTerminating(Isolate* isolate) {
6519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = isolate != NULL ?
6520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
6521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return IsExecutionTerminatingCheck(i_isolate);
65223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
65233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
65243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid V8::CancelTerminateExecution(Isolate* isolate) {
6526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->stack_guard()->ClearTerminateExecution();
6528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->CancelTerminateExecution();
6529a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6530a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
6533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
6534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->set_api_interrupt_callback(callback);
6535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->set_api_interrupt_callback_data(data);
6536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->stack_guard()->RequestApiInterrupt();
6537a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6538a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::ClearInterrupt() {
6541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
6542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->stack_guard()->ClearApiInterrupt();
6543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->set_api_interrupt_callback(NULL);
6544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i_isolate->set_api_interrupt_callback_data(NULL);
6545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
6549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(i::FLAG_expose_gc);
6550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (type == kMinorGarbageCollection) {
6551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
6552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::NEW_SPACE, "Isolate::RequestGarbageCollection",
6553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        kGCCallbackFlagForced);
6554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
6555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(kFullGarbageCollection, type);
6556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
6557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Heap::kAbortIncrementalMarkingMask,
6558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        "Isolate::RequestGarbageCollection", kGCCallbackFlagForced);
6559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate* Isolate::GetCurrent() {
656444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<Isolate*>(isolate);
6566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate* Isolate::New(const Isolate::CreateParams& params) {
6570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = new i::Isolate();
6571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
6572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (params.entry_hook) {
6573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->set_function_entry_hook(params.entry_hook);
6574b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6575b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (params.code_event_handler) {
6576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->InitializeLoggingAndCounters();
6577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
6578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           params.code_event_handler);
6579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetResourceConstraints(isolate, params.constraints);
6581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (params.enable_serializer) {
6582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->enable_serializer();
6583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
6585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate::Scope isolate_scope(v8_isolate);
6586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
6587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If the isolate has a function entry hook, it needs to re-build all its
6588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // code stubs with entry hooks embedded, so don't deserialize a snapshot.
6589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->Init(NULL);
6590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return v8_isolate;
6592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::Dispose() {
6596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!Utils::ApiCheck(!isolate->IsInUse(),
6598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "v8::Isolate::Dispose()",
6599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       "Disposing the isolate that is entered by a thread.")) {
6600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
6601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->TearDown();
6603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::Enter() {
6607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->Enter();
6609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::Exit() {
6613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->Exit();
6615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
6619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate,
6620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
6621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : on_failure_(on_failure) {
6622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (on_failure_ == CRASH_ON_FAILURE) {
6624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    internal_ = reinterpret_cast<void*>(
6625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        new i::DisallowJavascriptExecution(i_isolate));
6626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
6627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK_EQ(THROW_ON_FAILURE, on_failure);
6628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    internal_ = reinterpret_cast<void*>(
6629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        new i::ThrowOnJavascriptExecution(i_isolate));
6630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
6635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (on_failure_ == CRASH_ON_FAILURE) {
6636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
663744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else {
6638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
663944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
6640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
6644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate) {
6645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_assert_ = reinterpret_cast<void*>(
6647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new i::AllowJavascriptExecution(i_isolate));
6648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_throws_ = reinterpret_cast<void*>(
6649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new i::NoThrowOnJavascriptExecution(i_isolate));
665044f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
665144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
665244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
6654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
6655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
665644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
665744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
665844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
6660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Isolate* isolate)
6661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
6662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->handle_scope_implementer()->IncrementCallDepth();
666344f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
666444f0eee88ff00398ff7f715fab053374d808c90dSteve Block
666544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochIsolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
6667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->handle_scope_implementer()->DecrementCallDepth();
6668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
667244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!isolate->IsInitialized()) {
6674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_statistics->total_heap_size_ = 0;
6675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_statistics->total_heap_size_executable_ = 0;
6676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_statistics->total_physical_size_ = 0;
6677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_statistics->used_heap_size_ = 0;
6678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    heap_statistics->heap_size_limit_ = 0;
667944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    return;
66806ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
6681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Heap* heap = isolate->heap();
6682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_statistics->total_heap_size_ = heap->CommittedMemory();
6683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_statistics->total_heap_size_executable_ =
6684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      heap->CommittedMemoryExecutable();
6685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
6686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_statistics->used_heap_size_ = heap->SizeOfObjects();
6687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  heap_statistics->heap_size_limit_ = heap->MaxReserved();
668844f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
668944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
669044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetEventLogger(LogEventCallback that) {
6692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Do not overwrite the event logger if we want to log explicitly.
6693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (i::FLAG_log_timer_events) return;
669444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->set_event_logger(that);
669644f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
669744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
669844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
6700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (callback == NULL) return;
670144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->AddCallCompletedCallback(callback);
67036ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
67046ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
67056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
6706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
6707257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->RemoveCallCompletedCallback(callback);
6709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::RunMicrotasks() {
6713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
6714257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
6715257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::EnqueueMicrotask(Handle<Function> microtask) {
6718257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
6720257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch}
6721257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6722257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch
6723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
6724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
672544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
6726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::CallHandlerInfo> callback_info =
6727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::CallHandlerInfo>::cast(
6728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE));
6729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SET_FIELD_WRAPPED(callback_info, set_callback, microtask);
6730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SET_FIELD_WRAPPED(callback_info, set_data, data);
6731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->EnqueueMicrotask(callback_info);
6732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetAutorunMicrotasks(bool autorun) {
6736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
6737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6738a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Isolate::WillAutorunMicrotasks() const {
6741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks();
6742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetUseCounterCallback(UseCounterCallback callback) {
6746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
6747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetCounterFunction(CounterLookupCallback callback) {
6751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->stats_table()->SetCounterFunction(callback);
6753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->InitializeLoggingAndCounters();
6754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->counters()->ResetCounters();
6755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
6759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->stats_table()->SetCreateHistogramFunction(callback);
6761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->InitializeLoggingAndCounters();
6762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->counters()->ResetHistograms();
6763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Isolate::SetAddHistogramSampleFunction(
6767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddHistogramSampleCallback callback) {
6768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::Isolate*>(this)
6769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ->stats_table()
6770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ->SetAddHistogramSampleFunction(callback);
6771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool v8::Isolate::IdleNotification(int idle_time_in_ms) {
6775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Returning true tells the caller that it need not
6776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // continue to call IdleNotification.
6777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!i::FLAG_use_idle_notification) return true;
6779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->heap()->IdleNotification(idle_time_in_ms);
6780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Isolate::LowMemoryNotification() {
6784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  {
6786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::HistogramTimerScope idle_notification_scope(
6787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate->counters()->gc_low_memory_notification());
6788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->heap()->CollectAllAvailableGarbage("low memory notification");
6789a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6790a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6791a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint v8::Isolate::ContextDisposedNotification() {
6794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return isolate->heap()->NotifyContextDisposed();
6796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6797a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
6800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         JitCodeEventHandler event_handler) {
6801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Ensure that logging is initialized for our isolate.
6803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->InitializeLoggingAndCounters();
6804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->logger()->SetCodeEventHandler(options, event_handler);
6805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
6806a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6807f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
6808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid v8::Isolate::SetStackLimit(uintptr_t stack_limit) {
6809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(stack_limit);
6811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->stack_guard()->SetStackLimit(stack_limit);
6812f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
6813f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
6814f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
6815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
6816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : str_(NULL), length_(0) {
681744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj.IsEmpty()) return;
681944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
682044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::HandleScope scope(isolate);
6821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TryCatch try_catch;
6822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> str = obj->ToString();
6823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (str.IsEmpty()) return;
6824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> i_str = Utils::OpenHandle(*str);
6825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  length_ = v8::Utf8Length(*i_str, isolate);
6826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  str_ = i::NewArray<char>(length_ + 1);
6827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  str->WriteUtf8(str_);
6828f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke}
6829f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
6830f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke
6831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString::Utf8Value::~Utf8Value() {
6832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeleteArray(str_);
6833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6835a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString::Value::Value(v8::Handle<v8::Value> obj)
6837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : str_(NULL), length_(0) {
683844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj.IsEmpty()) return;
684044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
6841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
6842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TryCatch try_catch;
6843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> str = obj->ToString();
6844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (str.IsEmpty()) return;
6845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  length_ = str->Length();
6846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  str_ = i::NewArray<uint16_t>(length_ + 1);
6847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  str->Write(str_);
6848a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6849a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6850a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochString::Value::~Value() {
6852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::DeleteArray(str_);
6853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DEFINE_ERROR(NAME)                                                    \
6857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Local<Value> Exception::NAME(v8::Handle<v8::String> raw_message) {          \
6858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Isolate* isolate = i::Isolate::Current();                              \
6859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LOG_API(isolate, #NAME);                                                  \
6860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ON_BAILOUT(isolate, "v8::Exception::" #NAME "()", return Local<Value>()); \
6861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ENTER_V8(isolate);                                                        \
6862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Object* error;                                                         \
6863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    {                                                                         \
6864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::HandleScope scope(isolate);                                          \
6865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::String> message = Utils::OpenHandle(*raw_message);         \
6866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Handle<i::Object> result;                                            \
6867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXCEPTION_PREAMBLE(isolate);                                            \
6868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::MaybeHandle<i::Object> maybe_result =                                \
6869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate->factory()->New##NAME(message);                             \
6870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      has_pending_exception = !maybe_result.ToHandle(&result);                \
6871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      /* TODO(yangguo): crbug/403509. Return empty handle instead. */         \
6872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      EXCEPTION_BAILOUT_CHECK(                                                \
6873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate, v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate)));   \
6874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      error = *result;                                                        \
6875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }                                                                         \
6876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> result(error, isolate);                              \
6877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Utils::ToLocal(result);                                            \
6878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
6879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_ERROR(RangeError)
6881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_ERROR(ReferenceError)
6882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_ERROR(SyntaxError)
6883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_ERROR(TypeError)
6884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDEFINE_ERROR(Error)
6885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
6886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DEFINE_ERROR
6887f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
68883bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
6889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// --- D e b u g   S u p p o r t ---
68903bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
6891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
689244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
6893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
6894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ENTER_V8(isolate);
6895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
6896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
6897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (that != NULL) {
6898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
6899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->debug()->SetEventListener(foreign,
6901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     Utils::OpenHandle(*data, true));
6902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
6903a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Debug::DebugBreak(Isolate* isolate) {
6907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
6908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
690944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
6910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Debug::CancelDebugBreak(Isolate* isolate) {
6912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_isolate->stack_guard()->ClearDebugBreak();
6914a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6916a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool Debug::CheckDebugBreak(Isolate* isolate) {
6918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return internal_isolate->stack_guard()->CheckDebugBreak();
6920a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Debug::DebugBreakForCommand(Isolate* isolate, ClientData* data) {
6924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_isolate->debug()->EnqueueDebugCommand(data);
6926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6927a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
693044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
693144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
6932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate->debug()->SetMessageHandler(handler);
6933a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6934a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6935a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Debug::SendCommand(Isolate* isolate,
6937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        const uint16_t* command,
6938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        int length,
6939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        ClientData* client_data) {
6940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_isolate->debug()->EnqueueCommandMessage(
6942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      i::Vector<const uint16_t>(command, length), client_data);
6943d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block}
6944d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
6945d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
6946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Value> Debug::Call(v8::Handle<v8::Function> fun,
6947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                         v8::Handle<v8::Value> data) {
694844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
694944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!isolate->IsInitialized()) return Local<Value>();
695044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
695144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
6952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::MaybeHandle<i::Object> maybe_result;
695344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
6954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (data.IsEmpty()) {
6955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maybe_result = isolate->debug()->Call(
6956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Utils::OpenHandle(*fun), isolate->factory()->undefined_value());
6957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
6958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    maybe_result = isolate->debug()->Call(
6959b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Utils::OpenHandle(*fun), Utils::OpenHandle(*data));
6960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> result;
6962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !maybe_result.ToHandle(&result);
696344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
6964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Utils::ToLocal(result);
6965a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
6966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockLocal<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
696944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
697044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (!isolate->IsInitialized()) return Local<Value>();
697144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
697244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
6973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
697444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Debug* isolate_debug = isolate->debug();
697544f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_PREAMBLE(isolate);
6976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  has_pending_exception = !isolate_debug->Load();
6977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Local<v8::Value> result;
6978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!has_pending_exception) {
6979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::JSObject> debug(
6980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate_debug->debug_context()->global_object());
6981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
6982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        STATIC_CHAR_VECTOR("MakeMirror"));
6983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::Object> fun_obj =
6984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        i::Object::GetProperty(debug, name).ToHandleChecked();
6985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
6986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
6987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const int kArgc = 1;
6988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Handle<v8::Value> argv[kArgc] = { obj };
6989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result = v8_fun->Call(Utils::ToLocal(debug), kArgc, argv);
6990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    has_pending_exception = result.IsEmpty();
6991b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
699244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
6993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return scope.Escape(result);
69943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
69953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
69963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
6997e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarkevoid Debug::ProcessDebugMessages() {
6998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate::Current()->debug()->ProcessDebugMessages(true);
6999a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7000e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
7001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70026ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockLocal<Context> Debug::GetDebugContext() {
700344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
700444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  ENTER_V8(isolate);
7005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(i::Isolate::Current()->debug()->GetDebugContext());
70066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
7010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal_isolate->debug()->set_live_edit_enabled(enable);
7012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
70146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70156ded16be15dd865a9b21ea304d5273c8be299c87Steve BlockHandle<String> CpuProfileNode::GetFunctionName() const {
701644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
70176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
70186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const i::CodeEntry* entry = node->entry();
7019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::String> name =
7020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->InternalizeUtf8String(entry->name());
70216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  if (!entry->has_name_prefix()) {
7022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ToApiHandle<String>(name);
70236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  } else {
7024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We do not expect this to fail. Change this if it does.
7025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    i::Handle<i::String> cons = isolate->factory()->NewConsString(
7026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
7027b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        name).ToHandleChecked();
7028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return ToApiHandle<String>(cons);
70296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  }
70306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CpuProfileNode::GetScriptId() const {
70346ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const i::CodeEntry* entry = node->entry();
7036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return entry->script_id();
70376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70396ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<String> CpuProfileNode::GetScriptResourceName() const {
704144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
7042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
7044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      node->entry()->resource_name()));
70456ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CpuProfileNode::GetLineNumber() const {
7049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
70506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70516ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70526ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CpuProfileNode::GetColumnNumber() const {
7054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const i::ProfileNode*>(this)->
7055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      entry()->column_number();
70566ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70576ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70586ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* CpuProfileNode::GetBailoutReason() const {
7060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return node->entry()->bailout_reason();
70626ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70636ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70646ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochunsigned CpuProfileNode::GetHitCount() const {
70666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
70676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70706ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockunsigned CpuProfileNode::GetCallUid() const {
70710d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
70726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70736ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochunsigned CpuProfileNode::GetNodeId() const {
7076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const i::ProfileNode*>(this)->id();
7077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70806ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockint CpuProfileNode::GetChildrenCount() const {
70816ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
70826ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70836ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70846ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70856ded16be15dd865a9b21ea304d5273c8be299c87Steve Blockconst CpuProfileNode* CpuProfileNode::GetChild(int index) const {
70866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const i::ProfileNode* child =
70876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block      reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
70886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  return reinterpret_cast<const CpuProfileNode*>(child);
70896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
70906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
70916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
709244f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid CpuProfile::Delete() {
709344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
7094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::CpuProfiler* profiler = isolate->cpu_profiler();
7095b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(profiler != NULL);
7096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
709744f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
709844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
709944f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<String> CpuProfile::GetTitle() const {
710144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
7102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
7104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      profile->title()));
71056ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71066ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71076ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst CpuProfileNode* CpuProfile::GetTopDownRoot() const {
71096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
71116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst CpuProfileNode* CpuProfile::GetSample(int index) const {
71156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
71176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t CpuProfile::GetSampleTimestamp(int index) const {
71216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (profile->sample_timestamp(index) - base::TimeTicks())
7123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      .InMicroseconds();
71246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71266ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t CpuProfile::GetStartTime() const {
7128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (profile->start_time() - base::TimeTicks()).InMicroseconds();
71306ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint64_t CpuProfile::GetEndTime() const {
7134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (profile->end_time() - base::TimeTicks()).InMicroseconds();
71366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71386ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint CpuProfile::GetSamplesCount() const {
7140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
71416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71426ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71436ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuProfiler::SetSamplingInterval(int us) {
7145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(us >= 0);
7146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
7147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      base::TimeDelta::FromMicroseconds(us));
71486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71496ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71506ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuProfiler::StartProfiling(Handle<String> title, bool record_samples) {
7152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
7153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      *Utils::OpenHandle(*title), record_samples);
7154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
7158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  StartProfiling(title, record_samples);
7159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochCpuProfile* CpuProfiler::StopProfiling(Handle<String> title) {
7163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<CpuProfile*>(
7164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
7165f7060e27768c550ace7ec48ad8c093466db52dfaLeon Clarke          *Utils::OpenHandle(*title)));
71666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
71676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
71689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title) {
7170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return StopProfiling(title);
7171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid CpuProfiler::SetIdle(bool is_idle) {
7175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
7176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::StateTag state = isolate->current_vm_state();
7177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(state == i::EXTERNAL || state == i::IDLE);
7178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate->js_entry_sp() != NULL) return;
7179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_idle) {
7180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->set_current_vm_state(i::IDLE);
7181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (state == i::IDLE) {
7182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->set_current_vm_state(i::EXTERNAL);
7183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
718444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
718544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
718644f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7187756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickstatic i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
7188756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return const_cast<i::HeapGraphEdge*>(
7189756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      reinterpret_cast<const i::HeapGraphEdge*>(edge));
7190756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
7191756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
71923fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
71939dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenHeapGraphEdge::Type HeapGraphEdge::GetType() const {
7194756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
71959dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
71969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
71979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
71989dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenHandle<Value> HeapGraphEdge::GetName() const {
719944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
7200756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  i::HeapGraphEdge* edge = ToInternal(this);
72019dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  switch (edge->type()) {
7202756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    case i::HeapGraphEdge::kContextVariable:
7203756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    case i::HeapGraphEdge::kInternal:
7204756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    case i::HeapGraphEdge::kProperty:
72058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::HeapGraphEdge::kShortcut:
7206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    case i::HeapGraphEdge::kWeak:
7207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ToApiHandle<String>(
7208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate->factory()->InternalizeUtf8String(edge->name()));
7209756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    case i::HeapGraphEdge::kElement:
72108a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang    case i::HeapGraphEdge::kHidden:
7211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return ToApiHandle<Number>(
7212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          isolate->factory()->NewNumberFromInt(edge->index()));
72139dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen    default: UNREACHABLE();
72149dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  }
7215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
72169dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72179dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72189dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72199dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenconst HeapGraphNode* HeapGraphEdge::GetFromNode() const {
7220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const i::HeapEntry* from = ToInternal(this)->from();
72219dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return reinterpret_cast<const HeapGraphNode*>(from);
72229dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72239dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72249dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72259dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenconst HeapGraphNode* HeapGraphEdge::GetToNode() const {
7226756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  const i::HeapEntry* to = ToInternal(this)->to();
72279dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return reinterpret_cast<const HeapGraphNode*>(to);
72289dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72299dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72309dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7231756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickstatic i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
7232756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return const_cast<i::HeapEntry*>(
7233756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      reinterpret_cast<const i::HeapEntry*>(entry));
7234756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
7235756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7236756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
72379dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenHeapGraphNode::Type HeapGraphNode::GetType() const {
7238756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
72399dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72409dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72419dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72429dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenHandle<String> HeapGraphNode::GetName() const {
724344f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
7244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<String>(
7245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
72469dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72479dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSnapshotObjectId HeapGraphNode::GetId() const {
7250756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return ToInternal(this)->id();
72513bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch}
72523bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
72533bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdoch
72549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenint HeapGraphNode::GetSelfSize() const {
7255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  size_t size = ToInternal(this)->self_size();
7256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(size <= static_cast<size_t>(internal::kMaxInt));
7257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return static_cast<int>(size);
72589dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72599dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t HeapGraphNode::GetShallowSize() const {
7262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToInternal(this)->self_size();
72639dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72649dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72659dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72669dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenint HeapGraphNode::GetChildrenCount() const {
7267756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return ToInternal(this)->children().length();
72689dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72699dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72709dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72719dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenconst HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
72729dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return reinterpret_cast<const HeapGraphEdge*>(
7273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ToInternal(this)->children()[index]);
727469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch}
727569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
727669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
7277756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrickstatic i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
7278756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return const_cast<i::HeapSnapshot*>(
7279756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      reinterpret_cast<const i::HeapSnapshot*>(snapshot));
7280756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick}
7281756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
7282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
728344f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid HeapSnapshot::Delete() {
728444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
7285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
728644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    ToInternal(this)->Delete();
728744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  } else {
728844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // If this is the last snapshot, clean up all accessory data as well.
7289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate->heap_profiler()->DeleteAllSnapshots();
729044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
729144f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
729244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
729344f0eee88ff00398ff7f715fab053374d808c90dSteve Block
72949dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsenunsigned HeapSnapshot::GetUid() const {
7295756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return ToInternal(this)->uid();
72969dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
72979dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72989dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
72999dcf7e2f83591d471e88bf7d230651900b8e424bKristian MonsenHandle<String> HeapSnapshot::GetTitle() const {
730044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  i::Isolate* isolate = i::Isolate::Current();
7301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToApiHandle<String>(
7302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      isolate->factory()->InternalizeUtf8String(ToInternal(this)->title()));
73039dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
73049dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
73059dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
73063bec4d28b1f388dbc06a9c4276e1a03e86c52b04Ben Murdochconst HeapGraphNode* HeapSnapshot::GetRoot() const {
7307756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
73089dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
73099dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
73109dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
7312b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return reinterpret_cast<const HeapGraphNode*>(
7313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ToInternal(this)->GetEntryById(id));
7314b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
7315b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
73173fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochint HeapSnapshot::GetNodesCount() const {
7318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToInternal(this)->entries().length();
73193fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
73203fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
73213fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
73223fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdochconst HeapGraphNode* HeapSnapshot::GetNode(int index) const {
73233fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  return reinterpret_cast<const HeapGraphNode*>(
7324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      &ToInternal(this)->entries().at(index));
7325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
7329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return ToInternal(this)->max_snapshot_js_object_id();
73303fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch}
73313fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
73323fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
73330d5e116f6aee03185f237311a943491bb079a768Kristian Monsenvoid HeapSnapshot::Serialize(OutputStream* stream,
73340d5e116f6aee03185f237311a943491bb079a768Kristian Monsen                             HeapSnapshot::SerializationFormat format) const {
7335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(format == kJSON,
7336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::HeapSnapshot::Serialize",
7337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Unknown serialization format");
7338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Utils::ApiCheck(stream->GetChunkSize() > 0,
7339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "v8::HeapSnapshot::Serialize",
7340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  "Invalid stream chunk size");
73410d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
73420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  serializer.Serialize(stream);
73430d5e116f6aee03185f237311a943491bb079a768Kristian Monsen}
73440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
73450d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
7346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint HeapProfiler::GetSnapshotCount() {
7347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
73489dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
73499dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
73509dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
73529dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return reinterpret_cast<const HeapSnapshot*>(
7353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
73549dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
73559dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
73569dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
7358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj = Utils::OpenHandle(*value);
7359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
73609dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
73619dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
73629dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
7363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochHandle<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
7364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Handle<i::Object> obj =
7365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
7366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (obj.is_null()) return Local<Value>();
7367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Utils::ToLocal(obj);
7368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapProfiler::ClearObjectIds() {
7372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
7373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
7377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Handle<String> title,
7378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ActivityControl* control,
7379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ObjectNameResolver* resolver) {
73809dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen  return reinterpret_cast<const HeapSnapshot*>(
7381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
7382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          *Utils::OpenHandle(*title), control, resolver));
73839dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen}
73849dcf7e2f83591d471e88bf7d230651900b8e424bKristian Monsen
738544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
7387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
7388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      track_allocations);
738944f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
739044f0eee88ff00398ff7f715fab053374d808c90dSteve Block
739144f0eee88ff00398ff7f715fab053374d808c90dSteve Block
7392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapProfiler::StopTrackingHeapObjects() {
7393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
739444f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
739544f0eee88ff00398ff7f715fab053374d808c90dSteve Block
73966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
7398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
7399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapProfiler::DeleteAllHeapSnapshots() {
7403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
7404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
7408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               WrapperInfoCallback callback) {
7409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
7410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                               callback);
7411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochsize_t HeapProfiler::GetProfilerMemorySize() {
7415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return reinterpret_cast<i::HeapProfiler*>(this)->
7416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      GetMemorySizeUsedByProfiler();
7417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HeapProfiler::SetRetainedObjectInfo(UniqueId id,
7421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                         RetainedObjectInfo* info) {
7422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
74233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
74243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
74256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
7426b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochv8::Testing::StressType internal::Testing::stress_type_ =
7427b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    v8::Testing::kStressTypeOpt;
7428b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7429b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7430b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Testing::SetStressRunType(Testing::StressType type) {
7431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  internal::Testing::set_stress_type(type);
7432b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
7433b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7435b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochint Testing::GetStressRuns() {
7436b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
7437b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
7438b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // In debug mode the code runs much slower so stressing will only make two
7439b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // runs.
7440b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return 2;
7441b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#else
7442b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  return 5;
7443b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
7444b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
7445b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7446b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7447b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochstatic void SetFlagsFromString(const char* flags) {
7448b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  V8::SetFlagsFromString(flags, i::StrLength(flags));
7449b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
7450b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7451b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7452b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid Testing::PrepareStressRun(int run) {
7453b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* kLazyOptimizations =
7454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "--prepare-always-opt "
7455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "--max-inlined-source-size=999999 "
7456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "--max-inlined-nodes=999999 "
7457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "--max-inlined-nodes-cumulative=999999 "
7458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      "--noalways-opt";
7459b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* kForcedOptimizations = "--always-opt";
7460b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7461b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // If deoptimization stressed turn on frequent deoptimization. If no value
7462b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // is spefified through --deopt-every-n-times use a default default value.
7463b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
7464b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
7465b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch      internal::FLAG_deopt_every_n_times == 0) {
7466b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlagsFromString(kDeoptEvery13Times);
7467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
7468b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7469b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
7470b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // As stressing in debug mode only make two runs skip the deopt stressing
7471b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // here.
7472b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (run == GetStressRuns() - 1) {
7473b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlagsFromString(kForcedOptimizations);
7474b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
7475b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlagsFromString(kLazyOptimizations);
7476b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
7477b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#else
7478b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (run == GetStressRuns() - 1) {
7479b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlagsFromString(kForcedOptimizations);
74803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  } else if (run != GetStressRuns() - 2) {
7481b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    SetFlagsFromString(kLazyOptimizations);
7482b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
7483b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
7484b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
7485b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7486b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
7487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// TODO(svenpanne) Deprecate this.
748844f0eee88ff00398ff7f715fab053374d808c90dSteve Blockvoid Testing::DeoptimizeAll() {
7489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::Isolate* isolate = i::Isolate::Current();
7490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  i::HandleScope scope(isolate);
7491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  internal::Deoptimizer::DeoptimizeAll(isolate);
749244f0eee88ff00398ff7f715fab053374d808c90dSteve Block}
7493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
749544f0eee88ff00398ff7f715fab053374d808c90dSteve Blocknamespace internal {
7496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScopeImplementer::FreeThreadResources() {
749944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  Free();
7500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* HandleScopeImplementer::ArchiveThread(char* storage) {
7504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScopeData* current = isolate_->handle_scope_data();
7505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  handle_scope_data_ = *current;
7506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemCopy(storage, this, sizeof(*this));
7507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7508a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ResetAfterArchive();
7509a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  current->Initialize();
7510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return storage + ArchiveSpacePerThread();
7512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockint HandleScopeImplementer::ArchiveSpacePerThread() {
751644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  return sizeof(HandleScopeImplementer);
7517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7518a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* HandleScopeImplementer::RestoreThread(char* storage) {
7521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  MemCopy(this, storage, sizeof(*this));
7522257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  *isolate_->handle_scope_data() = handle_scope_data_;
7523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return storage + ArchiveSpacePerThread();
7524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7525a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7526a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7527a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
7528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
7529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool found_block_before_deferred = false;
7530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
7531a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Iterate over all handles in the blocks except for the last.
7532a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (int i = blocks()->length() - 2; i >= 0; --i) {
7533a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    Object** block = blocks()->at(i);
7534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (last_handle_before_deferred_block_ != NULL &&
7535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
7536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        (last_handle_before_deferred_block_ >= block)) {
7537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v->VisitPointers(block, last_handle_before_deferred_block_);
7538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(!found_block_before_deferred);
7539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
7540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      found_block_before_deferred = true;
7541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
7542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
7543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      v->VisitPointers(block, &block[kHandleBlockSize]);
7544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
7545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
7546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(last_handle_before_deferred_block_ == NULL ||
7548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         found_block_before_deferred);
7549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Iterate over live handles in the last block (if any).
7551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!blocks()->is_empty()) {
7552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    v->VisitPointers(blocks()->last(), handle_scope_data_.next);
7553a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
7554a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
7556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (unsigned i = 0; i < arraysize(context_lists); i++) {
7557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (context_lists[i]->is_empty()) continue;
7558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
7559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v->VisitPointers(start, start + context_lists[i]->length());
7560a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
7561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockvoid HandleScopeImplementer::Iterate(ObjectVisitor* v) {
7565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  HandleScopeData* current = isolate_->handle_scope_data();
756644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  handle_scope_data_ = *current;
756744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  IterateThis(v);
7568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockchar* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
757244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  HandleScopeImplementer* scope_implementer =
7573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      reinterpret_cast<HandleScopeImplementer*>(storage);
757444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  scope_implementer->IterateThis(v);
7575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return storage + ArchiveSpacePerThread();
7576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
7577a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
7580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DeferredHandles* deferred =
7581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
7582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!blocks_.is_empty()) {
7584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** block_start = blocks_.last();
7585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Object** block_limit = &block_start[kHandleBlockSize];
7586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We should not need to check for SealHandleScope here. Assert this.
7587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(prev_limit == block_limit ||
7588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           !(block_start <= prev_limit && prev_limit <= block_limit));
7589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (prev_limit == block_limit) break;
7590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    deferred->blocks_.Add(blocks_.last());
7591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    blocks_.RemoveLast();
7592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
7593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // deferred->blocks_ now contains the blocks installed on the
7595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // HandleScope stack since BeginDeferredScope was called, but in
7596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // reverse order.
7597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(prev_limit == NULL || !blocks_.is_empty());
7599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!blocks_.is_empty() && prev_limit != NULL);
7601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(last_handle_before_deferred_block_ != NULL);
7602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_handle_before_deferred_block_ = NULL;
7603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return deferred;
7604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid HandleScopeImplementer::BeginDeferredScope() {
7608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(last_handle_before_deferred_block_ == NULL);
7609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
7610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochDeferredHandles::~DeferredHandles() {
7614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  isolate_->UnlinkDeferredHandles(this);
7615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < blocks_.length(); i++) {
7617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef ENABLE_HANDLE_ZAPPING
7618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
7619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
7620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
7621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
7622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid DeferredHandles::Iterate(ObjectVisitor* v) {
7626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!blocks_.is_empty());
7627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK((first_block_limit_ >= blocks_.first()) &&
7629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
7630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v->VisitPointers(blocks_.first(), first_block_limit_);
7632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 1; i < blocks_.length(); i++) {
7634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
7635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
7636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InvokeAccessorGetterCallback(
7640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::Local<v8::Name> property,
7641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const v8::PropertyCallbackInfo<v8::Value>& info,
7642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    v8::AccessorNameGetterCallback getter) {
7643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Leaving JavaScript.
7644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
7646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      getter));
7647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VMState<EXTERNAL> state(isolate);
7648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalCallbackScope call_scope(isolate, getter_address);
7649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  getter(property, info);
7650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
7654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            v8::FunctionCallback callback) {
7655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Address callback_address =
7657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
7658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VMState<EXTERNAL> state(isolate);
7659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExternalCallbackScope call_scope(isolate, callback_address);
7660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  callback(info);
7661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
7662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
7664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
7665