blob: a45907680bd60f5834bd5abcf67dccb1ac4f8130 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/api.h"
Ben Murdochf87a2032010-10-22 12:50:53 +01006
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007#include <string.h> // For memcpy, strlen.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#ifdef V8_USE_ADDRESS_SANITIZER
9#include <sanitizer/asan_interface.h>
10#endif // V8_USE_ADDRESS_SANITIZER
11#include <cmath> // For isnan.
12#include "include/v8-debug.h"
13#include "include/v8-profiler.h"
14#include "include/v8-testing.h"
15#include "src/assert-scope.h"
16#include "src/background-parsing-task.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040017#include "src/base/functional.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000018#include "src/base/platform/platform.h"
19#include "src/base/platform/time.h"
20#include "src/base/utils/random-number-generator.h"
21#include "src/bootstrapper.h"
22#include "src/code-stubs.h"
23#include "src/compiler.h"
24#include "src/conversions-inl.h"
25#include "src/counters.h"
26#include "src/cpu-profiler.h"
27#include "src/debug.h"
28#include "src/deoptimizer.h"
29#include "src/execution.h"
30#include "src/global-handles.h"
31#include "src/heap-profiler.h"
32#include "src/heap-snapshot-generator-inl.h"
33#include "src/icu_util.h"
34#include "src/json-parser.h"
35#include "src/messages.h"
36#include "src/natives.h"
37#include "src/parser.h"
38#include "src/profile-generator-inl.h"
39#include "src/property.h"
40#include "src/property-details.h"
41#include "src/prototype.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040042#include "src/runtime/runtime.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043#include "src/runtime-profiler.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040044#include "src/sampler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000045#include "src/scanner-character-streams.h"
46#include "src/simulator.h"
47#include "src/snapshot.h"
48#include "src/unicode-inl.h"
49#include "src/v8threads.h"
50#include "src/version.h"
51#include "src/vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000052
53
Steve Block44f0eee2011-05-26 01:26:41 +010054#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000055
Emily Bernierd0a1eb72015-03-24 16:35:39 -040056#define ENTER_V8(isolate) \
57 i::VMState<v8::OTHER> __state__((isolate))
Steve Blocka7e24c12009-10-30 11:49:00 +000058
59namespace v8 {
60
Steve Block44f0eee2011-05-26 01:26:41 +010061#define ON_BAILOUT(isolate, location, code) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062 if (IsExecutionTerminatingCheck(isolate)) { \
Leon Clarkef7060e22010-06-03 12:02:55 +010063 code; \
64 UNREACHABLE(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000065 }
66
67
Steve Block44f0eee2011-05-26 01:26:41 +010068#define EXCEPTION_PREAMBLE(isolate) \
69 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 DCHECK(!(isolate)->external_caught_exception()); \
Steve Blocka7e24c12009-10-30 11:49:00 +000071 bool has_pending_exception = false
72
73
Ben Murdoch3ef787d2012-04-12 10:51:47 +010074#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback) \
Steve Blocka7e24c12009-10-30 11:49:00 +000075 do { \
Steve Block44f0eee2011-05-26 01:26:41 +010076 i::HandleScopeImplementer* handle_scope_implementer = \
77 (isolate)->handle_scope_implementer(); \
78 handle_scope_implementer->DecrementCallDepth(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000079 if (has_pending_exception) { \
Steve Block44f0eee2011-05-26 01:26:41 +010080 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
81 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010082 do_callback \
Steve Blocka7e24c12009-10-30 11:49:00 +000083 return value; \
84 } \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010085 do_callback \
Steve Blocka7e24c12009-10-30 11:49:00 +000086 } while (false)
87
88
Ben Murdoch3ef787d2012-04-12 10:51:47 +010089#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
90 EXCEPTION_BAILOUT_CHECK_GENERIC( \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 isolate, value, isolate->FireCallCompletedCallback();)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010092
93
94#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
95 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
96
97
Steve Blocka7e24c12009-10-30 11:49:00 +000098// --- E x c e p t i o n B e h a v i o r ---
99
100
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800101void i::FatalProcessOutOfMemory(const char* location) {
102 i::V8::FatalProcessOutOfMemory(location, false);
103}
104
Steve Blocka7e24c12009-10-30 11:49:00 +0000105
106// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
107// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100108void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Steve Blockd0582a62009-12-15 09:54:21 +0000109 i::HeapStats heap_stats;
110 int start_marker;
111 heap_stats.start_marker = &start_marker;
112 int new_space_size;
113 heap_stats.new_space_size = &new_space_size;
114 int new_space_capacity;
115 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100116 intptr_t old_pointer_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000117 heap_stats.old_pointer_space_size = &old_pointer_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100118 intptr_t old_pointer_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000119 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100120 intptr_t old_data_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000121 heap_stats.old_data_space_size = &old_data_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100122 intptr_t old_data_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000123 heap_stats.old_data_space_capacity = &old_data_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100124 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000125 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100126 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000127 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100128 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000129 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100130 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000131 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100132 intptr_t cell_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000133 heap_stats.cell_space_size = &cell_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100134 intptr_t cell_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000135 heap_stats.cell_space_capacity = &cell_space_capacity;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136 intptr_t property_cell_space_size;
137 heap_stats.property_cell_space_size = &property_cell_space_size;
138 intptr_t property_cell_space_capacity;
139 heap_stats.property_cell_space_capacity = &property_cell_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100140 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000141 heap_stats.lo_space_size = &lo_space_size;
142 int global_handle_count;
143 heap_stats.global_handle_count = &global_handle_count;
144 int weak_global_handle_count;
145 heap_stats.weak_global_handle_count = &weak_global_handle_count;
146 int pending_global_handle_count;
147 heap_stats.pending_global_handle_count = &pending_global_handle_count;
148 int near_death_global_handle_count;
149 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000150 int free_global_handle_count;
151 heap_stats.free_global_handle_count = &free_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100152 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100153 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100154 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100155 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
156 int objects_per_type[LAST_TYPE + 1] = {0};
157 heap_stats.objects_per_type = objects_per_type;
158 int size_per_type[LAST_TYPE + 1] = {0};
159 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100160 int os_error;
161 heap_stats.os_error = &os_error;
Steve Blockd0582a62009-12-15 09:54:21 +0000162 int end_marker;
163 heap_stats.end_marker = &end_marker;
Steve Block44f0eee2011-05-26 01:26:41 +0100164 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165 if (isolate->heap()->HasBeenSetUp()) {
166 // BUG(1718): Don't use the take_snapshot since we don't support
167 // HeapIterator here without doing a special GC.
168 isolate->heap()->RecordStats(&heap_stats, false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000169 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000170 Utils::ApiCheck(false, location, "Allocation failed - process out of memory");
171 // If the fatal error handler returns, we stop execution.
172 FATAL("API fatal error handler returned after process out of memory");
Steve Blocka7e24c12009-10-30 11:49:00 +0000173}
174
175
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176void Utils::ReportApiFailure(const char* location, const char* message) {
177 i::Isolate* isolate = i::Isolate::Current();
178 FatalErrorCallback callback = isolate->exception_behavior();
179 if (callback == NULL) {
180 base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
181 message);
182 base::OS::Abort();
183 } else {
184 callback(location, message);
185 }
186 isolate->SignalFatalError();
Steve Blocka7e24c12009-10-30 11:49:00 +0000187}
188
189
Steve Block44f0eee2011-05-26 01:26:41 +0100190static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100191 if (isolate->has_scheduled_exception()) {
192 return isolate->scheduled_exception() ==
193 isolate->heap()->termination_exception();
194 }
195 return false;
196}
197
198
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000199void V8::SetNativesDataBlob(StartupData* natives_blob) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400200 i::V8::SetNativesBlob(natives_blob);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000201}
202
203
204void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400205 i::V8::SetSnapshotBlob(snapshot_blob);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000206}
207
208
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400209StartupData V8::CreateSnapshotDataBlob() {
210 Isolate::CreateParams params;
211 params.enable_serializer = true;
212 Isolate* isolate = v8::Isolate::New(params);
213 StartupData result = {NULL, 0};
214 {
215 Isolate::Scope isolate_scope(isolate);
216 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
217 Persistent<Context> context;
218 {
219 HandleScope handle_scope(isolate);
220 context.Reset(isolate, Context::New(isolate));
221 }
222 if (!context.IsEmpty()) {
223 // Make sure all builtin scripts are cached.
224 {
225 HandleScope scope(isolate);
226 for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
227 internal_isolate->bootstrapper()->NativesSourceLookup(i);
228 }
229 }
230 // If we don't do this then we end up with a stray root pointing at the
231 // context even after we have disposed of the context.
232 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
233 i::Object* raw_context = *v8::Utils::OpenPersistent(context);
234 context.Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +0000235
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400236 i::SnapshotByteSink snapshot_sink;
237 i::StartupSerializer ser(internal_isolate, &snapshot_sink);
238 ser.SerializeStrongReferences();
Steve Blocka7e24c12009-10-30 11:49:00 +0000239
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400240 i::SnapshotByteSink context_sink;
241 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
242 context_ser.Serialize(&raw_context);
243 ser.SerializeWeakReferences();
244
245 i::SnapshotData sd(snapshot_sink, ser);
246 i::SnapshotData csd(context_sink, context_ser);
247
248 result = i::Snapshot::CreateSnapshotBlob(sd.RawData(), csd.RawData());
249 }
250 }
251 isolate->Dispose();
252 return result;
Ben Murdoch257744e2011-11-30 15:57:28 +0000253}
254
255
Steve Blocka7e24c12009-10-30 11:49:00 +0000256void V8::SetFlagsFromString(const char* str, int length) {
257 i::FlagList::SetFlagsFromString(str, length);
258}
259
260
261void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
262 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
263}
264
265
Steve Blocka7e24c12009-10-30 11:49:00 +0000266RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
267
268
269RegisteredExtension::RegisteredExtension(Extension* extension)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100270 : extension_(extension) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000271
272
273void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100274 that->next_ = first_extension_;
275 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000276}
277
278
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279void RegisteredExtension::UnregisterAll() {
280 RegisteredExtension* re = first_extension_;
281 while (re != NULL) {
282 RegisteredExtension* next = re->next();
283 delete re;
284 re = next;
285 }
286 first_extension_ = NULL;
287}
288
289
Steve Blocka7e24c12009-10-30 11:49:00 +0000290void RegisterExtension(Extension* that) {
291 RegisteredExtension* extension = new RegisteredExtension(that);
292 RegisteredExtension::Register(extension);
293}
294
295
296Extension::Extension(const char* name,
297 const char* source,
298 int dep_count,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100299 const char** deps,
300 int source_length)
Steve Blocka7e24c12009-10-30 11:49:00 +0000301 : name_(name),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100302 source_length_(source_length >= 0 ?
303 source_length :
304 (source ? static_cast<int>(strlen(source)) : 0)),
305 source_(source, source_length_),
Steve Blocka7e24c12009-10-30 11:49:00 +0000306 dep_count_(dep_count),
307 deps_(deps),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000308 auto_enable_(false) {
309 CHECK(source != NULL || source_length_ == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000310}
311
312
313ResourceConstraints::ResourceConstraints()
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000314 : max_semi_space_size_(0),
315 max_old_space_size_(0),
316 max_executable_size_(0),
317 stack_limit_(NULL),
318 max_available_threads_(0),
319 code_range_size_(0) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000320
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000321void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
322 uint64_t virtual_memory_limit,
323 uint32_t number_of_processors) {
324#if V8_OS_ANDROID
325 // Android has higher physical memory requirements before raising the maximum
326 // heap size limits since it has no swap space.
327 const uint64_t low_limit = 512ul * i::MB;
328 const uint64_t medium_limit = 1ul * i::GB;
329 const uint64_t high_limit = 2ul * i::GB;
330#else
331 const uint64_t low_limit = 512ul * i::MB;
332 const uint64_t medium_limit = 768ul * i::MB;
333 const uint64_t high_limit = 1ul * i::GB;
334#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000335
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000336 if (physical_memory <= low_limit) {
337 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice);
338 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
339 set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
340 } else if (physical_memory <= medium_limit) {
341 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice);
342 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
343 set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
344 } else if (physical_memory <= high_limit) {
345 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice);
346 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
347 set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
348 } else {
349 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice);
350 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
351 set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
Steve Blocka7e24c12009-10-30 11:49:00 +0000352 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000353
354 set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u));
355
356 if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
357 // Reserve no more than 1/8 of the memory for the code range, but at most
358 // kMaximalCodeRangeSize.
359 set_code_range_size(
360 i::Min(i::kMaximalCodeRangeSize / i::MB,
361 static_cast<size_t>((virtual_memory_limit >> 3) / i::MB)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000362 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000363}
364
365
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000366void SetResourceConstraints(i::Isolate* isolate,
367 const ResourceConstraints& constraints) {
368 int semi_space_size = constraints.max_semi_space_size();
369 int old_space_size = constraints.max_old_space_size();
370 int max_executable_size = constraints.max_executable_size();
371 size_t code_range_size = constraints.code_range_size();
372 if (semi_space_size != 0 || old_space_size != 0 ||
373 max_executable_size != 0 || code_range_size != 0) {
374 isolate->heap()->ConfigureHeap(semi_space_size, old_space_size,
375 max_executable_size, code_range_size);
376 }
377 if (constraints.stack_limit() != NULL) {
378 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
379 isolate->stack_guard()->SetStackLimit(limit);
380 }
381
382 isolate->set_max_available_threads(constraints.max_available_threads());
383}
384
385
386i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100387 LOG_API(isolate, "Persistent::New");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000388 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400389#ifdef VERIFY_HEAP
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000390 (*obj)->ObjectVerify();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400391#endif // VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +0000392 return result.location();
393}
394
395
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000396i::Object** V8::CopyPersistent(i::Object** obj) {
397 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400398#ifdef VERIFY_HEAP
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000399 (*obj)->ObjectVerify();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400400#endif // VERIFY_HEAP
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000401 return result.location();
Steve Blocka7e24c12009-10-30 11:49:00 +0000402}
403
404
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400405void V8::MakeWeak(i::Object** object, void* parameter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000406 WeakCallback weak_callback) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400407 i::GlobalHandles::MakeWeak(object, parameter, weak_callback);
408}
409
410
411void V8::MakePhantom(i::Object** object, void* parameter,
412 PhantomCallbackData<void>::Callback weak_callback) {
413 i::GlobalHandles::MakePhantom(object, parameter, weak_callback);
414}
415
416
417void V8::MakePhantom(
418 i::Object** object,
419 InternalFieldsCallbackData<void, void>::Callback weak_callback,
420 int internal_field_index1, int internal_field_index2) {
421 i::GlobalHandles::MakePhantom(object, weak_callback, internal_field_index1,
422 internal_field_index2);
Steve Blocka7e24c12009-10-30 11:49:00 +0000423}
424
425
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000426void* V8::ClearWeak(i::Object** obj) {
427 return i::GlobalHandles::ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000428}
429
430
431void V8::DisposeGlobal(i::Object** obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000432 i::GlobalHandles::Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000433}
434
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000435
436void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
437 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
438 i::Object* object = *Utils::OpenHandle(value);
439 isolate->eternal_handles()->Create(isolate, object, index);
440}
441
442
443Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
444 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
445 return Utils::ToLocal(isolate->eternal_handles()->Get(index));
446}
447
448
Steve Blocka7e24c12009-10-30 11:49:00 +0000449// --- H a n d l e s ---
450
451
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000452HandleScope::HandleScope(Isolate* isolate) {
453 Initialize(isolate);
454}
455
456
457void HandleScope::Initialize(Isolate* isolate) {
458 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
459 // We do not want to check the correct usage of the Locker class all over the
460 // place, so we do it only here: Without a HandleScope, an embedder can do
461 // almost nothing, so it is enough to check in this central place.
462 Utils::ApiCheck(!v8::Locker::IsActive() ||
463 internal_isolate->thread_manager()->IsLockedByCurrentThread(),
464 "HandleScope::HandleScope",
465 "Entering the V8 API without proper locking in place");
466 i::HandleScopeData* current = internal_isolate->handle_scope_data();
467 isolate_ = internal_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +0100468 prev_next_ = current->next;
469 prev_limit_ = current->limit;
Steve Block44f0eee2011-05-26 01:26:41 +0100470 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000471}
472
473
474HandleScope::~HandleScope() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000475 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
476}
477
478
479int HandleScope::NumberOfHandles(Isolate* isolate) {
480 return i::HandleScope::NumberOfHandles(
481 reinterpret_cast<i::Isolate*>(isolate));
482}
483
484
485i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
486 return i::HandleScope::CreateHandle(isolate, value);
487}
488
489
490i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
491 i::Object* value) {
492 DCHECK(heap_object->IsHeapObject());
493 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
494}
495
496
497EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
498 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
499 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
500 Initialize(v8_isolate);
501}
502
503
504i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
505 i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
506 Utils::ApiCheck(*escape_slot_ == heap->the_hole_value(),
507 "EscapeableHandleScope::Escape",
508 "Escape value set twice");
509 if (escape_value == NULL) {
510 *escape_slot_ = heap->undefined_value();
511 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000512 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000513 *escape_slot_ = *escape_value;
514 return escape_slot_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000515}
516
517
518void Context::Enter() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000519 i::Handle<i::Context> env = Utils::OpenHandle(this);
520 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100521 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000522 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
523 impl->EnterContext(env);
524 impl->SaveContext(isolate->context());
Steve Block44f0eee2011-05-26 01:26:41 +0100525 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000526}
527
528
529void Context::Exit() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000530 i::Handle<i::Context> env = Utils::OpenHandle(this);
531 i::Isolate* isolate = env->GetIsolate();
532 ENTER_V8(isolate);
533 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
534 if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
535 "v8::Context::Exit()",
536 "Cannot exit non-entered context")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000537 return;
538 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000539 impl->LeaveContext();
540 isolate->set_context(impl->RestoreContext());
Steve Blocka7e24c12009-10-30 11:49:00 +0000541}
542
543
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000544static void* DecodeSmiToAligned(i::Object* value, const char* location) {
545 Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
546 return reinterpret_cast<void*>(value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000547}
548
549
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000550static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
551 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
552 Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
553 return smi;
554}
555
556
557static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
558 int index,
559 bool can_grow,
560 const char* location) {
561 i::Handle<i::Context> env = Utils::OpenHandle(context);
562 bool ok =
563 Utils::ApiCheck(env->IsNativeContext(),
564 location,
565 "Not a native context") &&
566 Utils::ApiCheck(index >= 0, location, "Negative index");
567 if (!ok) return i::Handle<i::FixedArray>();
568 i::Handle<i::FixedArray> data(env->embedder_data());
569 if (index < data->length()) return data;
570 if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
571 return i::Handle<i::FixedArray>();
Steve Block44f0eee2011-05-26 01:26:41 +0100572 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000573 int new_size = i::Max(index, data->length() << 1) + 1;
574 data = i::FixedArray::CopySize(data, new_size);
575 env->set_embedder_data(*data);
576 return data;
577}
578
579
580v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
581 const char* location = "v8::Context::GetEmbedderData()";
582 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
583 if (data.is_null()) return Local<Value>();
584 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000585 return Utils::ToLocal(result);
586}
587
588
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000589void Context::SetEmbedderData(int index, v8::Handle<Value> value) {
590 const char* location = "v8::Context::SetEmbedderData()";
591 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
592 if (data.is_null()) return;
593 i::Handle<i::Object> val = Utils::OpenHandle(*value);
594 data->set(index, *val);
595 DCHECK_EQ(*Utils::OpenHandle(*value),
596 *Utils::OpenHandle(*GetEmbedderData(index)));
597}
Steve Blocka7e24c12009-10-30 11:49:00 +0000598
Steve Blocka7e24c12009-10-30 11:49:00 +0000599
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000600void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
601 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
602 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
603 if (data.is_null()) return NULL;
604 return DecodeSmiToAligned(data->get(index), location);
605}
Steve Block6ded16b2010-05-10 14:33:55 +0100606
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000607
608void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
609 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
610 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
611 data->set(index, EncodeAlignedAsSmi(value, location));
612 DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
Steve Blocka7e24c12009-10-30 11:49:00 +0000613}
614
615
616// --- N e a n d e r ---
617
618
619// A constructor cannot easily return an error value, therefore it is necessary
620// to check for a dead VM with ON_BAILOUT before constructing any Neander
621// objects. To remind you about this there is no HandleScope in the
622// NeanderObject constructor. When you add one to the site calling the
623// constructor you should check that you ensured the VM was not dead first.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100625 ENTER_V8(isolate);
626 value_ = isolate->factory()->NewNeanderObject();
627 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000628 value_->set_elements(*elements);
629}
630
631
632int NeanderObject::size() {
633 return i::FixedArray::cast(value_->elements())->length();
634}
635
636
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000637NeanderArray::NeanderArray(v8::internal::Isolate* isolate) : obj_(isolate, 2) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000638 obj_.set(0, i::Smi::FromInt(0));
639}
640
641
642int NeanderArray::length() {
643 return i::Smi::cast(obj_.get(0))->value();
644}
645
646
647i::Object* NeanderArray::get(int offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648 DCHECK(0 <= offset);
649 DCHECK(offset < length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000650 return obj_.get(offset + 1);
651}
652
653
654// This method cannot easily return an error value, therefore it is necessary
655// to check for a dead VM with ON_BAILOUT before calling it. To remind you
656// about this there is no HandleScope in this method. When you add one to the
657// site calling this method you should check that you ensured the VM was not
658// dead first.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400659void NeanderArray::add(i::Isolate* isolate, i::Handle<i::Object> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000660 int length = this->length();
661 int size = obj_.size();
662 if (length == size - 1) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400663 i::Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000664 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000665 for (int i = 0; i < length; i++)
666 new_elms->set(i + 1, get(i));
667 obj_.value()->set_elements(*new_elms);
668 }
669 obj_.set(length + 1, *value);
670 obj_.set(0, i::Smi::FromInt(length + 1));
671}
672
673
674void NeanderArray::set(int index, i::Object* value) {
675 if (index < 0 || index >= this->length()) return;
676 obj_.set(index + 1, value);
677}
678
679
680// --- T e m p l a t e ---
681
682
683static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
684 that->set_tag(i::Smi::FromInt(type));
685}
686
687
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000688static void TemplateSet(i::Isolate* isolate,
689 v8::Template* templ,
690 int length,
691 v8::Handle<v8::Data>* data) {
692 i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000693 if (list->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000694 list = NeanderArray(isolate).value();
695 Utils::OpenHandle(templ)->set_property_list(*list);
Steve Blocka7e24c12009-10-30 11:49:00 +0000696 }
697 NeanderArray array(list);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400698 array.add(isolate, isolate->factory()->NewNumberFromInt(length));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000699 for (int i = 0; i < length; i++) {
700 i::Handle<i::Object> value = data[i].IsEmpty() ?
701 i::Handle<i::Object>(isolate->factory()->undefined_value()) :
702 Utils::OpenHandle(*data[i]);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400703 array.add(isolate, value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000704 }
705}
706
707
708void Template::Set(v8::Handle<Name> name,
709 v8::Handle<Data> value,
710 v8::PropertyAttribute attribute) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400711 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000712 ENTER_V8(isolate);
713 i::HandleScope scope(isolate);
714 const int kSize = 3;
715 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
716 v8::Handle<v8::Data> data[kSize] = {
717 name,
718 value,
719 v8::Integer::New(v8_isolate, attribute)};
720 TemplateSet(isolate, this, kSize, data);
721}
722
723
724void Template::SetAccessorProperty(
725 v8::Local<v8::Name> name,
726 v8::Local<FunctionTemplate> getter,
727 v8::Local<FunctionTemplate> setter,
728 v8::PropertyAttribute attribute,
729 v8::AccessControl access_control) {
730 // TODO(verwaest): Remove |access_control|.
731 DCHECK_EQ(v8::DEFAULT, access_control);
732 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
733 ENTER_V8(isolate);
734 DCHECK(!name.IsEmpty());
735 DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
736 i::HandleScope scope(isolate);
737 const int kSize = 5;
738 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
739 v8::Handle<v8::Data> data[kSize] = {
740 name,
741 getter,
742 setter,
743 v8::Integer::New(v8_isolate, attribute)};
744 TemplateSet(isolate, this, kSize, data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000745}
746
747
748// --- F u n c t i o n T e m p l a t e ---
749static void InitializeFunctionTemplate(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000750 i::Handle<i::FunctionTemplateInfo> info) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000751 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
752 info->set_flag(0);
753}
754
755
756Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000757 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
758 ENTER_V8(i_isolate);
759 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
760 i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000761 if (result->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000762 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(i_isolate);
763 result = Utils::OpenHandle(*ObjectTemplate::New(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +0000764 Utils::OpenHandle(this)->set_prototype_template(*result);
765 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000766 return ToApiHandle<ObjectTemplate>(result);
Steve Blocka7e24c12009-10-30 11:49:00 +0000767}
768
769
770void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100771 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100772 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000773 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
774}
775
776
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000777static Local<FunctionTemplate> FunctionTemplateNew(
778 i::Isolate* isolate,
779 FunctionCallback callback,
780 v8::Handle<Value> data,
781 v8::Handle<Signature> signature,
782 int length,
783 bool do_not_cache) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000784 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100785 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000786 i::Handle<i::FunctionTemplateInfo> obj =
787 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
788 InitializeFunctionTemplate(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000789 obj->set_do_not_cache(do_not_cache);
790 int next_serial_number = 0;
791 if (!do_not_cache) {
792 next_serial_number = isolate->next_serial_number() + 1;
793 isolate->set_next_serial_number(next_serial_number);
794 }
Steve Block44f0eee2011-05-26 01:26:41 +0100795 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +0000796 if (callback != 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797 if (data.IsEmpty()) {
798 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
799 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000800 Utils::ToLocal(obj)->SetCallHandler(callback, data);
801 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000802 obj->set_length(length);
Steve Blocka7e24c12009-10-30 11:49:00 +0000803 obj->set_undetectable(false);
804 obj->set_needs_access_check(false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000805 if (!signature.IsEmpty())
806 obj->set_signature(*Utils::OpenHandle(*signature));
807 return Utils::ToLocal(obj);
808}
809
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000810Local<FunctionTemplate> FunctionTemplate::New(
811 Isolate* isolate,
812 FunctionCallback callback,
813 v8::Handle<Value> data,
814 v8::Handle<Signature> signature,
815 int length) {
816 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400817 // Changes to the environment cannot be captured in the snapshot. Expect no
818 // function templates when the isolate is created for serialization.
819 DCHECK(!i_isolate->serializer_enabled());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000820 LOG_API(i_isolate, "FunctionTemplate::New");
821 ENTER_V8(i_isolate);
822 return FunctionTemplateNew(
823 i_isolate, callback, data, signature, length, false);
824}
Steve Blocka7e24c12009-10-30 11:49:00 +0000825
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000826
827Local<Signature> Signature::New(Isolate* isolate,
828 Handle<FunctionTemplate> receiver, int argc,
829 Handle<FunctionTemplate> argv[]) {
830 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
831 LOG_API(i_isolate, "Signature::New");
832 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000833 i::Handle<i::Struct> struct_obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000834 i_isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000835 i::Handle<i::SignatureInfo> obj =
836 i::Handle<i::SignatureInfo>::cast(struct_obj);
837 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
838 if (argc > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000839 i::Handle<i::FixedArray> args = i_isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000840 for (int i = 0; i < argc; i++) {
841 if (!argv[i].IsEmpty())
842 args->set(i, *Utils::OpenHandle(*argv[i]));
843 }
844 obj->set_args(*args);
845 }
846 return Utils::ToLocal(obj);
847}
848
849
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000850Local<AccessorSignature> AccessorSignature::New(
851 Isolate* isolate,
852 Handle<FunctionTemplate> receiver) {
853 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
854}
855
856
857template<typename Operation>
858static Local<Operation> NewDescriptor(
859 Isolate* isolate,
860 const i::DeclaredAccessorDescriptorData& data,
861 Data* previous_descriptor) {
862 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
863 i::Handle<i::DeclaredAccessorDescriptor> previous =
864 i::Handle<i::DeclaredAccessorDescriptor>();
865 if (previous_descriptor != NULL) {
866 previous = Utils::OpenHandle(
867 static_cast<DeclaredAccessorDescriptor*>(previous_descriptor));
868 }
869 i::Handle<i::DeclaredAccessorDescriptor> descriptor =
870 i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous);
871 return Utils::Convert<i::DeclaredAccessorDescriptor, Operation>(descriptor);
872}
873
874
875Local<RawOperationDescriptor>
876ObjectOperationDescriptor::NewInternalFieldDereference(
877 Isolate* isolate,
878 int internal_field) {
879 i::DeclaredAccessorDescriptorData data;
880 data.type = i::kDescriptorObjectDereference;
881 data.object_dereference_descriptor.internal_field = internal_field;
882 return NewDescriptor<RawOperationDescriptor>(isolate, data, NULL);
883}
884
885
886Local<RawOperationDescriptor> RawOperationDescriptor::NewRawShift(
887 Isolate* isolate,
888 int16_t byte_offset) {
889 i::DeclaredAccessorDescriptorData data;
890 data.type = i::kDescriptorPointerShift;
891 data.pointer_shift_descriptor.byte_offset = byte_offset;
892 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
893}
894
895
896Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewHandleDereference(
897 Isolate* isolate) {
898 i::DeclaredAccessorDescriptorData data;
899 data.type = i::kDescriptorReturnObject;
900 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
901}
902
903
904Local<RawOperationDescriptor> RawOperationDescriptor::NewRawDereference(
905 Isolate* isolate) {
906 i::DeclaredAccessorDescriptorData data;
907 data.type = i::kDescriptorPointerDereference;
908 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
909}
910
911
912Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPointerCompare(
913 Isolate* isolate,
914 void* compare_value) {
915 i::DeclaredAccessorDescriptorData data;
916 data.type = i::kDescriptorPointerCompare;
917 data.pointer_compare_descriptor.compare_value = compare_value;
918 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
919}
920
921
922Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPrimitiveValue(
923 Isolate* isolate,
924 DeclaredAccessorDescriptorDataType data_type,
925 uint8_t bool_offset) {
926 i::DeclaredAccessorDescriptorData data;
927 data.type = i::kDescriptorPrimitiveValue;
928 data.primitive_value_descriptor.data_type = data_type;
929 data.primitive_value_descriptor.bool_offset = bool_offset;
930 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
931}
932
933
934template<typename T>
935static Local<DeclaredAccessorDescriptor> NewBitmaskCompare(
936 Isolate* isolate,
937 T bitmask,
938 T compare_value,
939 RawOperationDescriptor* operation) {
940 i::DeclaredAccessorDescriptorData data;
941 data.type = i::kDescriptorBitmaskCompare;
942 data.bitmask_compare_descriptor.bitmask = bitmask;
943 data.bitmask_compare_descriptor.compare_value = compare_value;
944 data.bitmask_compare_descriptor.size = sizeof(T);
945 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, operation);
946}
947
948
949Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare8(
950 Isolate* isolate,
951 uint8_t bitmask,
952 uint8_t compare_value) {
953 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
954}
955
956
957Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare16(
958 Isolate* isolate,
959 uint16_t bitmask,
960 uint16_t compare_value) {
961 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
962}
963
964
965Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare32(
966 Isolate* isolate,
967 uint32_t bitmask,
968 uint32_t compare_value) {
969 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
970}
971
972
Steve Blocka7e24c12009-10-30 11:49:00 +0000973Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
974 Handle<FunctionTemplate> types[1] = { type };
975 return TypeSwitch::New(1, types);
976}
977
978
979Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
Steve Block44f0eee2011-05-26 01:26:41 +0100980 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +0100981 LOG_API(isolate, "TypeSwitch::New");
982 ENTER_V8(isolate);
983 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000984 for (int i = 0; i < argc; i++)
985 vector->set(i, *Utils::OpenHandle(*types[i]));
986 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100987 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000988 i::Handle<i::TypeSwitchInfo> obj =
989 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
990 obj->set_types(*vector);
991 return Utils::ToLocal(obj);
992}
993
994
995int TypeSwitch::match(v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000996 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400997 LOG_API(info->GetIsolate(), "TypeSwitch::match");
998 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000999 i::FixedArray* types = i::FixedArray::cast(info->types());
1000 for (int i = 0; i < types->length(); i++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001001 if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
Steve Blocka7e24c12009-10-30 11:49:00 +00001002 return i + 1;
1003 }
1004 return 0;
1005}
1006
1007
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001008#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
1009 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
1010 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001011 } while (false)
1012
1013
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001014void FunctionTemplate::SetCallHandler(FunctionCallback callback,
Steve Blocka7e24c12009-10-30 11:49:00 +00001015 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001016 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001017 ENTER_V8(isolate);
1018 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001019 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001020 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001021 i::Handle<i::CallHandlerInfo> obj =
1022 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001023 SET_FIELD_WRAPPED(obj, set_callback, callback);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001024 if (data.IsEmpty()) {
1025 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1026 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001027 obj->set_data(*Utils::OpenHandle(*data));
1028 Utils::OpenHandle(this)->set_call_code(*obj);
1029}
1030
1031
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001032static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1033 i::Handle<i::AccessorInfo> obj,
1034 v8::Handle<Name> name,
1035 v8::AccessControl settings,
1036 v8::PropertyAttribute attributes,
1037 v8::Handle<AccessorSignature> signature) {
Leon Clarkef7060e22010-06-03 12:02:55 +01001038 obj->set_name(*Utils::OpenHandle(*name));
1039 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1040 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
Leon Clarkef7060e22010-06-03 12:02:55 +01001041 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001042 if (!signature.IsEmpty()) {
1043 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1044 }
Leon Clarkef7060e22010-06-03 12:02:55 +01001045 return obj;
1046}
1047
1048
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001049template<typename Getter, typename Setter>
1050static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1051 v8::Handle<Name> name,
1052 Getter getter,
1053 Setter setter,
1054 v8::Handle<Value> data,
1055 v8::AccessControl settings,
1056 v8::PropertyAttribute attributes,
1057 v8::Handle<AccessorSignature> signature) {
1058 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1059 i::Handle<i::ExecutableAccessorInfo> obj =
1060 isolate->factory()->NewExecutableAccessorInfo();
1061 SET_FIELD_WRAPPED(obj, set_getter, getter);
1062 SET_FIELD_WRAPPED(obj, set_setter, setter);
1063 if (data.IsEmpty()) {
1064 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00001065 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001066 obj->set_data(*Utils::OpenHandle(*data));
1067 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1068}
Steve Blocka7e24c12009-10-30 11:49:00 +00001069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001070
1071static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1072 v8::Handle<Name> name,
1073 v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
1074 void* setter_ignored,
1075 void* data_ignored,
1076 v8::AccessControl settings,
1077 v8::PropertyAttribute attributes,
1078 v8::Handle<AccessorSignature> signature) {
1079 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1080 if (descriptor.IsEmpty()) return i::Handle<i::DeclaredAccessorInfo>();
1081 i::Handle<i::DeclaredAccessorInfo> obj =
1082 isolate->factory()->NewDeclaredAccessorInfo();
1083 obj->set_descriptor(*Utils::OpenHandle(*descriptor));
1084 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
Steve Blocka7e24c12009-10-30 11:49:00 +00001085}
1086
1087
1088Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001089 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1090 if (!Utils::ApiCheck(!handle.is_null(),
1091 "v8::FunctionTemplate::InstanceTemplate()",
1092 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001093 return Local<ObjectTemplate>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001094 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001095 i::Isolate* isolate = handle->GetIsolate();
1096 ENTER_V8(isolate);
1097 if (handle->instance_template()->IsUndefined()) {
1098 Local<ObjectTemplate> templ =
1099 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1100 handle->set_instance_template(*Utils::OpenHandle(*templ));
1101 }
1102 i::Handle<i::ObjectTemplateInfo> result(
1103 i::ObjectTemplateInfo::cast(handle->instance_template()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001104 return Utils::ToLocal(result);
1105}
1106
1107
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001108void FunctionTemplate::SetLength(int length) {
1109 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1110 ENTER_V8(isolate);
1111 Utils::OpenHandle(this)->set_length(length);
1112}
1113
1114
Steve Blocka7e24c12009-10-30 11:49:00 +00001115void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01001116 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001117 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001118 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1119}
1120
1121
1122void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001123 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001124 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001125 Utils::OpenHandle(this)->set_hidden_prototype(value);
1126}
1127
1128
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001129void FunctionTemplate::ReadOnlyPrototype() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001130 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001131 ENTER_V8(isolate);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001132 Utils::OpenHandle(this)->set_read_only_prototype(true);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001133}
1134
1135
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001136void FunctionTemplate::RemovePrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01001137 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001138 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001139 Utils::OpenHandle(this)->set_remove_prototype(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001140}
1141
1142
1143// --- O b j e c t T e m p l a t e ---
1144
1145
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001146Local<ObjectTemplate> ObjectTemplate::New(Isolate* isolate) {
1147 return New(reinterpret_cast<i::Isolate*>(isolate), Local<FunctionTemplate>());
1148}
1149
1150
Steve Blocka7e24c12009-10-30 11:49:00 +00001151Local<ObjectTemplate> ObjectTemplate::New() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001152 return New(i::Isolate::Current(), Local<FunctionTemplate>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001153}
1154
1155
1156Local<ObjectTemplate> ObjectTemplate::New(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001157 i::Isolate* isolate,
1158 v8::Handle<FunctionTemplate> constructor) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001159 // Changes to the environment cannot be captured in the snapshot. Expect no
1160 // object templates when the isolate is created for serialization.
1161 DCHECK(!isolate->serializer_enabled());
Steve Block44f0eee2011-05-26 01:26:41 +01001162 LOG_API(isolate, "ObjectTemplate::New");
1163 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001164 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001165 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001166 i::Handle<i::ObjectTemplateInfo> obj =
1167 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1168 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1169 if (!constructor.IsEmpty())
1170 obj->set_constructor(*Utils::OpenHandle(*constructor));
1171 obj->set_internal_field_count(i::Smi::FromInt(0));
1172 return Utils::ToLocal(obj);
1173}
1174
1175
1176// Ensure that the object template has a constructor. If no
1177// constructor is available we create one.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001178static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1179 i::Isolate* isolate,
1180 ObjectTemplate* object_template) {
1181 i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1182 if (!obj ->IsUndefined()) {
1183 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1184 return i::Handle<i::FunctionTemplateInfo>(info, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001185 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001186 Local<FunctionTemplate> templ =
1187 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1188 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1189 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1190 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1191 return constructor;
1192}
1193
1194
1195static inline void AddPropertyToTemplate(
1196 i::Handle<i::TemplateInfo> info,
1197 i::Handle<i::AccessorInfo> obj) {
1198 i::Isolate* isolate = info->GetIsolate();
1199 i::Handle<i::Object> list(info->property_accessors(), isolate);
1200 if (list->IsUndefined()) {
1201 list = NeanderArray(isolate).value();
1202 info->set_property_accessors(*list);
1203 }
1204 NeanderArray array(list);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001205 array.add(isolate, obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001206}
1207
1208
1209static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1210 i::Isolate* isolate,
1211 Template* template_obj) {
1212 return Utils::OpenHandle(template_obj);
1213}
1214
1215
1216// TODO(dcarney): remove this with ObjectTemplate::SetAccessor
1217static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1218 i::Isolate* isolate,
1219 ObjectTemplate* object_template) {
1220 EnsureConstructor(isolate, object_template);
1221 return Utils::OpenHandle(object_template);
1222}
1223
1224
1225template<typename Getter, typename Setter, typename Data, typename Template>
1226static bool TemplateSetAccessor(
1227 Template* template_obj,
1228 v8::Local<Name> name,
1229 Getter getter,
1230 Setter setter,
1231 Data data,
1232 AccessControl settings,
1233 PropertyAttribute attribute,
1234 v8::Local<AccessorSignature> signature) {
1235 i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
1236 ENTER_V8(isolate);
1237 i::HandleScope scope(isolate);
1238 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
1239 name, getter, setter, data, settings, attribute, signature);
1240 if (obj.is_null()) return false;
1241 i::Handle<i::TemplateInfo> info = GetTemplateInfo(isolate, template_obj);
1242 AddPropertyToTemplate(info, obj);
1243 return true;
1244}
1245
1246
1247bool Template::SetDeclaredAccessor(
1248 Local<Name> name,
1249 Local<DeclaredAccessorDescriptor> descriptor,
1250 PropertyAttribute attribute,
1251 Local<AccessorSignature> signature,
1252 AccessControl settings) {
1253 void* null = NULL;
1254 return TemplateSetAccessor(
1255 this, name, descriptor, null, null, settings, attribute, signature);
1256}
1257
1258
1259void Template::SetNativeDataProperty(v8::Local<String> name,
1260 AccessorGetterCallback getter,
1261 AccessorSetterCallback setter,
1262 v8::Handle<Value> data,
1263 PropertyAttribute attribute,
1264 v8::Local<AccessorSignature> signature,
1265 AccessControl settings) {
1266 TemplateSetAccessor(
1267 this, name, getter, setter, data, settings, attribute, signature);
1268}
1269
1270
1271void Template::SetNativeDataProperty(v8::Local<Name> name,
1272 AccessorNameGetterCallback getter,
1273 AccessorNameSetterCallback setter,
1274 v8::Handle<Value> data,
1275 PropertyAttribute attribute,
1276 v8::Local<AccessorSignature> signature,
1277 AccessControl settings) {
1278 TemplateSetAccessor(
1279 this, name, getter, setter, data, settings, attribute, signature);
Steve Blocka7e24c12009-10-30 11:49:00 +00001280}
1281
1282
1283void ObjectTemplate::SetAccessor(v8::Handle<String> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001284 AccessorGetterCallback getter,
1285 AccessorSetterCallback setter,
Steve Blocka7e24c12009-10-30 11:49:00 +00001286 v8::Handle<Value> data,
1287 AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001288 PropertyAttribute attribute,
1289 v8::Handle<AccessorSignature> signature) {
1290 TemplateSetAccessor(
1291 this, name, getter, setter, data, settings, attribute, signature);
Steve Blocka7e24c12009-10-30 11:49:00 +00001292}
1293
1294
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001295void ObjectTemplate::SetAccessor(v8::Handle<Name> name,
1296 AccessorNameGetterCallback getter,
1297 AccessorNameSetterCallback setter,
1298 v8::Handle<Value> data,
1299 AccessControl settings,
1300 PropertyAttribute attribute,
1301 v8::Handle<AccessorSignature> signature) {
1302 TemplateSetAccessor(
1303 this, name, getter, setter, data, settings, attribute, signature);
1304}
1305
1306
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001307template <typename Getter, typename Setter, typename Query, typename Deleter,
1308 typename Enumerator>
1309static void ObjectTemplateSetNamedPropertyHandler(
1310 ObjectTemplate* templ, Getter getter, Setter setter, Query query,
1311 Deleter remover, Enumerator enumerator, Handle<Value> data,
1312 bool can_intercept_symbols, PropertyHandlerFlags flags) {
1313 i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001314 ENTER_V8(isolate);
1315 i::HandleScope scope(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001316 EnsureConstructor(isolate, templ);
1317 i::FunctionTemplateInfo* constructor =
1318 i::FunctionTemplateInfo::cast(Utils::OpenHandle(templ)->constructor());
Steve Blocka7e24c12009-10-30 11:49:00 +00001319 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001320 auto obj = i::Handle<i::InterceptorInfo>::cast(
1321 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001322
1323 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1324 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1325 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1326 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1327 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001328 obj->set_flags(0);
1329 obj->set_can_intercept_symbols(can_intercept_symbols);
1330 obj->set_all_can_read(static_cast<int>(flags) &
1331 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001332
1333 if (data.IsEmpty()) {
1334 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1335 }
1336 obj->set_data(*Utils::OpenHandle(*data));
1337 cons->set_named_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001338}
1339
1340
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001341void ObjectTemplate::SetNamedPropertyHandler(
1342 NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
1343 NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
1344 NamedPropertyEnumeratorCallback enumerator, Handle<Value> data) {
1345 ObjectTemplateSetNamedPropertyHandler(this, getter, setter, query, remover,
1346 enumerator, data, false,
1347 PropertyHandlerFlags::kNone);
1348}
1349
1350
1351void ObjectTemplate::SetHandler(
1352 const NamedPropertyHandlerConfiguration& config) {
1353 ObjectTemplateSetNamedPropertyHandler(
1354 this, config.getter, config.setter, config.query, config.deleter,
1355 config.enumerator, config.data, true, config.flags);
1356}
1357
1358
Steve Blocka7e24c12009-10-30 11:49:00 +00001359void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001360 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001361 ENTER_V8(isolate);
1362 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001363 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001364 i::FunctionTemplateInfo* constructor =
1365 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1366 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1367 cons->set_undetectable(true);
1368}
1369
1370
1371void ObjectTemplate::SetAccessCheckCallbacks(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001372 NamedSecurityCallback named_callback,
1373 IndexedSecurityCallback indexed_callback,
1374 Handle<Value> data,
1375 bool turned_on_by_default) {
Steve Block44f0eee2011-05-26 01:26:41 +01001376 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001377 ENTER_V8(isolate);
1378 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001379 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001380
1381 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001382 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001383 i::Handle<i::AccessCheckInfo> info =
1384 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001385
1386 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1387 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1388
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001389 if (data.IsEmpty()) {
1390 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1391 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001392 info->set_data(*Utils::OpenHandle(*data));
1393
1394 i::FunctionTemplateInfo* constructor =
1395 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1396 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1397 cons->set_access_check_info(*info);
1398 cons->set_needs_access_check(turned_on_by_default);
1399}
1400
1401
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001402void ObjectTemplate::SetHandler(
1403 const IndexedPropertyHandlerConfiguration& config) {
Steve Block44f0eee2011-05-26 01:26:41 +01001404 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001405 ENTER_V8(isolate);
1406 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001407 EnsureConstructor(isolate, this);
1408 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1409 Utils::OpenHandle(this)->constructor());
Steve Blocka7e24c12009-10-30 11:49:00 +00001410 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001411 auto obj = i::Handle<i::InterceptorInfo>::cast(
1412 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001413
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001414 if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
1415 if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
1416 if (config.query != 0) SET_FIELD_WRAPPED(obj, set_query, config.query);
1417 if (config.deleter != 0) SET_FIELD_WRAPPED(obj, set_deleter, config.deleter);
1418 if (config.enumerator != 0) {
1419 SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
1420 }
1421 obj->set_flags(0);
1422 obj->set_all_can_read(static_cast<int>(config.flags) &
1423 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001424
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001425 v8::Local<v8::Value> data = config.data;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001426 if (data.IsEmpty()) {
1427 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1428 }
1429 obj->set_data(*Utils::OpenHandle(*data));
1430 cons->set_indexed_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001431}
1432
1433
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001434void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
Steve Blocka7e24c12009-10-30 11:49:00 +00001435 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001436 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001437 ENTER_V8(isolate);
1438 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001439 EnsureConstructor(isolate, this);
1440 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1441 Utils::OpenHandle(this)->constructor());
Steve Blocka7e24c12009-10-30 11:49:00 +00001442 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001443 i::Handle<i::Struct> struct_obj =
1444 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1445 i::Handle<i::CallHandlerInfo> obj =
1446 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1447 SET_FIELD_WRAPPED(obj, set_callback, callback);
1448 if (data.IsEmpty()) {
1449 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1450 }
1451 obj->set_data(*Utils::OpenHandle(*data));
1452 cons->set_instance_call_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001453}
1454
1455
1456int ObjectTemplate::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00001457 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1458}
1459
1460
1461void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001462 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001463 if (!Utils::ApiCheck(i::Smi::IsValid(value),
1464 "v8::ObjectTemplate::SetInternalFieldCount()",
1465 "Invalid internal field count")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001466 return;
1467 }
Steve Block44f0eee2011-05-26 01:26:41 +01001468 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001469 if (value > 0) {
1470 // The internal field count is set by the constructor function's
1471 // construct code, so we ensure that there is a constructor
1472 // function to do the setting.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001473 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001474 }
1475 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1476}
1477
1478
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001479// --- S c r i p t s ---
Steve Blocka7e24c12009-10-30 11:49:00 +00001480
1481
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001482// Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1483// JSFunction.
1484
1485ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1486 BufferPolicy buffer_policy_)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001487 : data(data_),
1488 length(length_),
1489 rejected(false),
1490 buffer_policy(buffer_policy_) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001491
1492
1493ScriptCompiler::CachedData::~CachedData() {
1494 if (buffer_policy == BufferOwned) {
1495 delete[] data;
1496 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001497}
1498
1499
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001500ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
1501 Encoding encoding)
1502 : impl_(new i::StreamedSource(stream, encoding)) {}
1503
1504
1505ScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; }
1506
1507
1508const ScriptCompiler::CachedData*
1509ScriptCompiler::StreamedSource::GetCachedData() const {
1510 return impl_->cached_data.get();
1511}
1512
1513
1514Local<Script> UnboundScript::BindToCurrentContext() {
1515 i::Handle<i::HeapObject> obj =
1516 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1517 i::Handle<i::SharedFunctionInfo>
1518 function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
1519 i::Handle<i::JSFunction> function =
1520 obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001521 function_info, obj->GetIsolate()->native_context());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001522 return ToApiHandle<Script>(function);
1523}
1524
1525
1526int UnboundScript::GetId() {
1527 i::Handle<i::HeapObject> obj =
1528 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1529 i::Isolate* isolate = obj->GetIsolate();
1530 ON_BAILOUT(isolate, "v8::UnboundScript::GetId()", return -1);
1531 LOG_API(isolate, "v8::UnboundScript::GetId");
1532 {
1533 i::HandleScope scope(isolate);
1534 i::Handle<i::SharedFunctionInfo> function_info(
1535 i::SharedFunctionInfo::cast(*obj));
1536 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1537 return script->id()->value();
1538 }
1539}
1540
1541
1542int UnboundScript::GetLineNumber(int code_pos) {
1543 i::Handle<i::SharedFunctionInfo> obj =
1544 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1545 i::Isolate* isolate = obj->GetIsolate();
1546 ON_BAILOUT(isolate, "v8::UnboundScript::GetLineNumber()", return -1);
1547 LOG_API(isolate, "UnboundScript::GetLineNumber");
1548 if (obj->script()->IsScript()) {
1549 i::Handle<i::Script> script(i::Script::cast(obj->script()));
1550 return i::Script::GetLineNumber(script, code_pos);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001551 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001552 return -1;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001553 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001554}
1555
1556
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001557Handle<Value> UnboundScript::GetScriptName() {
1558 i::Handle<i::SharedFunctionInfo> obj =
1559 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1560 i::Isolate* isolate = obj->GetIsolate();
1561 ON_BAILOUT(isolate, "v8::UnboundScript::GetName()",
1562 return Handle<String>());
1563 LOG_API(isolate, "UnboundScript::GetName");
1564 if (obj->script()->IsScript()) {
1565 i::Object* name = i::Script::cast(obj->script())->name();
1566 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1567 } else {
1568 return Handle<String>();
Leon Clarkef7060e22010-06-03 12:02:55 +01001569 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001570}
Leon Clarkef7060e22010-06-03 12:02:55 +01001571
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001572
1573Handle<Value> UnboundScript::GetSourceURL() {
1574 i::Handle<i::SharedFunctionInfo> obj =
1575 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1576 i::Isolate* isolate = obj->GetIsolate();
1577 ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceURL()",
1578 return Handle<String>());
1579 LOG_API(isolate, "UnboundScript::GetSourceURL");
1580 if (obj->script()->IsScript()) {
1581 i::Object* url = i::Script::cast(obj->script())->source_url();
1582 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1583 } else {
1584 return Handle<String>();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001585 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001586}
1587
1588
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001589Handle<Value> UnboundScript::GetSourceMappingURL() {
1590 i::Handle<i::SharedFunctionInfo> obj =
1591 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1592 i::Isolate* isolate = obj->GetIsolate();
1593 ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceMappingURL()",
1594 return Handle<String>());
1595 LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
1596 if (obj->script()->IsScript()) {
1597 i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
1598 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1599 } else {
1600 return Handle<String>();
Ben Murdoch692be652012-01-10 18:47:50 +00001601 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001602}
1603
1604
1605Local<Value> Script::Run() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001606 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
1607 // If execution is terminating, Compile(..)->Run() requires this
1608 // check.
1609 if (obj.is_null()) return Local<Value>();
1610 i::Isolate* isolate = i::Handle<i::HeapObject>::cast(obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001611 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1612 LOG_API(isolate, "Script::Run");
1613 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001614 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
1615 i::HandleScope scope(isolate);
1616 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
1617 EXCEPTION_PREAMBLE(isolate);
1618 i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
1619 i::Handle<i::Object> result;
1620 has_pending_exception = !i::Execution::Call(
1621 isolate, fun, receiver, 0, NULL).ToHandle(&result);
1622 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
1623 return Utils::ToLocal(scope.CloseAndEscape(result));
1624}
1625
1626
1627Local<UnboundScript> Script::GetUnboundScript() {
1628 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1629 return ToApiHandle<UnboundScript>(
1630 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
1631}
1632
1633
1634Local<UnboundScript> ScriptCompiler::CompileUnbound(
1635 Isolate* v8_isolate,
1636 Source* source,
1637 CompileOptions options) {
1638 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1639 ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()",
1640 return Local<UnboundScript>());
1641
1642 // Support the old API for a transition period:
1643 // - kProduceToCache -> kProduceParserCache
1644 // - kNoCompileOptions + cached_data != NULL -> kConsumeParserCache
1645 if (options == kProduceDataToCache) {
1646 options = kProduceParserCache;
1647 } else if (options == kNoCompileOptions && source->cached_data) {
1648 options = kConsumeParserCache;
1649 }
1650
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001651 // Don't try to produce any kind of cache when the debugger is loaded.
1652 if (isolate->debug()->is_loaded() &&
1653 (options == kProduceParserCache || options == kProduceCodeCache)) {
1654 options = kNoCompileOptions;
1655 }
1656
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001657 i::ScriptData* script_data = NULL;
1658 if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1659 DCHECK(source->cached_data);
1660 // ScriptData takes care of pointer-aligning the data.
1661 script_data = new i::ScriptData(source->cached_data->data,
1662 source->cached_data->length);
1663 }
1664
1665 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
1666 LOG_API(isolate, "ScriptCompiler::CompileUnbound");
1667 ENTER_V8(isolate);
1668 i::SharedFunctionInfo* raw_result = NULL;
1669 { i::HandleScope scope(isolate);
1670 i::Handle<i::Object> name_obj;
1671 int line_offset = 0;
1672 int column_offset = 0;
1673 bool is_shared_cross_origin = false;
1674 if (!source->resource_name.IsEmpty()) {
1675 name_obj = Utils::OpenHandle(*(source->resource_name));
1676 }
1677 if (!source->resource_line_offset.IsEmpty()) {
1678 line_offset = static_cast<int>(source->resource_line_offset->Value());
1679 }
1680 if (!source->resource_column_offset.IsEmpty()) {
1681 column_offset =
1682 static_cast<int>(source->resource_column_offset->Value());
1683 }
1684 if (!source->resource_is_shared_cross_origin.IsEmpty()) {
1685 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
1686 is_shared_cross_origin =
1687 source->resource_is_shared_cross_origin == v8::True(v8_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001688 }
Steve Block44f0eee2011-05-26 01:26:41 +01001689 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001690 i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript(
1691 str, name_obj, line_offset, column_offset, is_shared_cross_origin,
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001692 isolate->native_context(), NULL, &script_data, options,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001693 i::NOT_NATIVES_CODE);
1694 has_pending_exception = result.is_null();
1695 if (has_pending_exception && script_data != NULL) {
1696 // This case won't happen during normal operation; we have compiled
1697 // successfully and produced cached data, and but the second compilation
1698 // of the same source code fails.
1699 delete script_data;
1700 script_data = NULL;
1701 }
1702 EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001703 raw_result = *result;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001704
1705 if ((options == kProduceParserCache || options == kProduceCodeCache) &&
1706 script_data != NULL) {
1707 // script_data now contains the data that was generated. source will
1708 // take the ownership.
1709 source->cached_data = new CachedData(
1710 script_data->data(), script_data->length(), CachedData::BufferOwned);
1711 script_data->ReleaseDataOwnership();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001712 } else if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1713 source->cached_data->rejected = script_data->rejected();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001714 }
1715 delete script_data;
Steve Blocka7e24c12009-10-30 11:49:00 +00001716 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001717 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
1718 return ToApiHandle<UnboundScript>(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001719}
1720
1721
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001722Local<Script> ScriptCompiler::Compile(
1723 Isolate* v8_isolate,
1724 Source* source,
1725 CompileOptions options) {
1726 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1727 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
1728 LOG_API(isolate, "ScriptCompiler::CompiletBound()");
1729 ENTER_V8(isolate);
1730 Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options);
1731 if (generic.IsEmpty()) return Local<Script>();
1732 return generic->BindToCurrentContext();
Steve Block6ded16b2010-05-10 14:33:55 +01001733}
1734
1735
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001736ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
1737 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
1738 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001739 return new i::BackgroundParsingTask(source->impl(), options,
1740 i::FLAG_stack_size, isolate);
1741}
1742
1743
1744Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
1745 StreamedSource* v8_source,
1746 Handle<String> full_source_string,
1747 const ScriptOrigin& origin) {
1748 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1749 i::StreamedSource* source = v8_source->impl();
1750 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
1751 LOG_API(isolate, "ScriptCompiler::Compile()");
1752 ENTER_V8(isolate);
1753 i::SharedFunctionInfo* raw_result = NULL;
1754
Steve Blocka7e24c12009-10-30 11:49:00 +00001755 {
Steve Block44f0eee2011-05-26 01:26:41 +01001756 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001757 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
1758 i::Handle<i::Script> script = isolate->factory()->NewScript(str);
1759 if (!origin.ResourceName().IsEmpty()) {
1760 script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
1761 }
1762 if (!origin.ResourceLineOffset().IsEmpty()) {
1763 script->set_line_offset(i::Smi::FromInt(
1764 static_cast<int>(origin.ResourceLineOffset()->Value())));
1765 }
1766 if (!origin.ResourceColumnOffset().IsEmpty()) {
1767 script->set_column_offset(i::Smi::FromInt(
1768 static_cast<int>(origin.ResourceColumnOffset()->Value())));
1769 }
1770 if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) {
1771 script->set_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin() ==
1772 v8::True(v8_isolate));
1773 }
1774 source->info->set_script(script);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001775 source->info->SetContext(isolate->native_context());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001776
1777 EXCEPTION_PREAMBLE(isolate);
1778
1779 // Do the parsing tasks which need to be done on the main thread. This will
1780 // also handle parse errors.
1781 source->parser->Internalize();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001782 source->parser->HandleSourceURLComments();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001783
1784 i::Handle<i::SharedFunctionInfo> result =
1785 i::Handle<i::SharedFunctionInfo>::null();
1786 if (source->info->function() != NULL) {
1787 // Parsing has succeeded.
1788 result =
1789 i::Compiler::CompileStreamedScript(source->info.get(), str->length());
1790 }
1791 has_pending_exception = result.is_null();
1792 if (has_pending_exception) isolate->ReportPendingMessages();
1793 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
1794
1795 raw_result = *result;
1796 // The Handle<Script> will go out of scope soon; make sure CompilationInfo
1797 // doesn't point to it.
1798 source->info->set_script(i::Handle<i::Script>());
1799 } // HandleScope goes out of scope.
1800 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
1801 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
1802 if (generic.IsEmpty()) {
1803 return Local<Script>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001804 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001805 return generic->BindToCurrentContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00001806}
1807
1808
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001809uint32_t ScriptCompiler::CachedDataVersionTag() {
1810 return static_cast<uint32_t>(base::hash_combine(
1811 internal::Version::Hash(), internal::FlagList::Hash(),
1812 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
1813}
1814
1815
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001816Local<Script> Script::Compile(v8::Handle<String> source,
1817 v8::ScriptOrigin* origin) {
1818 i::Handle<i::String> str = Utils::OpenHandle(*source);
1819 if (origin) {
1820 ScriptCompiler::Source script_source(source, *origin);
1821 return ScriptCompiler::Compile(
1822 reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
1823 &script_source);
Steve Blocka7e24c12009-10-30 11:49:00 +00001824 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001825 ScriptCompiler::Source script_source(source);
1826 return ScriptCompiler::Compile(
1827 reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
1828 &script_source);
1829}
1830
1831
1832Local<Script> Script::Compile(v8::Handle<String> source,
1833 v8::Handle<String> file_name) {
1834 ScriptOrigin origin(file_name);
1835 return Compile(source, &origin);
Steve Blocka7e24c12009-10-30 11:49:00 +00001836}
1837
1838
1839// --- E x c e p t i o n s ---
1840
1841
1842v8::TryCatch::TryCatch()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001843 : isolate_(i::Isolate::Current()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001844 next_(isolate_->try_catch_handler()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001845 is_verbose_(false),
1846 can_continue_(true),
1847 capture_message_(true),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001848 rethrow_(false),
1849 has_terminated_(false) {
1850 ResetInternal();
1851 // Special handling for simulators which have a separate JS stack.
1852 js_stack_comparable_address_ =
1853 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
1854 v8::internal::GetCurrentStackPosition()));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001855 isolate_->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001856}
1857
1858
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001859v8::TryCatch::TryCatch(v8::Isolate* isolate)
1860 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
1861 next_(isolate_->try_catch_handler()),
1862 is_verbose_(false),
1863 can_continue_(true),
1864 capture_message_(true),
1865 rethrow_(false),
1866 has_terminated_(false) {
1867 ResetInternal();
1868 // Special handling for simulators which have a separate JS stack.
1869 js_stack_comparable_address_ =
1870 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
1871 v8::internal::GetCurrentStackPosition()));
1872 isolate_->RegisterTryCatchHandler(this);
1873}
1874
1875
Steve Blocka7e24c12009-10-30 11:49:00 +00001876v8::TryCatch::~TryCatch() {
Steve Blockd0582a62009-12-15 09:54:21 +00001877 if (rethrow_) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001878 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
1879 v8::HandleScope scope(isolate);
1880 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
1881 if (HasCaught() && capture_message_) {
1882 // If an exception was caught and rethrow_ is indicated, the saved
1883 // message, script, and location need to be restored to Isolate TLS
1884 // for reuse. capture_message_ needs to be disabled so that DoThrow()
1885 // does not create a new message.
1886 isolate_->thread_local_top()->rethrowing_message_ = true;
1887 isolate_->RestorePendingMessageFromTryCatch(this);
1888 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001889 isolate_->UnregisterTryCatchHandler(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001890 v8::internal::SimulatorStack::UnregisterCTryCatch();
1891 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
1892 DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
Steve Blockd0582a62009-12-15 09:54:21 +00001893 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001894 if (HasCaught() && isolate_->has_scheduled_exception()) {
1895 // If an exception was caught but is still scheduled because no API call
1896 // promoted it, then it is canceled to prevent it from being propagated.
1897 // Note that this will not cancel termination exceptions.
1898 isolate_->CancelScheduledExceptionFromTryCatch(this);
1899 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001900 isolate_->UnregisterTryCatchHandler(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001901 v8::internal::SimulatorStack::UnregisterCTryCatch();
Steve Blockd0582a62009-12-15 09:54:21 +00001902 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001903}
1904
1905
1906bool v8::TryCatch::HasCaught() const {
1907 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1908}
1909
1910
1911bool v8::TryCatch::CanContinue() const {
1912 return can_continue_;
1913}
1914
1915
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001916bool v8::TryCatch::HasTerminated() const {
1917 return has_terminated_;
1918}
1919
1920
Steve Blockd0582a62009-12-15 09:54:21 +00001921v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1922 if (!HasCaught()) return v8::Local<v8::Value>();
1923 rethrow_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001924 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
Steve Blockd0582a62009-12-15 09:54:21 +00001925}
1926
1927
Steve Blocka7e24c12009-10-30 11:49:00 +00001928v8::Local<Value> v8::TryCatch::Exception() const {
1929 if (HasCaught()) {
1930 // Check for out of memory exception.
1931 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001932 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001933 } else {
1934 return v8::Local<Value>();
1935 }
1936}
1937
1938
1939v8::Local<Value> v8::TryCatch::StackTrace() const {
1940 if (HasCaught()) {
1941 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1942 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001943 i::HandleScope scope(isolate_);
1944 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001945 i::Handle<i::String> name = isolate_->factory()->stack_string();
1946 EXCEPTION_PREAMBLE(isolate_);
1947 Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
1948 has_pending_exception = !maybe.has_value;
1949 EXCEPTION_BAILOUT_CHECK(isolate_, v8::Local<Value>());
1950 if (!maybe.value) return v8::Local<Value>();
1951 i::Handle<i::Object> value;
1952 if (!i::Object::GetProperty(obj, name).ToHandle(&value)) {
1953 return v8::Local<Value>();
1954 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001955 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001956 } else {
1957 return v8::Local<Value>();
1958 }
1959}
1960
1961
1962v8::Local<v8::Message> v8::TryCatch::Message() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001963 i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
1964 DCHECK(message->IsJSMessageObject() || message->IsTheHole());
1965 if (HasCaught() && !message->IsTheHole()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001966 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001967 } else {
1968 return v8::Local<v8::Message>();
1969 }
1970}
1971
1972
1973void v8::TryCatch::Reset() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001974 if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
1975 // If an exception was caught but is still scheduled because no API call
1976 // promoted it, then it is canceled to prevent it from being propagated.
1977 // Note that this will not cancel termination exceptions.
1978 isolate_->CancelScheduledExceptionFromTryCatch(this);
1979 }
1980 ResetInternal();
1981}
1982
1983
1984void v8::TryCatch::ResetInternal() {
1985 i::Object* the_hole = isolate_->heap()->the_hole_value();
1986 exception_ = the_hole;
1987 message_obj_ = the_hole;
1988 message_script_ = the_hole;
1989 message_start_pos_ = 0;
1990 message_end_pos_ = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00001991}
1992
1993
1994void v8::TryCatch::SetVerbose(bool value) {
1995 is_verbose_ = value;
1996}
1997
1998
1999void v8::TryCatch::SetCaptureMessage(bool value) {
2000 capture_message_ = value;
2001}
2002
2003
2004// --- M e s s a g e ---
2005
2006
2007Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002008 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2009 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
2010 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002011 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00002012 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002013 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00002014 Local<String> result = Utils::ToLocal(raw_result);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002015 return scope.Escape(result);
2016}
2017
2018
2019ScriptOrigin Message::GetScriptOrigin() const {
2020 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2021 i::Handle<i::JSMessageObject> message =
2022 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2023 i::Handle<i::Object> script_wraper =
2024 i::Handle<i::Object>(message->script(), isolate);
2025 i::Handle<i::JSValue> script_value =
2026 i::Handle<i::JSValue>::cast(script_wraper);
2027 i::Handle<i::Script> script(i::Script::cast(script_value->value()));
2028 i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
2029 v8::Isolate* v8_isolate =
2030 reinterpret_cast<v8::Isolate*>(script->GetIsolate());
2031 v8::ScriptOrigin origin(
2032 Utils::ToLocal(scriptName),
2033 v8::Integer::New(v8_isolate, script->line_offset()->value()),
2034 v8::Integer::New(v8_isolate, script->column_offset()->value()),
2035 Handle<Boolean>(),
2036 v8::Integer::New(v8_isolate, script->id()->value()));
2037 return origin;
Steve Blocka7e24c12009-10-30 11:49:00 +00002038}
2039
2040
2041v8::Handle<Value> Message::GetScriptResourceName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002042 return GetScriptOrigin().ResourceName();
Steve Blocka7e24c12009-10-30 11:49:00 +00002043}
2044
2045
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002046v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002047 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002048 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002049 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Block1e0659c2011-05-24 12:43:12 +01002050 i::Handle<i::JSMessageObject> message =
2051 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002052 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002053 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
2054 i::Handle<i::JSArray> stackTrace =
2055 i::Handle<i::JSArray>::cast(stackFramesObj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002056 return scope.Escape(Utils::StackTraceToLocal(stackTrace));
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002057}
2058
2059
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002060MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002061 i::Isolate* isolate, const char* name, i::Handle<i::Object> recv, int argc,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002062 i::Handle<i::Object> argv[]) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002063 i::Handle<i::Object> object_fun =
2064 i::Object::GetProperty(
2065 isolate, isolate->js_builtins_object(), name).ToHandleChecked();
2066 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(object_fun);
2067 return i::Execution::Call(isolate, fun, recv, argc, argv);
Steve Blocka7e24c12009-10-30 11:49:00 +00002068}
2069
2070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002071MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002072 i::Isolate* isolate, const char* name, i::Handle<i::Object> data) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002073 i::Handle<i::Object> argv[] = { data };
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002074 return CallV8HeapFunction(isolate, name, isolate->js_builtins_object(),
2075 arraysize(argv), argv);
Steve Blocka7e24c12009-10-30 11:49:00 +00002076}
2077
2078
2079int Message::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002080 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2081 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
2082 ENTER_V8(isolate);
2083 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01002084
Steve Block44f0eee2011-05-26 01:26:41 +01002085 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002086 i::Handle<i::Object> result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002087 has_pending_exception =
2088 !CallV8HeapFunction(isolate, "GetLineNumber", Utils::OpenHandle(this))
2089 .ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01002090 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002091 return static_cast<int>(result->Number());
2092}
2093
2094
2095int Message::GetStartPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002096 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002097 ENTER_V8(isolate);
2098 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01002099 i::Handle<i::JSMessageObject> message =
2100 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2101 return message->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002102}
2103
2104
2105int Message::GetEndPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002106 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002107 ENTER_V8(isolate);
2108 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01002109 i::Handle<i::JSMessageObject> message =
2110 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2111 return message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002112}
2113
2114
2115int Message::GetStartColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002116 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002117 ON_BAILOUT(isolate, "v8::Message::GetStartColumn()", return kNoColumnInfo);
Steve Block44f0eee2011-05-26 01:26:41 +01002118 ENTER_V8(isolate);
2119 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002120 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002121 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002122 i::Handle<i::Object> start_col_obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002123 has_pending_exception =
2124 !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
2125 .ToHandle(&start_col_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002126 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002127 return static_cast<int>(start_col_obj->Number());
2128}
2129
2130
2131int Message::GetEndColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002132 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002133 ON_BAILOUT(isolate, "v8::Message::GetEndColumn()", return kNoColumnInfo);
Steve Block44f0eee2011-05-26 01:26:41 +01002134 ENTER_V8(isolate);
2135 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002136 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002137 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002138 i::Handle<i::Object> start_col_obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002139 has_pending_exception =
2140 !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
2141 .ToHandle(&start_col_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002142 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Block1e0659c2011-05-24 12:43:12 +01002143 i::Handle<i::JSMessageObject> message =
2144 i::Handle<i::JSMessageObject>::cast(data_obj);
2145 int start = message->start_position();
2146 int end = message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002147 return static_cast<int>(start_col_obj->Number()) + (end - start);
2148}
2149
2150
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002151bool Message::IsSharedCrossOrigin() const {
2152 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2153 ENTER_V8(isolate);
2154 i::HandleScope scope(isolate);
2155 i::Handle<i::JSMessageObject> message =
2156 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2157 i::Handle<i::JSValue> script =
2158 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2159 isolate));
2160 return i::Script::cast(script->value())->is_shared_cross_origin();
2161}
2162
2163
Steve Blocka7e24c12009-10-30 11:49:00 +00002164Local<String> Message::GetSourceLine() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002165 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2166 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
2167 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002168 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Block44f0eee2011-05-26 01:26:41 +01002169 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002170 i::Handle<i::Object> result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002171 has_pending_exception =
2172 !CallV8HeapFunction(isolate, "GetSourceLine", Utils::OpenHandle(this))
2173 .ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01002174 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002175 if (result->IsString()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002176 return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
Steve Blocka7e24c12009-10-30 11:49:00 +00002177 } else {
2178 return Local<String>();
2179 }
2180}
2181
2182
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002183void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
2184 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2185 ENTER_V8(i_isolate);
2186 i_isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00002187}
2188
2189
Kristian Monsen25f61362010-05-21 11:50:48 +01002190// --- S t a c k T r a c e ---
2191
2192Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002193 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002194 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002195 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Kristian Monsen25f61362010-05-21 11:50:48 +01002196 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002197 i::Handle<i::Object> obj =
2198 i::Object::GetElement(isolate, self, index).ToHandleChecked();
2199 i::Handle<i::JSObject> jsobj = i::Handle<i::JSObject>::cast(obj);
2200 return scope.Escape(Utils::StackFrameToLocal(jsobj));
Kristian Monsen25f61362010-05-21 11:50:48 +01002201}
2202
2203
2204int StackTrace::GetFrameCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002205 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002206 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002207 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2208}
2209
2210
2211Local<Array> StackTrace::AsArray() {
Steve Block44f0eee2011-05-26 01:26:41 +01002212 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002213 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002214 return Utils::ToLocal(Utils::OpenHandle(this));
2215}
2216
2217
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002218Local<StackTrace> StackTrace::CurrentStackTrace(
2219 Isolate* isolate,
2220 int frame_limit,
Kristian Monsen25f61362010-05-21 11:50:48 +01002221 StackTraceOptions options) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002222 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2223 ENTER_V8(i_isolate);
2224 // TODO(dcarney): remove when ScriptDebugServer is fixed.
2225 options = static_cast<StackTraceOptions>(
2226 static_cast<int>(options) | kExposeFramesAcrossSecurityOrigins);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002227 i::Handle<i::JSArray> stackTrace =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002228 i_isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002229 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01002230}
2231
2232
2233// --- S t a c k F r a m e ---
2234
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002235static int getIntProperty(const StackFrame* f, const char* propertyName,
2236 int defaultValue) {
2237 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002238 ENTER_V8(isolate);
2239 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002240 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2241 i::Handle<i::Object> obj =
2242 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2243 return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue;
2244}
2245
2246
2247int StackFrame::GetLineNumber() const {
2248 return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo);
Kristian Monsen25f61362010-05-21 11:50:48 +01002249}
2250
2251
2252int StackFrame::GetColumn() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002253 return getIntProperty(this, "column", Message::kNoColumnInfo);
2254}
2255
2256
2257int StackFrame::GetScriptId() const {
2258 return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo);
2259}
2260
2261
2262static Local<String> getStringProperty(const StackFrame* f,
2263 const char* propertyName) {
2264 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002265 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002266 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2267 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2268 i::Handle<i::Object> obj =
2269 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2270 return obj->IsString()
2271 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
2272 : Local<String>();
Kristian Monsen25f61362010-05-21 11:50:48 +01002273}
2274
2275
2276Local<String> StackFrame::GetScriptName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002277 return getStringProperty(this, "scriptName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002278}
2279
2280
Ben Murdochf87a2032010-10-22 12:50:53 +01002281Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002282 return getStringProperty(this, "scriptNameOrSourceURL");
Ben Murdochf87a2032010-10-22 12:50:53 +01002283}
2284
2285
Kristian Monsen25f61362010-05-21 11:50:48 +01002286Local<String> StackFrame::GetFunctionName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002287 return getStringProperty(this, "functionName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002288}
2289
2290
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002291static bool getBoolProperty(const StackFrame* f, const char* propertyName) {
2292 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002293 ENTER_V8(isolate);
2294 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002295 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2296 i::Handle<i::Object> obj =
2297 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2298 return obj->IsTrue();
Kristian Monsen25f61362010-05-21 11:50:48 +01002299}
2300
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002301bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
2302
Kristian Monsen25f61362010-05-21 11:50:48 +01002303
2304bool StackFrame::IsConstructor() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002305 return getBoolProperty(this, "isConstructor");
2306}
2307
2308
2309// --- J S O N ---
2310
2311Local<Value> JSON::Parse(Local<String> json_string) {
2312 i::Handle<i::String> string = Utils::OpenHandle(*json_string);
2313 i::Isolate* isolate = string->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002314 ENTER_V8(isolate);
2315 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002316 i::Handle<i::String> source = i::String::Flatten(string);
2317 EXCEPTION_PREAMBLE(isolate);
2318 i::MaybeHandle<i::Object> maybe_result =
2319 source->IsSeqOneByteString() ? i::JsonParser<true>::Parse(source)
2320 : i::JsonParser<false>::Parse(source);
2321 i::Handle<i::Object> result;
2322 has_pending_exception = !maybe_result.ToHandle(&result);
2323 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
2324 return Utils::ToLocal(
2325 i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
Kristian Monsen25f61362010-05-21 11:50:48 +01002326}
2327
2328
Steve Blocka7e24c12009-10-30 11:49:00 +00002329// --- D a t a ---
2330
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002331bool Value::FullIsUndefined() const {
2332 bool result = Utils::OpenHandle(this)->IsUndefined();
2333 DCHECK_EQ(result, QuickIsUndefined());
2334 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002335}
2336
2337
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002338bool Value::FullIsNull() const {
2339 bool result = Utils::OpenHandle(this)->IsNull();
2340 DCHECK_EQ(result, QuickIsNull());
2341 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002342}
2343
2344
2345bool Value::IsTrue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002346 return Utils::OpenHandle(this)->IsTrue();
2347}
2348
2349
2350bool Value::IsFalse() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002351 return Utils::OpenHandle(this)->IsFalse();
2352}
2353
2354
2355bool Value::IsFunction() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002356 return Utils::OpenHandle(this)->IsJSFunction();
2357}
2358
2359
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002360bool Value::IsName() const {
2361 return Utils::OpenHandle(this)->IsName();
2362}
2363
2364
Steve Blocka7e24c12009-10-30 11:49:00 +00002365bool Value::FullIsString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002366 bool result = Utils::OpenHandle(this)->IsString();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002367 DCHECK_EQ(result, QuickIsString());
Steve Blocka7e24c12009-10-30 11:49:00 +00002368 return result;
2369}
2370
2371
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002372bool Value::IsSymbol() const {
2373 return Utils::OpenHandle(this)->IsSymbol();
2374}
2375
2376
Steve Blocka7e24c12009-10-30 11:49:00 +00002377bool Value::IsArray() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002378 return Utils::OpenHandle(this)->IsJSArray();
2379}
2380
2381
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002382bool Value::IsArrayBuffer() const {
2383 return Utils::OpenHandle(this)->IsJSArrayBuffer();
2384}
2385
2386
2387bool Value::IsArrayBufferView() const {
2388 return Utils::OpenHandle(this)->IsJSArrayBufferView();
2389}
2390
2391
2392bool Value::IsTypedArray() const {
2393 return Utils::OpenHandle(this)->IsJSTypedArray();
2394}
2395
2396
2397#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
2398 bool Value::Is##Type##Array() const { \
2399 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2400 return obj->IsJSTypedArray() && \
2401 i::JSTypedArray::cast(*obj)->type() == kExternal##Type##Array; \
2402 }
2403
2404TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
2405
2406#undef VALUE_IS_TYPED_ARRAY
2407
2408
2409bool Value::IsDataView() const {
2410 return Utils::OpenHandle(this)->IsJSDataView();
2411}
2412
2413
Steve Blocka7e24c12009-10-30 11:49:00 +00002414bool Value::IsObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002415 return Utils::OpenHandle(this)->IsJSObject();
2416}
2417
2418
2419bool Value::IsNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002420 return Utils::OpenHandle(this)->IsNumber();
2421}
2422
2423
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002424#define VALUE_IS_SPECIFIC_TYPE(Type, Class) \
2425 bool Value::Is##Type() const { \
2426 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2427 if (!obj->IsHeapObject()) return false; \
2428 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); \
2429 return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
Steve Block44f0eee2011-05-26 01:26:41 +01002430 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002431
2432VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
2433VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
2434VALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
2435VALUE_IS_SPECIFIC_TYPE(StringObject, String)
2436VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
2437VALUE_IS_SPECIFIC_TYPE(Date, Date)
2438VALUE_IS_SPECIFIC_TYPE(Map, Map)
2439VALUE_IS_SPECIFIC_TYPE(Set, Set)
2440VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
2441VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
2442
2443#undef VALUE_IS_SPECIFIC_TYPE
2444
2445
2446bool Value::IsBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002447 return Utils::OpenHandle(this)->IsBoolean();
2448}
2449
2450
2451bool Value::IsExternal() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002452 return Utils::OpenHandle(this)->IsExternal();
Steve Blocka7e24c12009-10-30 11:49:00 +00002453}
2454
2455
2456bool Value::IsInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002457 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2458 if (obj->IsSmi()) return true;
2459 if (obj->IsNumber()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002460 return i::IsInt32Double(obj->Number());
Steve Blocka7e24c12009-10-30 11:49:00 +00002461 }
2462 return false;
2463}
2464
2465
Steve Block6ded16b2010-05-10 14:33:55 +01002466bool Value::IsUint32() const {
Steve Block6ded16b2010-05-10 14:33:55 +01002467 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2468 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2469 if (obj->IsNumber()) {
2470 double value = obj->Number();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002471 return !i::IsMinusZero(value) &&
2472 value >= 0 &&
2473 value <= i::kMaxUInt32 &&
2474 value == i::FastUI2D(i::FastD2UI(value));
Steve Block6ded16b2010-05-10 14:33:55 +01002475 }
2476 return false;
2477}
2478
2479
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002480static bool CheckConstructor(i::Isolate* isolate,
2481 i::Handle<i::JSObject> obj,
2482 const char* class_name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002483 i::Handle<i::Object> constr(obj->map()->constructor(), isolate);
2484 if (!constr->IsJSFunction()) return false;
2485 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(constr);
2486 return func->shared()->native() && constr.is_identical_to(
2487 i::Object::GetProperty(isolate,
2488 isolate->js_builtins_object(),
2489 class_name).ToHandleChecked());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002490}
2491
2492
2493bool Value::IsNativeError() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002494 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2495 if (obj->IsJSObject()) {
2496 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002497 i::Isolate* isolate = js_obj->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002498 return CheckConstructor(isolate, js_obj, "$Error") ||
2499 CheckConstructor(isolate, js_obj, "$EvalError") ||
2500 CheckConstructor(isolate, js_obj, "$RangeError") ||
2501 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2502 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2503 CheckConstructor(isolate, js_obj, "$TypeError") ||
2504 CheckConstructor(isolate, js_obj, "$URIError");
2505 } else {
2506 return false;
2507 }
2508}
2509
2510
Iain Merrick75681382010-08-19 15:07:18 +01002511bool Value::IsRegExp() const {
Iain Merrick75681382010-08-19 15:07:18 +01002512 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2513 return obj->IsJSRegExp();
2514}
2515
2516
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002517bool Value::IsGeneratorFunction() const {
2518 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2519 if (!obj->IsJSFunction()) return false;
2520 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
2521 return func->shared()->is_generator();
2522}
2523
2524
2525bool Value::IsGeneratorObject() const {
2526 return Utils::OpenHandle(this)->IsJSGeneratorObject();
2527}
2528
2529
2530bool Value::IsMapIterator() const {
2531 return Utils::OpenHandle(this)->IsJSMapIterator();
2532}
2533
2534
2535bool Value::IsSetIterator() const {
2536 return Utils::OpenHandle(this)->IsJSSetIterator();
2537}
2538
2539
2540Local<String> Value::ToString(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002541 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2542 i::Handle<i::Object> str;
2543 if (obj->IsString()) {
2544 str = obj;
2545 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002546 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002547 LOG_API(isolate, "ToString");
2548 ENTER_V8(isolate);
2549 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002550 has_pending_exception = !i::Execution::ToString(
2551 isolate, obj).ToHandle(&str);
Steve Block44f0eee2011-05-26 01:26:41 +01002552 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002553 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002554 return ToApiHandle<String>(str);
Steve Blocka7e24c12009-10-30 11:49:00 +00002555}
2556
2557
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002558Local<String> Value::ToDetailString(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002559 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2560 i::Handle<i::Object> str;
2561 if (obj->IsString()) {
2562 str = obj;
2563 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002564 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002565 LOG_API(isolate, "ToDetailString");
2566 ENTER_V8(isolate);
2567 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002568 has_pending_exception = !i::Execution::ToDetailString(
2569 isolate, obj).ToHandle(&str);
Steve Block44f0eee2011-05-26 01:26:41 +01002570 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002571 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002572 return ToApiHandle<String>(str);
Steve Blocka7e24c12009-10-30 11:49:00 +00002573}
2574
2575
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002576Local<v8::Object> Value::ToObject(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002577 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2578 i::Handle<i::Object> val;
2579 if (obj->IsJSObject()) {
2580 val = obj;
2581 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002582 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002583 LOG_API(isolate, "ToObject");
2584 ENTER_V8(isolate);
2585 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002586 has_pending_exception = !i::Execution::ToObject(
2587 isolate, obj).ToHandle(&val);
Steve Block44f0eee2011-05-26 01:26:41 +01002588 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002589 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002590 return ToApiHandle<Object>(val);
Steve Blocka7e24c12009-10-30 11:49:00 +00002591}
2592
2593
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002594Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002595 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2596 if (obj->IsBoolean()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002597 return ToApiHandle<Boolean>(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00002598 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002599 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002600 LOG_API(isolate, "ToBoolean");
2601 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002602 i::Handle<i::Object> val =
2603 isolate->factory()->ToBoolean(obj->BooleanValue());
2604 return ToApiHandle<Boolean>(val);
Steve Blocka7e24c12009-10-30 11:49:00 +00002605 }
2606}
2607
2608
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002609Local<Number> Value::ToNumber(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002610 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2611 i::Handle<i::Object> num;
2612 if (obj->IsNumber()) {
2613 num = obj;
2614 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002615 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002616 LOG_API(isolate, "ToNumber");
2617 ENTER_V8(isolate);
2618 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002619 has_pending_exception = !i::Execution::ToNumber(
2620 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002621 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002622 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002623 return ToApiHandle<Number>(num);
Steve Blocka7e24c12009-10-30 11:49:00 +00002624}
2625
2626
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002627Local<Integer> Value::ToInteger(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002628 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2629 i::Handle<i::Object> num;
2630 if (obj->IsSmi()) {
2631 num = obj;
2632 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002633 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002634 LOG_API(isolate, "ToInteger");
2635 ENTER_V8(isolate);
2636 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002637 has_pending_exception = !i::Execution::ToInteger(
2638 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002639 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002640 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002641 return ToApiHandle<Integer>(num);
2642}
2643
2644
2645void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
2646 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
2647 Utils::ApiCheck(isolate != NULL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002648 !isolate->IsDead(),
2649 "v8::internal::Internals::CheckInitialized()",
2650 "Isolate is not initialized or V8 has died");
Steve Blocka7e24c12009-10-30 11:49:00 +00002651}
2652
2653
2654void External::CheckCast(v8::Value* that) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002655 Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(),
2656 "v8::External::Cast()",
2657 "Could not convert to external");
Steve Blocka7e24c12009-10-30 11:49:00 +00002658}
2659
2660
2661void v8::Object::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002662 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002663 Utils::ApiCheck(obj->IsJSObject(),
2664 "v8::Object::Cast()",
2665 "Could not convert to object");
Steve Blocka7e24c12009-10-30 11:49:00 +00002666}
2667
2668
2669void v8::Function::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002670 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002671 Utils::ApiCheck(obj->IsJSFunction(),
2672 "v8::Function::Cast()",
2673 "Could not convert to function");
2674}
2675
2676
2677void v8::Name::CheckCast(v8::Value* that) {
2678 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2679 Utils::ApiCheck(obj->IsName(),
2680 "v8::Name::Cast()",
2681 "Could not convert to name");
Steve Blocka7e24c12009-10-30 11:49:00 +00002682}
2683
2684
2685void v8::String::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002686 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002687 Utils::ApiCheck(obj->IsString(),
2688 "v8::String::Cast()",
2689 "Could not convert to string");
2690}
2691
2692
2693void v8::Symbol::CheckCast(v8::Value* that) {
2694 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2695 Utils::ApiCheck(obj->IsSymbol(),
2696 "v8::Symbol::Cast()",
2697 "Could not convert to symbol");
Steve Blocka7e24c12009-10-30 11:49:00 +00002698}
2699
2700
2701void v8::Number::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002702 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002703 Utils::ApiCheck(obj->IsNumber(),
2704 "v8::Number::Cast()",
2705 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00002706}
2707
2708
2709void v8::Integer::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002710 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002711 Utils::ApiCheck(obj->IsNumber(),
2712 "v8::Integer::Cast()",
2713 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00002714}
2715
2716
2717void v8::Array::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002718 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002719 Utils::ApiCheck(obj->IsJSArray(),
2720 "v8::Array::Cast()",
2721 "Could not convert to array");
2722}
2723
2724
2725void v8::Promise::CheckCast(Value* that) {
2726 Utils::ApiCheck(that->IsPromise(),
2727 "v8::Promise::Cast()",
2728 "Could not convert to promise");
2729}
2730
2731
2732void v8::Promise::Resolver::CheckCast(Value* that) {
2733 Utils::ApiCheck(that->IsPromise(),
2734 "v8::Promise::Resolver::Cast()",
2735 "Could not convert to promise resolver");
2736}
2737
2738
2739void v8::ArrayBuffer::CheckCast(Value* that) {
2740 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2741 Utils::ApiCheck(obj->IsJSArrayBuffer(),
2742 "v8::ArrayBuffer::Cast()",
2743 "Could not convert to ArrayBuffer");
2744}
2745
2746
2747void v8::ArrayBufferView::CheckCast(Value* that) {
2748 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2749 Utils::ApiCheck(obj->IsJSArrayBufferView(),
2750 "v8::ArrayBufferView::Cast()",
2751 "Could not convert to ArrayBufferView");
2752}
2753
2754
2755void v8::TypedArray::CheckCast(Value* that) {
2756 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2757 Utils::ApiCheck(obj->IsJSTypedArray(),
2758 "v8::TypedArray::Cast()",
2759 "Could not convert to TypedArray");
2760}
2761
2762
2763#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \
2764 void v8::Type##Array::CheckCast(Value* that) { \
2765 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
2766 Utils::ApiCheck(obj->IsJSTypedArray() && \
2767 i::JSTypedArray::cast(*obj)->type() == \
2768 kExternal##Type##Array, \
2769 "v8::" #Type "Array::Cast()", \
2770 "Could not convert to " #Type "Array"); \
2771 }
2772
2773
2774TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
2775
2776#undef CHECK_TYPED_ARRAY_CAST
2777
2778
2779void v8::DataView::CheckCast(Value* that) {
2780 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2781 Utils::ApiCheck(obj->IsJSDataView(),
2782 "v8::DataView::Cast()",
2783 "Could not convert to DataView");
Steve Blocka7e24c12009-10-30 11:49:00 +00002784}
2785
2786
2787void v8::Date::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002788 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002789 i::Isolate* isolate = NULL;
2790 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2791 Utils::ApiCheck(isolate != NULL &&
2792 obj->HasSpecificClassOf(isolate->heap()->Date_string()),
2793 "v8::Date::Cast()",
2794 "Could not convert to date");
Steve Blocka7e24c12009-10-30 11:49:00 +00002795}
2796
2797
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002798void v8::StringObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002799 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002800 i::Isolate* isolate = NULL;
2801 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2802 Utils::ApiCheck(isolate != NULL &&
2803 obj->HasSpecificClassOf(isolate->heap()->String_string()),
2804 "v8::StringObject::Cast()",
2805 "Could not convert to StringObject");
2806}
2807
2808
2809void v8::SymbolObject::CheckCast(v8::Value* that) {
2810 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2811 i::Isolate* isolate = NULL;
2812 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2813 Utils::ApiCheck(isolate != NULL &&
2814 obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
2815 "v8::SymbolObject::Cast()",
2816 "Could not convert to SymbolObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002817}
2818
2819
2820void v8::NumberObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002821 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002822 i::Isolate* isolate = NULL;
2823 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2824 Utils::ApiCheck(isolate != NULL &&
2825 obj->HasSpecificClassOf(isolate->heap()->Number_string()),
2826 "v8::NumberObject::Cast()",
2827 "Could not convert to NumberObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002828}
2829
2830
2831void v8::BooleanObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002832 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002833 i::Isolate* isolate = NULL;
2834 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2835 Utils::ApiCheck(isolate != NULL &&
2836 obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
2837 "v8::BooleanObject::Cast()",
2838 "Could not convert to BooleanObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002839}
2840
2841
Ben Murdochf87a2032010-10-22 12:50:53 +01002842void v8::RegExp::CheckCast(v8::Value* that) {
Ben Murdochf87a2032010-10-22 12:50:53 +01002843 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002844 Utils::ApiCheck(obj->IsJSRegExp(),
2845 "v8::RegExp::Cast()",
2846 "Could not convert to regular expression");
Ben Murdochf87a2032010-10-22 12:50:53 +01002847}
2848
2849
Steve Blocka7e24c12009-10-30 11:49:00 +00002850bool Value::BooleanValue() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002851 return Utils::OpenHandle(this)->BooleanValue();
Steve Blocka7e24c12009-10-30 11:49:00 +00002852}
2853
2854
2855double Value::NumberValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002856 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2857 i::Handle<i::Object> num;
2858 if (obj->IsNumber()) {
2859 num = obj;
2860 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002861 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002862 LOG_API(isolate, "NumberValue");
2863 ENTER_V8(isolate);
2864 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002865 has_pending_exception = !i::Execution::ToNumber(
2866 isolate, obj).ToHandle(&num);
2867 EXCEPTION_BAILOUT_CHECK(isolate, base::OS::nan_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002868 }
2869 return num->Number();
2870}
2871
2872
2873int64_t Value::IntegerValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002874 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2875 i::Handle<i::Object> num;
2876 if (obj->IsNumber()) {
2877 num = obj;
2878 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002879 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002880 LOG_API(isolate, "IntegerValue");
2881 ENTER_V8(isolate);
2882 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002883 has_pending_exception = !i::Execution::ToInteger(
2884 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002885 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002886 }
2887 if (num->IsSmi()) {
2888 return i::Smi::cast(*num)->value();
2889 } else {
2890 return static_cast<int64_t>(num->Number());
2891 }
2892}
2893
2894
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002895Local<Int32> Value::ToInt32(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002896 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2897 i::Handle<i::Object> num;
2898 if (obj->IsSmi()) {
2899 num = obj;
2900 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002901 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002902 LOG_API(isolate, "ToInt32");
2903 ENTER_V8(isolate);
2904 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002905 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002906 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002907 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002908 return ToApiHandle<Int32>(num);
Steve Blocka7e24c12009-10-30 11:49:00 +00002909}
2910
2911
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002912Local<Uint32> Value::ToUint32(Isolate* v8_isolate) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002913 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2914 i::Handle<i::Object> num;
2915 if (obj->IsSmi()) {
2916 num = obj;
2917 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002918 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01002919 LOG_API(isolate, "ToUInt32");
2920 ENTER_V8(isolate);
2921 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002922 has_pending_exception = !i::Execution::ToUint32(
2923 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002924 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002925 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002926 return ToApiHandle<Uint32>(num);
Steve Blocka7e24c12009-10-30 11:49:00 +00002927}
2928
2929
2930Local<Uint32> Value::ToArrayIndex() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002931 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2932 if (obj->IsSmi()) {
2933 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2934 return Local<Uint32>();
2935 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002936 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002937 LOG_API(isolate, "ToArrayIndex");
2938 ENTER_V8(isolate);
2939 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002940 i::Handle<i::Object> string_obj;
2941 has_pending_exception = !i::Execution::ToString(
2942 isolate, obj).ToHandle(&string_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002943 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002944 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2945 uint32_t index;
2946 if (str->AsArrayIndex(&index)) {
2947 i::Handle<i::Object> value;
2948 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002949 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002950 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002951 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002952 }
2953 return Utils::Uint32ToLocal(value);
2954 }
2955 return Local<Uint32>();
2956}
2957
2958
2959int32_t Value::Int32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002960 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2961 if (obj->IsSmi()) {
2962 return i::Smi::cast(*obj)->value();
2963 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002964 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002965 LOG_API(isolate, "Int32Value (slow)");
2966 ENTER_V8(isolate);
2967 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002968 i::Handle<i::Object> num;
2969 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002970 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002971 if (num->IsSmi()) {
2972 return i::Smi::cast(*num)->value();
2973 } else {
2974 return static_cast<int32_t>(num->Number());
2975 }
2976 }
2977}
2978
2979
2980bool Value::Equals(Handle<Value> that) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002981 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002982 i::Handle<i::Object> other = Utils::OpenHandle(*that);
2983 if (obj->IsSmi() && other->IsSmi()) {
2984 return obj->Number() == other->Number();
2985 }
2986 i::Object* ho = obj->IsSmi() ? *other : *obj;
2987 i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002988 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
2989 "v8::Value::Equals()",
2990 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002991 return false;
2992 }
Steve Block44f0eee2011-05-26 01:26:41 +01002993 LOG_API(isolate, "Equals");
2994 ENTER_V8(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01002995 // If both obj and other are JSObjects, we'd better compare by identity
2996 // immediately when going into JS builtin. The reason is Invoke
2997 // would overwrite global object receiver with global proxy.
2998 if (obj->IsJSObject() && other->IsJSObject()) {
2999 return *obj == *other;
3000 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003001 i::Handle<i::Object> args[] = { other };
Steve Block44f0eee2011-05-26 01:26:41 +01003002 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003003 i::Handle<i::Object> result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003004 has_pending_exception =
3005 !CallV8HeapFunction(isolate, "EQUALS", obj, arraysize(args), args)
3006 .ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01003007 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003008 return *result == i::Smi::FromInt(i::EQUAL);
3009}
3010
3011
3012bool Value::StrictEquals(Handle<Value> that) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003013 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003014 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3015 if (obj->IsSmi()) {
3016 return other->IsNumber() && obj->Number() == other->Number();
3017 }
3018 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003019 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3020 "v8::Value::StrictEquals()",
3021 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003022 return false;
3023 }
Steve Block44f0eee2011-05-26 01:26:41 +01003024 LOG_API(isolate, "StrictEquals");
Steve Blocka7e24c12009-10-30 11:49:00 +00003025 // Must check HeapNumber first, since NaN !== NaN.
3026 if (obj->IsHeapNumber()) {
3027 if (!other->IsNumber()) return false;
3028 double x = obj->Number();
3029 double y = other->Number();
3030 // Must check explicitly for NaN:s on Windows, but -0 works fine.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003031 return x == y && !std::isnan(x) && !std::isnan(y);
Steve Blocka7e24c12009-10-30 11:49:00 +00003032 } else if (*obj == *other) { // Also covers Booleans.
3033 return true;
3034 } else if (obj->IsSmi()) {
3035 return other->IsNumber() && obj->Number() == other->Number();
3036 } else if (obj->IsString()) {
3037 return other->IsString() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003038 i::String::Equals(i::Handle<i::String>::cast(obj),
3039 i::Handle<i::String>::cast(other));
Steve Blocka7e24c12009-10-30 11:49:00 +00003040 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
3041 return other->IsUndefined() || other->IsUndetectableObject();
3042 } else {
3043 return false;
3044 }
3045}
3046
3047
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003048bool Value::SameValue(Handle<Value> that) const {
3049 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
3050 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3051 "v8::Value::SameValue()",
3052 "Reading from empty handle")) {
3053 return false;
3054 }
3055 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3056 return obj->SameValue(*other);
3057}
3058
3059
Steve Blocka7e24c12009-10-30 11:49:00 +00003060uint32_t Value::Uint32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003061 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3062 if (obj->IsSmi()) {
3063 return i::Smi::cast(*obj)->value();
3064 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003065 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01003066 LOG_API(isolate, "Uint32Value");
3067 ENTER_V8(isolate);
3068 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003069 i::Handle<i::Object> num;
3070 has_pending_exception = !i::Execution::ToUint32(
3071 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01003072 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00003073 if (num->IsSmi()) {
3074 return i::Smi::cast(*num)->value();
3075 } else {
3076 return static_cast<uint32_t>(num->Number());
3077 }
3078 }
3079}
3080
3081
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003082bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003083 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3084 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
3085 ENTER_V8(isolate);
3086 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003087 i::Handle<i::Object> self = Utils::OpenHandle(this);
3088 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3089 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003090 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003091 has_pending_exception =
3092 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
3093 i::SLOPPY).is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003094 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003095 return true;
3096}
3097
3098
Steve Block6ded16b2010-05-10 14:33:55 +01003099bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003100 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3101 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
3102 ENTER_V8(isolate);
3103 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01003104 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3105 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003106 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003107 has_pending_exception = i::JSObject::SetElement(
3108 self, index, value_obj, NONE, i::SLOPPY).is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003109 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Block6ded16b2010-05-10 14:33:55 +01003110 return true;
3111}
3112
3113
Steve Blocka7e24c12009-10-30 11:49:00 +00003114bool v8::Object::ForceSet(v8::Handle<Value> key,
3115 v8::Handle<Value> value,
3116 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01003117 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3118 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
3119 ENTER_V8(isolate);
3120 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003121 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3122 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3123 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003124 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003125 has_pending_exception = i::Runtime::DefineObjectProperty(
Steve Blocka7e24c12009-10-30 11:49:00 +00003126 self,
3127 key_obj,
3128 value_obj,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003129 static_cast<PropertyAttributes>(attribs)).is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003130 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003131 return true;
3132}
3133
3134
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003135bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
3136 return ForceSet(v8::Handle<Value>(reinterpret_cast<Value*>(*key)),
3137 value, DontEnum);
3138}
3139
3140
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003141i::MaybeHandle<i::Object> DeleteObjectProperty(
3142 i::Isolate* isolate, i::Handle<i::JSReceiver> receiver,
3143 i::Handle<i::Object> key, i::JSReceiver::DeleteMode mode) {
3144 // Check if the given key is an array index.
3145 uint32_t index;
3146 if (key->ToArrayIndex(&index)) {
3147 // In Firefox/SpiderMonkey, Safari and Opera you can access the
3148 // characters of a string using [] notation. In the case of a
3149 // String object we just need to redirect the deletion to the
3150 // underlying string if the index is in range. Since the
3151 // underlying string does nothing with the deletion, we can ignore
3152 // such deletions.
3153 if (receiver->IsStringObjectWithCharacterAt(index)) {
3154 return isolate->factory()->true_value();
3155 }
3156
3157 return i::JSReceiver::DeleteElement(receiver, index, mode);
3158 }
3159
3160 i::Handle<i::Name> name;
3161 if (key->IsName()) {
3162 name = i::Handle<i::Name>::cast(key);
3163 } else {
3164 // Call-back into JavaScript to convert the key to a string.
3165 i::Handle<i::Object> converted;
3166 if (!i::Execution::ToString(isolate, key).ToHandle(&converted)) {
3167 return i::MaybeHandle<i::Object>();
3168 }
3169 name = i::Handle<i::String>::cast(converted);
3170 }
3171
3172 if (name->IsString()) {
3173 name = i::String::Flatten(i::Handle<i::String>::cast(name));
3174 }
3175 return i::JSReceiver::DeleteProperty(receiver, name, mode);
3176}
3177
3178
Steve Blocka7e24c12009-10-30 11:49:00 +00003179bool v8::Object::ForceDelete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003180 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3181 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
3182 ENTER_V8(isolate);
3183 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003184 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3185 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003186
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003187 // When deleting a property on the global object using ForceDelete
3188 // deoptimize all functions as optimized code does not check for the hole
3189 // value with DontDelete properties. We have to deoptimize all contexts
3190 // because of possible cross-context inlined functions.
3191 if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
3192 i::Deoptimizer::DeoptimizeAll(isolate);
3193 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003194
Steve Block44f0eee2011-05-26 01:26:41 +01003195 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003196 i::Handle<i::Object> obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003197 has_pending_exception =
3198 !DeleteObjectProperty(isolate, self, key_obj,
3199 i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01003200 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003201 return obj->IsTrue();
3202}
3203
3204
3205Local<Value> v8::Object::Get(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003206 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3207 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
3208 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003209 i::Handle<i::Object> self = Utils::OpenHandle(this);
3210 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01003211 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003212 i::Handle<i::Object> result;
3213 has_pending_exception =
3214 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01003215 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003216 return Utils::ToLocal(result);
3217}
3218
3219
Steve Block6ded16b2010-05-10 14:33:55 +01003220Local<Value> v8::Object::Get(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01003221 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3222 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
3223 ENTER_V8(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01003224 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003225 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003226 i::Handle<i::Object> result;
3227 has_pending_exception =
3228 !i::Object::GetElement(isolate, self, index).ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01003229 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Block6ded16b2010-05-10 14:33:55 +01003230 return Utils::ToLocal(result);
3231}
3232
3233
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003234Local<Value> v8::Object::GetPrivate(v8::Handle<Private> key) {
3235 return Get(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3236}
3237
3238
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003239PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
3240 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003241 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttributes()",
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003242 return static_cast<PropertyAttribute>(NONE));
3243 ENTER_V8(isolate);
3244 i::HandleScope scope(isolate);
3245 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3246 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003247 if (!key_obj->IsName()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003248 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003249 has_pending_exception = !i::Execution::ToString(
3250 isolate, key_obj).ToHandle(&key_obj);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003251 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3252 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003253 i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
3254 EXCEPTION_PREAMBLE(isolate);
3255 Maybe<PropertyAttributes> result =
3256 i::JSReceiver::GetPropertyAttributes(self, key_name);
3257 has_pending_exception = !result.has_value;
3258 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3259 if (result.value == ABSENT) return static_cast<PropertyAttribute>(NONE);
3260 return static_cast<PropertyAttribute>(result.value);
3261}
3262
3263
3264Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) {
3265 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3266 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyDescriptor()",
3267 return Local<Value>());
3268 ENTER_V8(isolate);
3269 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3270 i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
3271 i::Handle<i::Object> args[] = { obj, key_name };
3272 EXCEPTION_PREAMBLE(isolate);
3273 i::Handle<i::Object> result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003274 has_pending_exception =
3275 !CallV8HeapFunction(isolate, "ObjectGetOwnPropertyDescriptor",
3276 isolate->factory()->undefined_value(),
3277 arraysize(args), args).ToHandle(&result);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003278 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3279 return Utils::ToLocal(result);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003280}
3281
3282
Steve Blocka7e24c12009-10-30 11:49:00 +00003283Local<Value> v8::Object::GetPrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01003284 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003285 ON_BAILOUT(isolate, "v8::Object::GetPrototype()", return Local<v8::Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01003286 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003287 i::Handle<i::Object> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003288 i::PrototypeIterator iter(isolate, self);
3289 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
Steve Blocka7e24c12009-10-30 11:49:00 +00003290}
3291
3292
Andrei Popescu402d9372010-02-26 13:31:12 +00003293bool v8::Object::SetPrototype(Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003294 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3295 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
3296 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00003297 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3298 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003299 // We do not allow exceptions thrown while setting the prototype
3300 // to propagate outside.
3301 TryCatch try_catch;
Steve Block44f0eee2011-05-26 01:26:41 +01003302 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003303 i::MaybeHandle<i::Object> result =
3304 i::JSObject::SetPrototype(self, value_obj, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00003305 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003306 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00003307 return true;
3308}
3309
3310
Steve Blocka7e24c12009-10-30 11:49:00 +00003311Local<Object> v8::Object::FindInstanceInPrototypeChain(
3312 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01003313 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3314 ON_BAILOUT(isolate,
3315 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003316 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01003317 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003318 i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this),
3319 i::PrototypeIterator::START_AT_RECEIVER);
Steve Blocka7e24c12009-10-30 11:49:00 +00003320 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003321 while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) {
3322 iter.Advance();
3323 if (iter.IsAtEnd()) {
3324 return Local<Object>();
3325 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003326 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003327 return Utils::ToLocal(
3328 i::handle(i::JSObject::cast(iter.GetCurrent()), isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00003329}
3330
3331
3332Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01003333 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3334 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
3335 return Local<v8::Array>());
3336 ENTER_V8(isolate);
3337 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003338 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003339 EXCEPTION_PREAMBLE(isolate);
3340 i::Handle<i::FixedArray> value;
3341 has_pending_exception = !i::JSReceiver::GetKeys(
3342 self, i::JSReceiver::INCLUDE_PROTOS).ToHandle(&value);
3343 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003344 // Because we use caching to speed up enumeration it is important
3345 // to never change the result of the basic enumeration function so
3346 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01003347 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3348 i::Handle<i::JSArray> result =
3349 isolate->factory()->NewJSArrayWithElements(elms);
3350 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003351}
3352
3353
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003354Local<Array> v8::Object::GetOwnPropertyNames() {
3355 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3356 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
3357 return Local<v8::Array>());
3358 ENTER_V8(isolate);
3359 i::HandleScope scope(isolate);
3360 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003361 EXCEPTION_PREAMBLE(isolate);
3362 i::Handle<i::FixedArray> value;
3363 has_pending_exception = !i::JSReceiver::GetKeys(
3364 self, i::JSReceiver::OWN_ONLY).ToHandle(&value);
3365 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003366 // Because we use caching to speed up enumeration it is important
3367 // to never change the result of the basic enumeration function so
3368 // we clone the result.
3369 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3370 i::Handle<i::JSArray> result =
3371 isolate->factory()->NewJSArrayWithElements(elms);
3372 return Utils::ToLocal(scope.CloseAndEscape(result));
3373}
3374
3375
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003376static bool GetPredefinedToString(i::Handle<i::String> tag,
3377 Local<String>* result) {
3378 i::Isolate* i_isolate = tag->GetIsolate();
3379 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
3380 i::Factory* factory = i_isolate->factory();
3381
3382 if (i::String::Equals(tag, factory->Arguments_string())) {
3383 *result = v8::String::NewFromUtf8(isolate, "[object ~Arguments]");
3384 } else if (i::String::Equals(tag, factory->Array_string())) {
3385 *result = v8::String::NewFromUtf8(isolate, "[object ~Array]");
3386 } else if (i::String::Equals(tag, factory->Boolean_string())) {
3387 *result = v8::String::NewFromUtf8(isolate, "[object ~Boolean]");
3388 } else if (i::String::Equals(tag, factory->Date_string())) {
3389 *result = v8::String::NewFromUtf8(isolate, "[object ~Date]");
3390 } else if (i::String::Equals(tag, factory->Error_string())) {
3391 *result = v8::String::NewFromUtf8(isolate, "[object ~Error]");
3392 } else if (i::String::Equals(tag, factory->Function_string())) {
3393 *result = v8::String::NewFromUtf8(isolate, "[object ~Function]");
3394 } else if (i::String::Equals(tag, factory->Number_string())) {
3395 *result = v8::String::NewFromUtf8(isolate, "[object ~Number]");
3396 } else if (i::String::Equals(tag, factory->RegExp_string())) {
3397 *result = v8::String::NewFromUtf8(isolate, "[object ~RegExp]");
3398 } else if (i::String::Equals(tag, factory->String_string())) {
3399 *result = v8::String::NewFromUtf8(isolate, "[object ~String]");
3400 } else {
3401 return false;
3402 }
3403 return true;
3404}
3405
3406
Steve Blocka7e24c12009-10-30 11:49:00 +00003407Local<String> v8::Object::ObjectProtoToString() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003408 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
3409 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
3410 ON_BAILOUT(i_isolate, "v8::Object::ObjectProtoToString()",
Steve Block44f0eee2011-05-26 01:26:41 +01003411 return Local<v8::String>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003412 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003413 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3414
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003415 i::Handle<i::Object> name(self->class_name(), i_isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003416 i::Handle<i::Object> tag;
Steve Blocka7e24c12009-10-30 11:49:00 +00003417
3418 // Native implementation of Object.prototype.toString (v8natives.js):
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003419 // var c = %_ClassOf(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003420 // if (c === 'Arguments') c = 'Object';
3421 // return "[object " + c + "]";
3422
3423 if (!name->IsString()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003424 return v8::String::NewFromUtf8(isolate, "[object ]");
Steve Blocka7e24c12009-10-30 11:49:00 +00003425 } else {
3426 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003427 if (i::String::Equals(class_name,
3428 i_isolate->factory()->Arguments_string())) {
3429 return v8::String::NewFromUtf8(isolate, "[object Object]");
Steve Blocka7e24c12009-10-30 11:49:00 +00003430 } else {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003431 if (internal::FLAG_harmony_tostring) {
3432 i::Handle<i::Symbol> toStringTag =
3433 Utils::OpenHandle(*Symbol::GetToStringTag(isolate));
3434 EXCEPTION_PREAMBLE(i_isolate);
3435 has_pending_exception =
3436 !i::Runtime::GetObjectProperty(i_isolate, self, toStringTag)
3437 .ToHandle(&tag);
3438 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::String>());
3439
3440 if (!tag->IsUndefined()) {
3441 if (!tag->IsString())
3442 return v8::String::NewFromUtf8(isolate, "[object ???]");
3443 i::Handle<i::String> tag_name = i::Handle<i::String>::cast(tag);
3444 if (!i::String::Equals(class_name, tag_name)) {
3445 Local<String> result;
3446 if (GetPredefinedToString(tag_name, &result)) return result;
3447
3448 class_name = tag_name;
3449 }
3450 }
3451 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003452 const char* prefix = "[object ";
3453 Local<String> str = Utils::ToLocal(class_name);
3454 const char* postfix = "]";
3455
Steve Blockd0582a62009-12-15 09:54:21 +00003456 int prefix_len = i::StrLength(prefix);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003457 int str_len = str->Utf8Length();
Steve Blockd0582a62009-12-15 09:54:21 +00003458 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00003459
Steve Blockd0582a62009-12-15 09:54:21 +00003460 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01003461 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00003462
3463 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01003464 char* ptr = buf.start();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003465 i::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003466 ptr += prefix_len;
3467
3468 // Write real content.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003469 str->WriteUtf8(ptr, str_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00003470 ptr += str_len;
3471
3472 // Write postfix.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003473 i::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003474
3475 // Copy the buffer into a heap-allocated string and return it.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003476 Local<String> result = v8::String::NewFromUtf8(
3477 isolate, buf.start(), String::kNormalString, buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00003478 return result;
3479 }
3480 }
3481}
3482
3483
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003484Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01003485 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3486 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
3487 return Local<v8::String>());
3488 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003489 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3490 i::Handle<i::String> name(self->constructor_name());
3491 return Utils::ToLocal(name);
3492}
3493
3494
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003495bool v8::Object::Delete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003496 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3497 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
3498 ENTER_V8(isolate);
3499 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003500 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003501 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3502 EXCEPTION_PREAMBLE(isolate);
3503 i::Handle<i::Object> obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003504 has_pending_exception =
3505 !DeleteObjectProperty(isolate, self, key_obj,
3506 i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003507 EXCEPTION_BAILOUT_CHECK(isolate, false);
3508 return obj->IsTrue();
Steve Blocka7e24c12009-10-30 11:49:00 +00003509}
3510
3511
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003512bool v8::Object::DeletePrivate(v8::Handle<Private> key) {
3513 return Delete(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3514}
3515
3516
3517bool v8::Object::Has(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003518 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3519 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
3520 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003521 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3522 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3523 EXCEPTION_PREAMBLE(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003524 Maybe<bool> maybe;
3525 // Check if the given key is an array index.
3526 uint32_t index;
3527 if (key_obj->ToArrayIndex(&index)) {
3528 maybe = i::JSReceiver::HasElement(self, index);
3529 } else {
3530 // Convert the key to a name - possibly by calling back into JavaScript.
3531 i::Handle<i::Name> name;
3532 if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) {
3533 maybe = i::JSReceiver::HasProperty(self, name);
3534 }
3535 }
3536 if (!maybe.has_value) has_pending_exception = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003537 EXCEPTION_BAILOUT_CHECK(isolate, false);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003538 DCHECK(maybe.has_value);
3539 return maybe.value;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003540}
3541
3542
3543bool v8::Object::HasPrivate(v8::Handle<Private> key) {
3544 // TODO(rossberg): this should use HasOwnProperty, but we'd need to
3545 // generalise that to a (noy yet existant) Name argument first.
3546 return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
Steve Blocka7e24c12009-10-30 11:49:00 +00003547}
3548
3549
3550bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01003551 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3552 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
3553 return false);
3554 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003555 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00003556 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003557
3558 EXCEPTION_PREAMBLE(isolate);
3559 i::Handle<i::Object> obj;
3560 has_pending_exception =
3561 !i::JSReceiver::DeleteElement(self, index).ToHandle(&obj);
3562 EXCEPTION_BAILOUT_CHECK(isolate, false);
3563 return obj->IsTrue();
Steve Blocka7e24c12009-10-30 11:49:00 +00003564}
3565
3566
3567bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01003568 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3569 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003570 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003571 EXCEPTION_PREAMBLE(isolate);
3572 Maybe<bool> maybe = i::JSReceiver::HasElement(self, index);
3573 has_pending_exception = !maybe.has_value;
3574 EXCEPTION_BAILOUT_CHECK(isolate, false);
3575 return maybe.value;
3576}
3577
3578
3579template<typename Getter, typename Setter, typename Data>
3580static inline bool ObjectSetAccessor(Object* obj,
3581 Handle<Name> name,
3582 Getter getter,
3583 Setter setter,
3584 Data data,
3585 AccessControl settings,
3586 PropertyAttribute attributes) {
3587 i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate();
3588 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3589 ENTER_V8(isolate);
3590 i::HandleScope scope(isolate);
3591 v8::Handle<AccessorSignature> signature;
3592 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(
3593 name, getter, setter, data, settings, attributes, signature);
3594 if (info.is_null()) return false;
3595 bool fast = Utils::OpenHandle(obj)->HasFastProperties();
3596 i::Handle<i::Object> result;
3597 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3598 isolate, result,
3599 i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
3600 false);
3601 if (result->IsUndefined()) return false;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003602 if (fast) {
3603 i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0, "APISetAccessor");
3604 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003605 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003606}
3607
3608
Leon Clarkef7060e22010-06-03 12:02:55 +01003609bool Object::SetAccessor(Handle<String> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003610 AccessorGetterCallback getter,
3611 AccessorSetterCallback setter,
Leon Clarkef7060e22010-06-03 12:02:55 +01003612 v8::Handle<Value> data,
3613 AccessControl settings,
3614 PropertyAttribute attributes) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003615 return ObjectSetAccessor(
3616 this, name, getter, setter, data, settings, attributes);
3617}
3618
3619
3620bool Object::SetAccessor(Handle<Name> name,
3621 AccessorNameGetterCallback getter,
3622 AccessorNameSetterCallback setter,
3623 v8::Handle<Value> data,
3624 AccessControl settings,
3625 PropertyAttribute attributes) {
3626 return ObjectSetAccessor(
3627 this, name, getter, setter, data, settings, attributes);
3628}
3629
3630
3631bool Object::SetDeclaredAccessor(Local<Name> name,
3632 Local<DeclaredAccessorDescriptor> descriptor,
3633 PropertyAttribute attributes,
3634 AccessControl settings) {
3635 void* null = NULL;
3636 return ObjectSetAccessor(
3637 this, name, descriptor, null, null, settings, attributes);
3638}
3639
3640
3641void Object::SetAccessorProperty(Local<Name> name,
3642 Local<Function> getter,
3643 Handle<Function> setter,
3644 PropertyAttribute attribute,
3645 AccessControl settings) {
3646 // TODO(verwaest): Remove |settings|.
3647 DCHECK_EQ(v8::DEFAULT, settings);
Steve Block44f0eee2011-05-26 01:26:41 +01003648 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003649 ON_BAILOUT(isolate, "v8::Object::SetAccessorProperty()", return);
Steve Block44f0eee2011-05-26 01:26:41 +01003650 ENTER_V8(isolate);
3651 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003652 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
3653 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
3654 if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
3655 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(this),
3656 v8::Utils::OpenHandle(*name),
3657 getter_i,
3658 setter_i,
3659 static_cast<PropertyAttributes>(attribute));
Leon Clarkef7060e22010-06-03 12:02:55 +01003660}
3661
3662
Ben Murdoch257744e2011-11-30 15:57:28 +00003663bool v8::Object::HasOwnProperty(Handle<String> key) {
3664 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3665 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3666 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003667 EXCEPTION_PREAMBLE(isolate);
3668 Maybe<bool> maybe = i::JSReceiver::HasOwnProperty(Utils::OpenHandle(this),
3669 Utils::OpenHandle(*key));
3670 has_pending_exception = !maybe.has_value;
3671 EXCEPTION_BAILOUT_CHECK(isolate, false);
3672 return maybe.value;
Ben Murdoch257744e2011-11-30 15:57:28 +00003673}
3674
3675
Steve Blocka7e24c12009-10-30 11:49:00 +00003676bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003677 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3678 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
3679 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003680 EXCEPTION_PREAMBLE(isolate);
3681 Maybe<bool> maybe = i::JSObject::HasRealNamedProperty(
3682 Utils::OpenHandle(this), Utils::OpenHandle(*key));
3683 has_pending_exception = !maybe.has_value;
3684 EXCEPTION_BAILOUT_CHECK(isolate, false);
3685 return maybe.value;
Steve Blocka7e24c12009-10-30 11:49:00 +00003686}
3687
3688
3689bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003690 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3691 ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
Steve Block44f0eee2011-05-26 01:26:41 +01003692 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003693 EXCEPTION_PREAMBLE(isolate);
3694 Maybe<bool> maybe =
3695 i::JSObject::HasRealElementProperty(Utils::OpenHandle(this), index);
3696 has_pending_exception = !maybe.has_value;
3697 EXCEPTION_BAILOUT_CHECK(isolate, false);
3698 return maybe.value;
Steve Blocka7e24c12009-10-30 11:49:00 +00003699}
3700
3701
3702bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003703 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3704 ON_BAILOUT(isolate,
3705 "v8::Object::HasRealNamedCallbackProperty()",
3706 return false);
3707 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003708 EXCEPTION_PREAMBLE(isolate);
3709 Maybe<bool> maybe = i::JSObject::HasRealNamedCallbackProperty(
3710 Utils::OpenHandle(this), Utils::OpenHandle(*key));
3711 has_pending_exception = !maybe.has_value;
3712 EXCEPTION_BAILOUT_CHECK(isolate, false);
3713 return maybe.value;
Steve Blocka7e24c12009-10-30 11:49:00 +00003714}
3715
3716
3717bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003718 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3719 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
3720 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003721 return Utils::OpenHandle(this)->HasNamedInterceptor();
3722}
3723
3724
3725bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003726 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3727 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
3728 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003729 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3730}
3731
3732
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003733static Local<Value> GetPropertyByLookup(i::LookupIterator* it) {
3734 // If the property being looked up is a callback, it can throw an exception.
3735 EXCEPTION_PREAMBLE(it->isolate());
3736 i::Handle<i::Object> result;
3737 has_pending_exception = !i::Object::GetProperty(it).ToHandle(&result);
3738 EXCEPTION_BAILOUT_CHECK(it->isolate(), Local<Value>());
Ben Murdoch8b112d22011-06-08 16:22:53 +01003739
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003740 if (it->IsFound()) return Utils::ToLocal(result);
3741 return Local<Value>();
Ben Murdoch8b112d22011-06-08 16:22:53 +01003742}
3743
3744
Steve Blocka7e24c12009-10-30 11:49:00 +00003745Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003746 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003747 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3748 ON_BAILOUT(isolate,
3749 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003750 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01003751 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003752 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3753 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003754 i::PrototypeIterator iter(isolate, self_obj);
3755 if (iter.IsAtEnd()) return Local<Value>();
3756 i::Handle<i::Object> proto = i::PrototypeIterator::GetCurrent(iter);
3757 i::LookupIterator it(self_obj, key_obj, i::Handle<i::JSReceiver>::cast(proto),
3758 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3759 return GetPropertyByLookup(&it);
Steve Blocka7e24c12009-10-30 11:49:00 +00003760}
3761
3762
3763Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003764 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3765 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
3766 return Local<Value>());
3767 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003768 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3769 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003770 i::LookupIterator it(self_obj, key_obj,
3771 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3772 return GetPropertyByLookup(&it);
Steve Blocka7e24c12009-10-30 11:49:00 +00003773}
3774
3775
3776// Turns on access checks by copying the map and setting the check flag.
3777// Because the object gets a new map, existing inline cache caching
3778// the old map of this object will fail.
3779void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01003780 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3781 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
3782 ENTER_V8(isolate);
3783 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003784 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3785
Ben Murdochb0fe1622011-05-05 13:52:32 +01003786 // When turning on access checks for a global object deoptimize all functions
3787 // as optimized code does not always handle access checks.
3788 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3789
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003790 i::Handle<i::Map> new_map =
3791 i::Map::Copy(i::Handle<i::Map>(obj->map()), "APITurnOnAccessCheck");
Steve Blocka7e24c12009-10-30 11:49:00 +00003792 new_map->set_is_access_check_needed(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003793 i::JSObject::MigrateToMap(obj, new_map);
Steve Blocka7e24c12009-10-30 11:49:00 +00003794}
3795
3796
Steve Blocka7e24c12009-10-30 11:49:00 +00003797Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01003798 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3799 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
3800 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003801 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003802 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003803 i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00003804 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003805 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003806 return Utils::ToLocal(result);
3807}
3808
3809
Ben Murdoch8b112d22011-06-08 16:22:53 +01003810Local<v8::Context> v8::Object::CreationContext() {
3811 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3812 ON_BAILOUT(isolate,
3813 "v8::Object::CreationContext()", return Local<v8::Context>());
3814 ENTER_V8(isolate);
3815 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003816 i::Context* context = self->GetCreationContext();
Ben Murdoch8b112d22011-06-08 16:22:53 +01003817 return Utils::ToLocal(i::Handle<i::Context>(context));
3818}
3819
3820
Steve Blocka7e24c12009-10-30 11:49:00 +00003821int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01003822 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3823 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
3824 ENTER_V8(isolate);
3825 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003826 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003827 return i::JSReceiver::GetOrCreateIdentityHash(self)->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003828}
3829
3830
3831bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3832 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003833 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3834 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003835 if (value.IsEmpty()) return DeleteHiddenValue(key);
Steve Block44f0eee2011-05-26 01:26:41 +01003836 ENTER_V8(isolate);
3837 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003838 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003839 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003840 i::Handle<i::String> key_string =
3841 isolate->factory()->InternalizeString(key_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00003842 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003843 i::Handle<i::Object> result =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003844 i::JSObject::SetHiddenProperty(self, key_string, value_obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003845 return *result == *self;
Steve Blocka7e24c12009-10-30 11:49:00 +00003846}
3847
3848
3849v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003850 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3851 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3852 return Local<v8::Value>());
3853 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003854 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003855 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003856 i::Handle<i::String> key_string =
3857 isolate->factory()->InternalizeString(key_obj);
3858 i::Handle<i::Object> result(self->GetHiddenProperty(key_string), isolate);
3859 if (result->IsTheHole()) return v8::Local<v8::Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +00003860 return Utils::ToLocal(result);
3861}
3862
3863
3864bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003865 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3866 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
3867 ENTER_V8(isolate);
3868 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003869 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003870 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003871 i::Handle<i::String> key_string =
3872 isolate->factory()->InternalizeString(key_obj);
3873 i::JSObject::DeleteHiddenProperty(self, key_string);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003874 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003875}
3876
3877
Steve Block44f0eee2011-05-26 01:26:41 +01003878namespace {
3879
Ben Murdoch589d6972011-11-30 16:04:58 +00003880static i::ElementsKind GetElementsKindFromExternalArrayType(
3881 ExternalArrayType array_type) {
3882 switch (array_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003883#define ARRAY_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \
3884 case kExternal##Type##Array: \
3885 return i::EXTERNAL_##TYPE##_ELEMENTS;
3886
3887 TYPED_ARRAYS(ARRAY_TYPE_TO_ELEMENTS_KIND)
3888#undef ARRAY_TYPE_TO_ELEMENTS_KIND
Ben Murdoch589d6972011-11-30 16:04:58 +00003889 }
3890 UNREACHABLE();
3891 return i::DICTIONARY_ELEMENTS;
3892}
3893
3894
Steve Block44f0eee2011-05-26 01:26:41 +01003895void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3896 void* data,
3897 ExternalArrayType array_type,
3898 int length) {
3899 i::Isolate* isolate = object->GetIsolate();
3900 i::Handle<i::ExternalArray> array =
3901 isolate->factory()->NewExternalArray(length, array_type, data);
3902
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003903 i::Handle<i::Map> external_array_map =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003904 i::JSObject::GetElementsTransitionMap(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003905 object,
3906 GetElementsKindFromExternalArrayType(array_type));
3907
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003908 i::JSObject::SetMapAndElements(object, external_array_map, array);
Steve Block44f0eee2011-05-26 01:26:41 +01003909}
3910
3911} // namespace
3912
3913
Steve Blocka7e24c12009-10-30 11:49:00 +00003914void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003915 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3916 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3917 ENTER_V8(isolate);
3918 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003919 if (!Utils::ApiCheck(length >= 0 &&
3920 length <= i::ExternalUint8ClampedArray::kMaxLength,
3921 "v8::Object::SetIndexedPropertiesToPixelData()",
3922 "length exceeds max acceptable value")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003923 return;
3924 }
3925 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003926 if (!Utils::ApiCheck(!self->IsJSArray(),
3927 "v8::Object::SetIndexedPropertiesToPixelData()",
3928 "JSArray is not supported")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003929 return;
3930 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003931 PrepareExternalArrayElements(self, data, kExternalUint8ClampedArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003932}
3933
3934
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003935bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003936 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003937 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3938 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003939 return self->HasExternalUint8ClampedElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003940}
3941
3942
3943uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003944 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003945 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3946 return NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003947 if (self->HasExternalUint8ClampedElements()) {
3948 return i::ExternalUint8ClampedArray::cast(self->elements())->
3949 external_uint8_clamped_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003950 } else {
3951 return NULL;
3952 }
3953}
3954
3955
3956int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003957 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003958 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3959 return -1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003960 if (self->HasExternalUint8ClampedElements()) {
3961 return i::ExternalUint8ClampedArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003962 } else {
3963 return -1;
3964 }
3965}
3966
Ben Murdoch589d6972011-11-30 16:04:58 +00003967
Steve Block3ce2e202009-11-05 08:53:23 +00003968void v8::Object::SetIndexedPropertiesToExternalArrayData(
3969 void* data,
3970 ExternalArrayType array_type,
3971 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003972 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3973 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3974 ENTER_V8(isolate);
3975 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003976 if (!Utils::ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
3977 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3978 "length exceeds max acceptable value")) {
Steve Block3ce2e202009-11-05 08:53:23 +00003979 return;
3980 }
3981 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003982 if (!Utils::ApiCheck(!self->IsJSArray(),
3983 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3984 "JSArray is not supported")) {
Steve Block3ce2e202009-11-05 08:53:23 +00003985 return;
3986 }
Steve Block44f0eee2011-05-26 01:26:41 +01003987 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003988}
3989
3990
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003991bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003992 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003993 ON_BAILOUT(self->GetIsolate(),
3994 "v8::HasIndexedPropertiesInExternalArrayData()",
3995 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003996 return self->HasExternalArrayElements();
3997}
3998
3999
4000void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01004001 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004002 ON_BAILOUT(self->GetIsolate(),
4003 "v8::GetIndexedPropertiesExternalArrayData()",
4004 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01004005 if (self->HasExternalArrayElements()) {
4006 return i::ExternalArray::cast(self->elements())->external_pointer();
4007 } else {
4008 return NULL;
4009 }
4010}
4011
4012
4013ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01004014 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004015 ON_BAILOUT(self->GetIsolate(),
4016 "v8::GetIndexedPropertiesExternalArrayDataType()",
4017 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01004018 switch (self->elements()->map()->instance_type()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004019#define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \
4020 case i::EXTERNAL_##TYPE##_ARRAY_TYPE: \
4021 return kExternal##Type##Array;
4022 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
4023#undef INSTANCE_TYPE_TO_ARRAY_TYPE
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01004024 default:
4025 return static_cast<ExternalArrayType>(-1);
4026 }
4027}
4028
4029
4030int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01004031 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004032 ON_BAILOUT(self->GetIsolate(),
4033 "v8::GetIndexedPropertiesExternalArrayDataLength()",
4034 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01004035 if (self->HasExternalArrayElements()) {
4036 return i::ExternalArray::cast(self->elements())->length();
4037 } else {
4038 return -1;
4039 }
4040}
4041
4042
Ben Murdoch257744e2011-11-30 15:57:28 +00004043bool v8::Object::IsCallable() {
4044 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4045 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
4046 ENTER_V8(isolate);
4047 i::HandleScope scope(isolate);
4048 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004049 return obj->IsCallable();
Ben Murdoch257744e2011-11-30 15:57:28 +00004050}
4051
4052
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004053Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004054 int argc,
Ben Murdoch257744e2011-11-30 15:57:28 +00004055 v8::Handle<v8::Value> argv[]) {
4056 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4057 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
4058 return Local<v8::Value>());
4059 LOG_API(isolate, "Object::CallAsFunction");
4060 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004061 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00004062 i::HandleScope scope(isolate);
4063 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4064 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4065 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004066 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch257744e2011-11-30 15:57:28 +00004067 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
4068 if (obj->IsJSFunction()) {
4069 fun = i::Handle<i::JSFunction>::cast(obj);
4070 } else {
4071 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004072 i::Handle<i::Object> delegate;
4073 has_pending_exception = !i::Execution::TryGetFunctionDelegate(
4074 isolate, obj).ToHandle(&delegate);
Ben Murdoch257744e2011-11-30 15:57:28 +00004075 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
4076 fun = i::Handle<i::JSFunction>::cast(delegate);
4077 recv_obj = obj;
4078 }
4079 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004080 i::Handle<i::Object> returned;
4081 has_pending_exception = !i::Execution::Call(
4082 isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004083 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
Ben Murdoch257744e2011-11-30 15:57:28 +00004084 return Utils::ToLocal(scope.CloseAndEscape(returned));
4085}
4086
4087
4088Local<v8::Value> Object::CallAsConstructor(int argc,
4089 v8::Handle<v8::Value> argv[]) {
4090 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4091 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
4092 return Local<v8::Object>());
4093 LOG_API(isolate, "Object::CallAsConstructor");
4094 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004095 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00004096 i::HandleScope scope(isolate);
4097 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4098 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004099 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch257744e2011-11-30 15:57:28 +00004100 if (obj->IsJSFunction()) {
4101 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
4102 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004103 i::Handle<i::Object> returned;
4104 has_pending_exception = !i::Execution::New(
4105 fun, argc, args).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004106 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
Ben Murdoch257744e2011-11-30 15:57:28 +00004107 return Utils::ToLocal(scope.CloseAndEscape(
4108 i::Handle<i::JSObject>::cast(returned)));
4109 }
4110 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004111 i::Handle<i::Object> delegate;
4112 has_pending_exception = !i::Execution::TryGetConstructorDelegate(
4113 isolate, obj).ToHandle(&delegate);
Ben Murdoch257744e2011-11-30 15:57:28 +00004114 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
4115 if (!delegate->IsUndefined()) {
4116 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
4117 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004118 i::Handle<i::Object> returned;
4119 has_pending_exception = !i::Execution::Call(
4120 isolate, fun, obj, argc, args).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004121 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004122 DCHECK(!delegate->IsUndefined());
Ben Murdoch257744e2011-11-30 15:57:28 +00004123 return Utils::ToLocal(scope.CloseAndEscape(returned));
4124 }
4125 return Local<v8::Object>();
4126}
4127
4128
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004129Local<Function> Function::New(Isolate* v8_isolate,
4130 FunctionCallback callback,
4131 Local<Value> data,
4132 int length) {
4133 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
4134 LOG_API(isolate, "Function::New");
4135 ENTER_V8(isolate);
4136 return FunctionTemplateNew(
4137 isolate, callback, data, Local<Signature>(), length, true)->
4138 GetFunction();
4139}
4140
4141
Steve Blocka7e24c12009-10-30 11:49:00 +00004142Local<v8::Object> Function::NewInstance() const {
4143 return NewInstance(0, NULL);
4144}
4145
4146
4147Local<v8::Object> Function::NewInstance(int argc,
4148 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01004149 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4150 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
4151 return Local<v8::Object>());
4152 LOG_API(isolate, "Function::NewInstance");
4153 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004154 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4155 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004156 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
4157 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004158 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01004159 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004160 i::Handle<i::Object> returned;
4161 has_pending_exception = !i::Execution::New(
4162 function, argc, args).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004163 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004164 return scope.Escape(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004165}
4166
4167
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004168Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
Steve Blocka7e24c12009-10-30 11:49:00 +00004169 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01004170 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4171 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
4172 LOG_API(isolate, "Function::Call");
4173 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004174 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4175 i::HandleScope scope(isolate);
4176 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
4177 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4178 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
4179 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4180 EXCEPTION_PREAMBLE(isolate);
4181 i::Handle<i::Object> returned;
4182 has_pending_exception = !i::Execution::Call(
4183 isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
4184 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
4185 return Utils::ToLocal(scope.CloseAndEscape(returned));
Steve Blocka7e24c12009-10-30 11:49:00 +00004186}
4187
4188
4189void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01004190 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4191 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004192 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004193 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4194 func->shared()->set_name(*Utils::OpenHandle(*name));
4195}
4196
4197
4198Handle<Value> Function::GetName() const {
4199 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004200 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name(),
4201 func->GetIsolate()));
Steve Blocka7e24c12009-10-30 11:49:00 +00004202}
4203
4204
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004205Handle<Value> Function::GetInferredName() const {
4206 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004207 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4208 func->GetIsolate()));
4209}
4210
4211
4212Handle<Value> Function::GetDisplayName() const {
4213 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4214 ON_BAILOUT(isolate, "v8::Function::GetDisplayName()",
4215 return ToApiHandle<Primitive>(
4216 isolate->factory()->undefined_value()));
4217 ENTER_V8(isolate);
4218 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4219 i::Handle<i::String> property_name =
4220 isolate->factory()->InternalizeOneByteString(
4221 STATIC_CHAR_VECTOR("displayName"));
4222
4223 i::Handle<i::Object> value =
4224 i::JSObject::GetDataProperty(func, property_name);
4225 if (value->IsString()) {
4226 i::Handle<i::String> name = i::Handle<i::String>::cast(value);
4227 if (name->length() > 0) return Utils::ToLocal(name);
4228 }
4229
4230 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004231}
4232
4233
Andrei Popescu402d9372010-02-26 13:31:12 +00004234ScriptOrigin Function::GetScriptOrigin() const {
4235 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4236 if (func->shared()->script()->IsScript()) {
4237 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004238 i::Handle<i::Object> scriptName = i::Script::GetNameOrSourceURL(script);
4239 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(func->GetIsolate());
Andrei Popescu402d9372010-02-26 13:31:12 +00004240 v8::ScriptOrigin origin(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004241 Utils::ToLocal(scriptName),
4242 v8::Integer::New(isolate, script->line_offset()->value()),
4243 v8::Integer::New(isolate, script->column_offset()->value()));
Andrei Popescu402d9372010-02-26 13:31:12 +00004244 return origin;
4245 }
4246 return v8::ScriptOrigin(Handle<Value>());
4247}
4248
4249
4250const int Function::kLineOffsetNotFound = -1;
4251
4252
4253int Function::GetScriptLineNumber() const {
4254 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4255 if (func->shared()->script()->IsScript()) {
4256 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004257 return i::Script::GetLineNumber(script, func->shared()->start_position());
Andrei Popescu402d9372010-02-26 13:31:12 +00004258 }
4259 return kLineOffsetNotFound;
4260}
4261
4262
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004263int Function::GetScriptColumnNumber() const {
4264 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4265 if (func->shared()->script()->IsScript()) {
4266 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004267 return i::Script::GetColumnNumber(script, func->shared()->start_position());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004268 }
4269 return kLineOffsetNotFound;
4270}
4271
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004272
4273bool Function::IsBuiltin() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004274 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004275 return func->IsBuiltin();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004276}
4277
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004278
4279int Function::ScriptId() const {
4280 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4281 if (!func->shared()->script()->IsScript()) {
4282 return v8::UnboundScript::kNoScriptId;
4283 }
4284 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4285 return script->id()->value();
4286}
4287
4288
4289Local<v8::Value> Function::GetBoundFunction() const {
4290 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4291 if (!func->shared()->bound()) {
4292 return v8::Undefined(reinterpret_cast<v8::Isolate*>(func->GetIsolate()));
4293 }
4294 i::Handle<i::FixedArray> bound_args = i::Handle<i::FixedArray>(
4295 i::FixedArray::cast(func->function_bindings()));
4296 i::Handle<i::Object> original(
4297 bound_args->get(i::JSFunction::kBoundFunctionIndex),
4298 func->GetIsolate());
4299 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(original));
4300}
4301
4302
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004303int Name::GetIdentityHash() {
4304 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4305 ON_BAILOUT(isolate, "v8::Name::GetIdentityHash()", return 0);
4306 ENTER_V8(isolate);
4307 i::HandleScope scope(isolate);
4308 i::Handle<i::Name> self = Utils::OpenHandle(this);
4309 return static_cast<int>(self->Hash());
4310}
4311
4312
Steve Blocka7e24c12009-10-30 11:49:00 +00004313int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004314 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004315 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00004316}
4317
4318
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004319bool String::IsOneByte() const {
4320 i::Handle<i::String> str = Utils::OpenHandle(this);
4321 return str->HasOnlyOneByteChars();
4322}
4323
4324
4325// Helpers for ContainsOnlyOneByteHelper
4326template<size_t size> struct OneByteMask;
4327template<> struct OneByteMask<4> {
4328 static const uint32_t value = 0xFF00FF00;
4329};
4330template<> struct OneByteMask<8> {
4331 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4332};
4333static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4334static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4335static inline bool Unaligned(const uint16_t* chars) {
4336 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4337}
4338
4339
4340static inline const uint16_t* Align(const uint16_t* chars) {
4341 return reinterpret_cast<uint16_t*>(
4342 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4343}
4344
4345class ContainsOnlyOneByteHelper {
4346 public:
4347 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4348 bool Check(i::String* string) {
4349 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4350 if (cons_string == NULL) return is_one_byte_;
4351 return CheckCons(cons_string);
4352 }
4353 void VisitOneByteString(const uint8_t* chars, int length) {
4354 // Nothing to do.
4355 }
4356 void VisitTwoByteString(const uint16_t* chars, int length) {
4357 // Accumulated bits.
4358 uintptr_t acc = 0;
4359 // Align to uintptr_t.
4360 const uint16_t* end = chars + length;
4361 while (Unaligned(chars) && chars != end) {
4362 acc |= *chars++;
4363 }
4364 // Read word aligned in blocks,
4365 // checking the return value at the end of each block.
4366 const uint16_t* aligned_end = Align(end);
4367 const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4368 const int inner_loops = 16;
4369 while (chars + inner_loops*increment < aligned_end) {
4370 for (int i = 0; i < inner_loops; i++) {
4371 acc |= *reinterpret_cast<const uintptr_t*>(chars);
4372 chars += increment;
4373 }
4374 // Check for early return.
4375 if ((acc & kOneByteMask) != 0) {
4376 is_one_byte_ = false;
4377 return;
4378 }
4379 }
4380 // Read the rest.
4381 while (chars != end) {
4382 acc |= *chars++;
4383 }
4384 // Check result.
4385 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
4386 }
4387
4388 private:
4389 bool CheckCons(i::ConsString* cons_string) {
4390 while (true) {
4391 // Check left side if flat.
4392 i::String* left = cons_string->first();
4393 i::ConsString* left_as_cons =
4394 i::String::VisitFlat(this, left, 0);
4395 if (!is_one_byte_) return false;
4396 // Check right side if flat.
4397 i::String* right = cons_string->second();
4398 i::ConsString* right_as_cons =
4399 i::String::VisitFlat(this, right, 0);
4400 if (!is_one_byte_) return false;
4401 // Standard recurse/iterate trick.
4402 if (left_as_cons != NULL && right_as_cons != NULL) {
4403 if (left->length() < right->length()) {
4404 CheckCons(left_as_cons);
4405 cons_string = right_as_cons;
4406 } else {
4407 CheckCons(right_as_cons);
4408 cons_string = left_as_cons;
4409 }
4410 // Check fast return.
4411 if (!is_one_byte_) return false;
4412 continue;
4413 }
4414 // Descend left in place.
4415 if (left_as_cons != NULL) {
4416 cons_string = left_as_cons;
4417 continue;
4418 }
4419 // Descend right in place.
4420 if (right_as_cons != NULL) {
4421 cons_string = right_as_cons;
4422 continue;
4423 }
4424 // Terminate.
4425 break;
4426 }
4427 return is_one_byte_;
4428 }
4429 bool is_one_byte_;
4430 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4431};
4432
4433
4434bool String::ContainsOnlyOneByte() const {
4435 i::Handle<i::String> str = Utils::OpenHandle(this);
4436 if (str->HasOnlyOneByteChars()) return true;
4437 ContainsOnlyOneByteHelper helper;
4438 return helper.Check(*str);
4439}
4440
4441
4442class Utf8LengthHelper : public i::AllStatic {
4443 public:
4444 enum State {
4445 kEndsWithLeadingSurrogate = 1 << 0,
4446 kStartsWithTrailingSurrogate = 1 << 1,
4447 kLeftmostEdgeIsCalculated = 1 << 2,
4448 kRightmostEdgeIsCalculated = 1 << 3,
4449 kLeftmostEdgeIsSurrogate = 1 << 4,
4450 kRightmostEdgeIsSurrogate = 1 << 5
4451 };
4452
4453 static const uint8_t kInitialState = 0;
4454
4455 static inline bool EndsWithSurrogate(uint8_t state) {
4456 return state & kEndsWithLeadingSurrogate;
4457 }
4458
4459 static inline bool StartsWithSurrogate(uint8_t state) {
4460 return state & kStartsWithTrailingSurrogate;
4461 }
4462
4463 class Visitor {
4464 public:
4465 Visitor() : utf8_length_(0), state_(kInitialState) {}
4466
4467 void VisitOneByteString(const uint8_t* chars, int length) {
4468 int utf8_length = 0;
4469 // Add in length 1 for each non-Latin1 character.
4470 for (int i = 0; i < length; i++) {
4471 utf8_length += *chars++ >> 7;
4472 }
4473 // Add in length 1 for each character.
4474 utf8_length_ = utf8_length + length;
4475 state_ = kInitialState;
4476 }
4477
4478 void VisitTwoByteString(const uint16_t* chars, int length) {
4479 int utf8_length = 0;
4480 int last_character = unibrow::Utf16::kNoPreviousCharacter;
4481 for (int i = 0; i < length; i++) {
4482 uint16_t c = chars[i];
4483 utf8_length += unibrow::Utf8::Length(c, last_character);
4484 last_character = c;
4485 }
4486 utf8_length_ = utf8_length;
4487 uint8_t state = 0;
4488 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4489 state |= kStartsWithTrailingSurrogate;
4490 }
4491 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4492 state |= kEndsWithLeadingSurrogate;
4493 }
4494 state_ = state;
4495 }
4496
4497 static i::ConsString* VisitFlat(i::String* string,
4498 int* length,
4499 uint8_t* state) {
4500 Visitor visitor;
4501 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4502 *length = visitor.utf8_length_;
4503 *state = visitor.state_;
4504 return cons_string;
4505 }
4506
4507 private:
4508 int utf8_length_;
4509 uint8_t state_;
4510 DISALLOW_COPY_AND_ASSIGN(Visitor);
4511 };
4512
4513 static inline void MergeLeafLeft(int* length,
4514 uint8_t* state,
4515 uint8_t leaf_state) {
4516 bool edge_surrogate = StartsWithSurrogate(leaf_state);
4517 if (!(*state & kLeftmostEdgeIsCalculated)) {
4518 DCHECK(!(*state & kLeftmostEdgeIsSurrogate));
4519 *state |= kLeftmostEdgeIsCalculated
4520 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4521 } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4522 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4523 }
4524 if (EndsWithSurrogate(leaf_state)) {
4525 *state |= kEndsWithLeadingSurrogate;
4526 } else {
4527 *state &= ~kEndsWithLeadingSurrogate;
4528 }
4529 }
4530
4531 static inline void MergeLeafRight(int* length,
4532 uint8_t* state,
4533 uint8_t leaf_state) {
4534 bool edge_surrogate = EndsWithSurrogate(leaf_state);
4535 if (!(*state & kRightmostEdgeIsCalculated)) {
4536 DCHECK(!(*state & kRightmostEdgeIsSurrogate));
4537 *state |= (kRightmostEdgeIsCalculated
4538 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4539 } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4540 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4541 }
4542 if (StartsWithSurrogate(leaf_state)) {
4543 *state |= kStartsWithTrailingSurrogate;
4544 } else {
4545 *state &= ~kStartsWithTrailingSurrogate;
4546 }
4547 }
4548
4549 static inline void MergeTerminal(int* length,
4550 uint8_t state,
4551 uint8_t* state_out) {
4552 DCHECK((state & kLeftmostEdgeIsCalculated) &&
4553 (state & kRightmostEdgeIsCalculated));
4554 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4555 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4556 }
4557 *state_out = kInitialState |
4558 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4559 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4560 }
4561
4562 static int Calculate(i::ConsString* current, uint8_t* state_out) {
4563 using namespace internal;
4564 int total_length = 0;
4565 uint8_t state = kInitialState;
4566 while (true) {
4567 i::String* left = current->first();
4568 i::String* right = current->second();
4569 uint8_t right_leaf_state;
4570 uint8_t left_leaf_state;
4571 int leaf_length;
4572 ConsString* left_as_cons =
4573 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4574 if (left_as_cons == NULL) {
4575 total_length += leaf_length;
4576 MergeLeafLeft(&total_length, &state, left_leaf_state);
4577 }
4578 ConsString* right_as_cons =
4579 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4580 if (right_as_cons == NULL) {
4581 total_length += leaf_length;
4582 MergeLeafRight(&total_length, &state, right_leaf_state);
4583 if (left_as_cons != NULL) {
4584 // 1 Leaf node. Descend in place.
4585 current = left_as_cons;
4586 continue;
4587 } else {
4588 // Terminal node.
4589 MergeTerminal(&total_length, state, state_out);
4590 return total_length;
4591 }
4592 } else if (left_as_cons == NULL) {
4593 // 1 Leaf node. Descend in place.
4594 current = right_as_cons;
4595 continue;
4596 }
4597 // Both strings are ConsStrings.
4598 // Recurse on smallest.
4599 if (left->length() < right->length()) {
4600 total_length += Calculate(left_as_cons, &left_leaf_state);
4601 MergeLeafLeft(&total_length, &state, left_leaf_state);
4602 current = right_as_cons;
4603 } else {
4604 total_length += Calculate(right_as_cons, &right_leaf_state);
4605 MergeLeafRight(&total_length, &state, right_leaf_state);
4606 current = left_as_cons;
4607 }
4608 }
4609 UNREACHABLE();
4610 return 0;
4611 }
4612
4613 static inline int Calculate(i::ConsString* current) {
4614 uint8_t state = kInitialState;
4615 return Calculate(current, &state);
4616 }
4617
4618 private:
4619 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
4620};
4621
4622
4623static int Utf8Length(i::String* str, i::Isolate* isolate) {
4624 int length = str->length();
4625 if (length == 0) return 0;
4626 uint8_t state;
4627 i::ConsString* cons_string =
4628 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4629 if (cons_string == NULL) return length;
4630 return Utf8LengthHelper::Calculate(cons_string);
4631}
4632
4633
Steve Blocka7e24c12009-10-30 11:49:00 +00004634int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004635 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004636 i::Isolate* isolate = str->GetIsolate();
4637 return v8::Utf8Length(*str, isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004638}
4639
4640
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004641class Utf8WriterVisitor {
4642 public:
4643 Utf8WriterVisitor(
4644 char* buffer,
4645 int capacity,
4646 bool skip_capacity_check,
4647 bool replace_invalid_utf8)
4648 : early_termination_(false),
4649 last_character_(unibrow::Utf16::kNoPreviousCharacter),
4650 buffer_(buffer),
4651 start_(buffer),
4652 capacity_(capacity),
4653 skip_capacity_check_(capacity == -1 || skip_capacity_check),
4654 replace_invalid_utf8_(replace_invalid_utf8),
4655 utf16_chars_read_(0) {
4656 }
4657
4658 static int WriteEndCharacter(uint16_t character,
4659 int last_character,
4660 int remaining,
4661 char* const buffer,
4662 bool replace_invalid_utf8) {
4663 using namespace unibrow;
4664 DCHECK(remaining > 0);
4665 // We can't use a local buffer here because Encode needs to modify
4666 // previous characters in the stream. We know, however, that
4667 // exactly one character will be advanced.
4668 if (Utf16::IsSurrogatePair(last_character, character)) {
4669 int written = Utf8::Encode(buffer,
4670 character,
4671 last_character,
4672 replace_invalid_utf8);
4673 DCHECK(written == 1);
4674 return written;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004675 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004676 // Use a scratch buffer to check the required characters.
4677 char temp_buffer[Utf8::kMaxEncodedSize];
4678 // Can't encode using last_character as gcc has array bounds issues.
4679 int written = Utf8::Encode(temp_buffer,
4680 character,
4681 Utf16::kNoPreviousCharacter,
4682 replace_invalid_utf8);
4683 // Won't fit.
4684 if (written > remaining) return 0;
4685 // Copy over the character from temp_buffer.
4686 for (int j = 0; j < written; j++) {
4687 buffer[j] = temp_buffer[j];
4688 }
4689 return written;
4690 }
4691
4692 // Visit writes out a group of code units (chars) of a v8::String to the
4693 // internal buffer_. This is done in two phases. The first phase calculates a
4694 // pesimistic estimate (writable_length) on how many code units can be safely
4695 // written without exceeding the buffer capacity and without writing the last
4696 // code unit (it could be a lead surrogate). The estimated number of code
4697 // units is then written out in one go, and the reported byte usage is used
4698 // to correct the estimate. This is repeated until the estimate becomes <= 0
4699 // or all code units have been written out. The second phase writes out code
4700 // units until the buffer capacity is reached, would be exceeded by the next
4701 // unit, or all units have been written out.
4702 template<typename Char>
4703 void Visit(const Char* chars, const int length) {
4704 using namespace unibrow;
4705 DCHECK(!early_termination_);
4706 if (length == 0) return;
4707 // Copy state to stack.
4708 char* buffer = buffer_;
4709 int last_character =
4710 sizeof(Char) == 1 ? Utf16::kNoPreviousCharacter : last_character_;
4711 int i = 0;
4712 // Do a fast loop where there is no exit capacity check.
4713 while (true) {
4714 int fast_length;
4715 if (skip_capacity_check_) {
4716 fast_length = length;
4717 } else {
4718 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4719 // Need enough space to write everything but one character.
4720 STATIC_ASSERT(Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
4721 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
4722 int writable_length =
4723 (remaining_capacity - max_size_per_char)/max_size_per_char;
4724 // Need to drop into slow loop.
4725 if (writable_length <= 0) break;
4726 fast_length = i + writable_length;
4727 if (fast_length > length) fast_length = length;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004728 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004729 // Write the characters to the stream.
4730 if (sizeof(Char) == 1) {
4731 for (; i < fast_length; i++) {
4732 buffer +=
4733 Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
4734 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004735 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004736 } else {
4737 for (; i < fast_length; i++) {
4738 uint16_t character = *chars++;
4739 buffer += Utf8::Encode(buffer,
4740 character,
4741 last_character,
4742 replace_invalid_utf8_);
4743 last_character = character;
4744 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004745 }
4746 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004747 // Array is fully written. Exit.
4748 if (fast_length == length) {
4749 // Write state back out to object.
4750 last_character_ = last_character;
4751 buffer_ = buffer;
4752 utf16_chars_read_ += length;
4753 return;
4754 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004755 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004756 DCHECK(!skip_capacity_check_);
4757 // Slow loop. Must check capacity on each iteration.
4758 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4759 DCHECK(remaining_capacity >= 0);
4760 for (; i < length && remaining_capacity > 0; i++) {
4761 uint16_t character = *chars++;
4762 // remaining_capacity is <= 3 bytes at this point, so we do not write out
4763 // an umatched lead surrogate.
4764 if (replace_invalid_utf8_ && Utf16::IsLeadSurrogate(character)) {
4765 early_termination_ = true;
4766 break;
4767 }
4768 int written = WriteEndCharacter(character,
4769 last_character,
4770 remaining_capacity,
4771 buffer,
4772 replace_invalid_utf8_);
4773 if (written == 0) {
4774 early_termination_ = true;
4775 break;
4776 }
4777 buffer += written;
4778 remaining_capacity -= written;
4779 last_character = character;
4780 }
4781 // Write state back out to object.
4782 last_character_ = last_character;
4783 buffer_ = buffer;
4784 utf16_chars_read_ += i;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004785 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004786
4787 inline bool IsDone() {
4788 return early_termination_;
4789 }
4790
4791 inline void VisitOneByteString(const uint8_t* chars, int length) {
4792 Visit(chars, length);
4793 }
4794
4795 inline void VisitTwoByteString(const uint16_t* chars, int length) {
4796 Visit(chars, length);
4797 }
4798
4799 int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
4800 // Write out number of utf16 characters written to the stream.
4801 if (utf16_chars_read_out != NULL) {
4802 *utf16_chars_read_out = utf16_chars_read_;
4803 }
4804 // Only null terminate if all of the string was written and there's space.
4805 if (write_null &&
4806 !early_termination_ &&
4807 (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
4808 *buffer_++ = '\0';
4809 }
4810 return static_cast<int>(buffer_ - start_);
4811 }
4812
4813 private:
4814 bool early_termination_;
4815 int last_character_;
4816 char* buffer_;
4817 char* const start_;
4818 int capacity_;
4819 bool const skip_capacity_check_;
4820 bool const replace_invalid_utf8_;
4821 int utf16_chars_read_;
4822 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
4823};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004824
4825
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004826static bool RecursivelySerializeToUtf8(i::String* current,
4827 Utf8WriterVisitor* writer,
4828 int recursion_budget) {
4829 while (!writer->IsDone()) {
4830 i::ConsString* cons_string = i::String::VisitFlat(writer, current);
4831 if (cons_string == NULL) return true; // Leaf node.
4832 if (recursion_budget <= 0) return false;
4833 // Must write the left branch first.
4834 i::String* first = cons_string->first();
4835 bool success = RecursivelySerializeToUtf8(first,
4836 writer,
4837 recursion_budget - 1);
4838 if (!success) return false;
4839 // Inline tail recurse for right branch.
4840 current = cons_string->second();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004841 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004842 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00004843}
4844
4845
Steve Block6ded16b2010-05-10 14:33:55 +01004846int String::WriteUtf8(char* buffer,
4847 int capacity,
4848 int* nchars_ref,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004849 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01004850 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004851 LOG_API(isolate, "String::WriteUtf8");
4852 ENTER_V8(isolate);
Ben Murdoch85b71792012-04-11 18:30:58 +01004853 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004854 if (options & HINT_MANY_WRITES_EXPECTED) {
4855 str = i::String::Flatten(str); // Flatten the string for efficiency.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004856 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004857 const int string_length = str->length();
4858 bool write_null = !(options & NO_NULL_TERMINATION);
4859 bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
4860 int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
4861 // First check if we can just write the string without checking capacity.
4862 if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
4863 Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004864 const int kMaxRecursion = 100;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004865 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
4866 if (success) return writer.CompleteWrite(write_null, nchars_ref);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004867 } else if (capacity >= string_length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004868 // First check that the buffer is large enough.
4869 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004870 if (utf8_bytes <= capacity) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004871 // one-byte fast path.
4872 if (utf8_bytes == string_length) {
4873 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
4874 if (nchars_ref != NULL) *nchars_ref = string_length;
4875 if (write_null && (utf8_bytes+1 <= capacity)) {
4876 return string_length + 1;
4877 }
4878 return string_length;
4879 }
4880 if (write_null && (utf8_bytes+1 > capacity)) {
4881 options |= NO_NULL_TERMINATION;
4882 }
4883 // Recurse once without a capacity limit.
4884 // This will get into the first branch above.
4885 // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004886 return WriteUtf8(buffer, -1, nchars_ref, options);
4887 }
4888 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004889 // Recursive slow path can potentially be unreasonable slow. Flatten.
4890 str = i::String::Flatten(str);
4891 Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
4892 i::String::VisitFlat(&writer, *str);
4893 return writer.CompleteWrite(write_null, nchars_ref);
Steve Blocka7e24c12009-10-30 11:49:00 +00004894}
4895
4896
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004897template<typename CharType>
4898static inline int WriteHelper(const String* string,
4899 CharType* buffer,
4900 int start,
4901 int length,
4902 int options) {
4903 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004904 LOG_API(isolate, "String::Write");
4905 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004906 DCHECK(start >= 0 && length >= -1);
4907 i::Handle<i::String> str = Utils::OpenHandle(string);
Steve Block44f0eee2011-05-26 01:26:41 +01004908 isolate->string_tracker()->RecordWrite(str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004909 if (options & String::HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01004910 // Flatten the string for efficiency. This applies whether we are
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004911 // using StringCharacterStream or Get(i) to access the characters.
4912 str = i::String::Flatten(str);
Steve Block6ded16b2010-05-10 14:33:55 +01004913 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01004914 int end = start + length;
4915 if ((length == -1) || (length > str->length() - start) )
4916 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00004917 if (end < 0) return 0;
4918 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004919 if (!(options & String::NO_NULL_TERMINATION) &&
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004920 (length == -1 || end - start < length)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004921 buffer[end - start] = '\0';
4922 }
4923 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00004924}
4925
4926
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004927int String::WriteOneByte(uint8_t* buffer,
4928 int start,
4929 int length,
4930 int options) const {
4931 return WriteHelper(this, buffer, start, length, options);
4932}
4933
4934
4935int String::Write(uint16_t* buffer,
4936 int start,
4937 int length,
4938 int options) const {
4939 return WriteHelper(this, buffer, start, length, options);
4940}
4941
4942
Steve Blocka7e24c12009-10-30 11:49:00 +00004943bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004944 i::Handle<i::String> str = Utils::OpenHandle(this);
4945 return i::StringShape(*str).IsExternalTwoByte();
4946}
4947
4948
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004949bool v8::String::IsExternalOneByte() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004950 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004951 return i::StringShape(*str).IsExternalOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00004952}
4953
4954
4955void v8::String::VerifyExternalStringResource(
4956 v8::String::ExternalStringResource* value) const {
4957 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004958 const v8::String::ExternalStringResource* expected;
Steve Blocka7e24c12009-10-30 11:49:00 +00004959 if (i::StringShape(*str).IsExternalTwoByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004960 const void* resource =
4961 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4962 expected = reinterpret_cast<const ExternalStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004963 } else {
4964 expected = NULL;
4965 }
4966 CHECK_EQ(expected, value);
4967}
4968
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004969void v8::String::VerifyExternalStringResourceBase(
4970 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004971 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004972 const v8::String::ExternalStringResourceBase* expected;
4973 Encoding expectedEncoding;
4974 if (i::StringShape(*str).IsExternalOneByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004975 const void* resource =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004976 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
4977 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4978 expectedEncoding = ONE_BYTE_ENCODING;
4979 } else if (i::StringShape(*str).IsExternalTwoByte()) {
4980 const void* resource =
4981 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4982 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4983 expectedEncoding = TWO_BYTE_ENCODING;
4984 } else {
4985 expected = NULL;
4986 expectedEncoding =
4987 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
4988 }
4989 CHECK_EQ(expected, value);
4990 CHECK_EQ(expectedEncoding, encoding);
4991}
4992
4993const v8::String::ExternalOneByteStringResource*
4994v8::String::GetExternalOneByteStringResource() const {
4995 i::Handle<i::String> str = Utils::OpenHandle(this);
4996 if (i::StringShape(*str).IsExternalOneByte()) {
4997 const void* resource =
4998 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
4999 return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00005000 } else {
5001 return NULL;
5002 }
5003}
5004
5005
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005006Local<Value> Symbol::Name() const {
5007 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5008 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
5009 return Utils::ToLocal(name);
5010}
5011
5012
5013Local<Value> Private::Name() const {
5014 return reinterpret_cast<const Symbol*>(this)->Name();
5015}
5016
5017
Steve Blocka7e24c12009-10-30 11:49:00 +00005018double Number::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005019 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5020 return obj->Number();
5021}
5022
5023
5024bool Boolean::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005025 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5026 return obj->IsTrue();
5027}
5028
5029
5030int64_t Integer::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005031 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5032 if (obj->IsSmi()) {
5033 return i::Smi::cast(*obj)->value();
5034 } else {
5035 return static_cast<int64_t>(obj->Number());
5036 }
5037}
5038
5039
5040int32_t Int32::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005041 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5042 if (obj->IsSmi()) {
5043 return i::Smi::cast(*obj)->value();
5044 } else {
5045 return static_cast<int32_t>(obj->Number());
5046 }
5047}
5048
5049
Steve Block6ded16b2010-05-10 14:33:55 +01005050uint32_t Uint32::Value() const {
Steve Block6ded16b2010-05-10 14:33:55 +01005051 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5052 if (obj->IsSmi()) {
5053 return i::Smi::cast(*obj)->value();
5054 } else {
5055 return static_cast<uint32_t>(obj->Number());
5056 }
5057}
5058
5059
Steve Blocka7e24c12009-10-30 11:49:00 +00005060int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005061 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
5062 return obj->GetInternalFieldCount();
5063}
5064
5065
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005066static bool InternalFieldOK(i::Handle<i::JSObject> obj,
5067 int index,
5068 const char* location) {
5069 return Utils::ApiCheck(index < obj->GetInternalFieldCount(),
5070 location,
5071 "Internal field out of bounds");
5072}
5073
5074
5075Local<Value> v8::Object::SlowGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005076 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005077 const char* location = "v8::Object::GetInternalField()";
5078 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
5079 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
5080 return Utils::ToLocal(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00005081}
5082
5083
5084void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005085 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005086 const char* location = "v8::Object::SetInternalField()";
5087 if (!InternalFieldOK(obj, index, location)) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00005088 i::Handle<i::Object> val = Utils::OpenHandle(*value);
5089 obj->SetInternalField(index, *val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005090 DCHECK_EQ(value, GetInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00005091}
5092
5093
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005094void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5095 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
5096 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5097 if (!InternalFieldOK(obj, index, location)) return NULL;
5098 return DecodeSmiToAligned(obj->GetInternalField(index), location);
Ben Murdochb8e0da22011-05-16 14:20:40 +01005099}
5100
5101
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005102void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5103 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
5104 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5105 if (!InternalFieldOK(obj, index, location)) return;
5106 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
5107 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
Ben Murdochb8e0da22011-05-16 14:20:40 +01005108}
5109
5110
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005111static void* ExternalValue(i::Object* obj) {
5112 // Obscure semantics for undefined, but somehow checked in our unit tests...
5113 if (obj->IsUndefined()) return NULL;
5114 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
5115 return i::Foreign::cast(foreign)->foreign_address();
Steve Blocka7e24c12009-10-30 11:49:00 +00005116}
5117
5118
5119// --- E n v i r o n m e n t ---
5120
Steve Block44f0eee2011-05-26 01:26:41 +01005121
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005122void v8::V8::InitializePlatform(Platform* platform) {
5123 i::V8::InitializePlatform(platform);
Steve Blocka7e24c12009-10-30 11:49:00 +00005124}
5125
5126
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005127void v8::V8::ShutdownPlatform() {
5128 i::V8::ShutdownPlatform();
5129}
5130
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005131v8::Platform* v8::V8::GetCurrentPlatform() {
5132 return i::V8::GetCurrentPlatform();
5133}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005134
5135bool v8::V8::Initialize() {
5136 i::V8::Initialize();
5137 return true;
5138}
5139
5140
5141void v8::V8::SetEntropySource(EntropySource entropy_source) {
5142 base::RandomNumberGenerator::SetEntropySource(entropy_source);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005143}
5144
5145
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005146void v8::V8::SetReturnAddressLocationResolver(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005147 ReturnAddressLocationResolver return_address_resolver) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005148 i::V8::SetReturnAddressLocationResolver(return_address_resolver);
5149}
5150
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005151void v8::V8::SetArrayBufferAllocator(
5152 ArrayBuffer::Allocator* allocator) {
5153 if (!Utils::ApiCheck(i::V8::ArrayBufferAllocator() == NULL,
5154 "v8::V8::SetArrayBufferAllocator",
5155 "ArrayBufferAllocator might only be set once"))
5156 return;
5157 i::V8::SetArrayBufferAllocator(allocator);
5158}
5159
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005160
Steve Blocka7e24c12009-10-30 11:49:00 +00005161bool v8::V8::Dispose() {
5162 i::V8::TearDown();
5163 return true;
5164}
5165
5166
Russell Brenner90bac252010-11-18 13:33:46 -08005167HeapStatistics::HeapStatistics(): total_heap_size_(0),
5168 total_heap_size_executable_(0),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005169 total_physical_size_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01005170 used_heap_size_(0),
5171 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00005172
5173
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005174bool v8::V8::InitializeICU(const char* icu_data_file) {
5175 return i::InitializeICU(icu_data_file);
Steve Block6ded16b2010-05-10 14:33:55 +01005176}
5177
5178
Steve Blocka7e24c12009-10-30 11:49:00 +00005179const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01005180 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00005181}
5182
5183
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005184static i::Handle<i::Context> CreateEnvironment(
5185 i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00005186 v8::ExtensionConfiguration* extensions,
5187 v8::Handle<ObjectTemplate> global_template,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005188 v8::Handle<Value> maybe_global_proxy) {
5189 i::Handle<i::Context> env;
Steve Blocka7e24c12009-10-30 11:49:00 +00005190
5191 // Enter V8 via an ENTER_V8 scope.
Steve Blocka7e24c12009-10-30 11:49:00 +00005192 {
Steve Block44f0eee2011-05-26 01:26:41 +01005193 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005194 v8::Handle<ObjectTemplate> proxy_template = global_template;
5195 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5196 i::Handle<i::FunctionTemplateInfo> global_constructor;
5197
5198 if (!global_template.IsEmpty()) {
5199 // Make sure that the global_template has a constructor.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005200 global_constructor = EnsureConstructor(isolate, *global_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005201
5202 // Create a fresh template for the global proxy object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005203 proxy_template = ObjectTemplate::New(
5204 reinterpret_cast<v8::Isolate*>(isolate));
5205 proxy_constructor = EnsureConstructor(isolate, *proxy_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005206
5207 // Set the global template to be the prototype template of
5208 // global proxy template.
5209 proxy_constructor->set_prototype_template(
5210 *Utils::OpenHandle(*global_template));
5211
5212 // Migrate security handlers from global_template to
5213 // proxy_template. Temporarily removing access check
5214 // information from the global template.
5215 if (!global_constructor->access_check_info()->IsUndefined()) {
5216 proxy_constructor->set_access_check_info(
5217 global_constructor->access_check_info());
5218 proxy_constructor->set_needs_access_check(
5219 global_constructor->needs_access_check());
5220 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01005221 global_constructor->set_access_check_info(
5222 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00005223 }
5224 }
5225
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005226 i::Handle<i::Object> proxy = Utils::OpenHandle(*maybe_global_proxy, true);
5227 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
5228 if (!proxy.is_null()) {
5229 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(proxy);
5230 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005231 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01005232 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005233 maybe_proxy, proxy_template, extensions);
Steve Blocka7e24c12009-10-30 11:49:00 +00005234
5235 // Restore the access check info on the global template.
5236 if (!global_template.IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005237 DCHECK(!global_constructor.is_null());
5238 DCHECK(!proxy_constructor.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00005239 global_constructor->set_access_check_info(
5240 proxy_constructor->access_check_info());
5241 global_constructor->set_needs_access_check(
5242 proxy_constructor->needs_access_check());
5243 }
5244 }
5245 // Leave V8.
5246
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005247 return env;
5248}
5249
5250Local<Context> v8::Context::New(
5251 v8::Isolate* external_isolate,
5252 v8::ExtensionConfiguration* extensions,
5253 v8::Handle<ObjectTemplate> global_template,
5254 v8::Handle<Value> global_object) {
5255 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5256 LOG_API(isolate, "Context::New");
5257 ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
5258 i::HandleScope scope(isolate);
5259 ExtensionConfiguration no_extensions;
5260 if (extensions == NULL) extensions = &no_extensions;
5261 i::Handle<i::Context> env =
5262 CreateEnvironment(isolate, extensions, global_template, global_object);
5263 if (env.is_null()) return Local<Context>();
5264 return Utils::ToLocal(scope.CloseAndEscape(env));
Steve Blocka7e24c12009-10-30 11:49:00 +00005265}
5266
5267
5268void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005269 i::Handle<i::Context> env = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005270 i::Isolate* isolate = env->GetIsolate();
5271 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005272 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
5273 env->set_security_token(*token_handle);
5274}
5275
5276
5277void v8::Context::UseDefaultSecurityToken() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005278 i::Handle<i::Context> env = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005279 i::Isolate* isolate = env->GetIsolate();
5280 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005281 env->set_security_token(env->global_object());
Steve Blocka7e24c12009-10-30 11:49:00 +00005282}
5283
5284
5285Handle<Value> v8::Context::GetSecurityToken() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005286 i::Handle<i::Context> env = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005287 i::Isolate* isolate = env->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +00005288 i::Object* security_token = env->security_token();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005289 i::Handle<i::Object> token_handle(security_token, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005290 return Utils::ToLocal(token_handle);
5291}
5292
5293
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005294v8::Isolate* Context::GetIsolate() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005295 i::Handle<i::Context> env = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005296 return reinterpret_cast<Isolate*>(env->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00005297}
5298
5299
5300v8::Local<v8::Object> Context::Global() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005301 i::Handle<i::Context> context = Utils::OpenHandle(this);
5302 i::Isolate* isolate = context->GetIsolate();
5303 i::Handle<i::Object> global(context->global_proxy(), isolate);
5304 // TODO(dcarney): This should always return the global proxy
5305 // but can't presently as calls to GetProtoype will return the wrong result.
5306 if (i::Handle<i::JSGlobalProxy>::cast(
5307 global)->IsDetachedFrom(context->global_object())) {
5308 global = i::Handle<i::Object>(context->global_object(), isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005309 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005310 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5311}
5312
5313
5314void Context::DetachGlobal() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005315 i::Handle<i::Context> context = Utils::OpenHandle(this);
5316 i::Isolate* isolate = context->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005317 ENTER_V8(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005318 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00005319}
5320
5321
Ben Murdoch257744e2011-11-30 15:57:28 +00005322void Context::AllowCodeGenerationFromStrings(bool allow) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005323 i::Handle<i::Context> context = Utils::OpenHandle(this);
5324 i::Isolate* isolate = context->GetIsolate();
Ben Murdoch257744e2011-11-30 15:57:28 +00005325 ENTER_V8(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005326 context->set_allow_code_gen_from_strings(
5327 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5328}
5329
5330
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005331bool Context::IsCodeGenerationFromStringsAllowed() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005332 i::Handle<i::Context> context = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005333 return !context->allow_code_gen_from_strings()->IsFalse();
5334}
5335
5336
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005337void Context::SetErrorMessageForCodeGenerationFromStrings(
5338 Handle<String> error) {
5339 i::Handle<i::Context> context = Utils::OpenHandle(this);
5340 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
5341 context->set_error_message_for_code_gen_from_strings(*error_handle);
Andrei Popescu74b3c142010-03-29 12:03:09 +01005342}
5343
5344
Steve Blocka7e24c12009-10-30 11:49:00 +00005345Local<v8::Object> ObjectTemplate::NewInstance() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005346 i::Handle<i::ObjectTemplateInfo> info = Utils::OpenHandle(this);
5347 i::Isolate* isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005348 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
5349 return Local<v8::Object>());
5350 LOG_API(isolate, "ObjectTemplate::NewInstance");
5351 ENTER_V8(isolate);
5352 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005353 i::Handle<i::Object> obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005354 has_pending_exception = !i::Execution::InstantiateObject(info).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01005355 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005356 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
5357}
5358
5359
5360Local<v8::Function> FunctionTemplate::GetFunction() {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005361 i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
5362 i::Isolate* isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005363 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00005364 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01005365 LOG_API(isolate, "FunctionTemplate::GetFunction");
5366 ENTER_V8(isolate);
5367 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005368 i::Handle<i::Object> obj;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005369 has_pending_exception =
5370 !i::Execution::InstantiateFunction(info).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01005371 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005372 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
5373}
5374
5375
5376bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005377 i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
5378 i::Isolate* isolate = info->GetIsolate();
5379 ON_BAILOUT(isolate, "v8::FunctionTemplate::HasInstanceOf()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00005380 i::Object* obj = *Utils::OpenHandle(*value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005381 return info->IsTemplateFor(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005382}
5383
5384
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005385Local<External> v8::External::New(Isolate* isolate, void* value) {
5386 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
5387 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5388 LOG_API(i_isolate, "External::New");
5389 ENTER_V8(i_isolate);
5390 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
5391 return Utils::ExternalToLocal(external);
Steve Blocka7e24c12009-10-30 11:49:00 +00005392}
5393
5394
5395void* External::Value() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005396 return ExternalValue(*Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00005397}
5398
5399
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005400// anonymous namespace for string creation helper functions
5401namespace {
5402
5403inline int StringLength(const char* string) {
5404 return i::StrLength(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005405}
5406
5407
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005408inline int StringLength(const uint8_t* string) {
5409 return i::StrLength(reinterpret_cast<const char*>(string));
5410}
5411
5412
5413inline int StringLength(const uint16_t* string) {
5414 int length = 0;
5415 while (string[length] != '\0')
5416 length++;
5417 return length;
5418}
5419
5420
5421MUST_USE_RESULT
5422inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5423 String::NewStringType type,
5424 i::Vector<const char> string) {
5425 if (type == String::kInternalizedString) {
5426 return factory->InternalizeUtf8String(string);
5427 }
5428 return factory->NewStringFromUtf8(string);
5429}
5430
5431
5432MUST_USE_RESULT
5433inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5434 String::NewStringType type,
5435 i::Vector<const uint8_t> string) {
5436 if (type == String::kInternalizedString) {
5437 return factory->InternalizeOneByteString(string);
5438 }
5439 return factory->NewStringFromOneByte(string);
5440}
5441
5442
5443MUST_USE_RESULT
5444inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5445 String::NewStringType type,
5446 i::Vector<const uint16_t> string) {
5447 if (type == String::kInternalizedString) {
5448 return factory->InternalizeTwoByteString(string);
5449 }
5450 return factory->NewStringFromTwoByte(string);
5451}
5452
5453
5454template<typename Char>
5455inline Local<String> NewString(Isolate* v8_isolate,
5456 const char* location,
5457 const char* env,
5458 const Char* data,
5459 String::NewStringType type,
5460 int length) {
5461 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
5462 LOG_API(isolate, env);
5463 if (length == 0 && type != String::kUndetectableString) {
5464 return String::Empty(v8_isolate);
5465 }
Steve Block44f0eee2011-05-26 01:26:41 +01005466 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005467 if (length == -1) length = StringLength(data);
5468 // We do not expect this to fail. Change this if it does.
5469 i::Handle<i::String> result = NewString(
5470 isolate->factory(),
5471 type,
5472 i::Vector<const Char>(data, length)).ToHandleChecked();
5473 if (type == String::kUndetectableString) {
5474 result->MarkAsUndetectable();
5475 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005476 return Utils::ToLocal(result);
5477}
5478
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005479} // anonymous namespace
5480
5481
5482Local<String> String::NewFromUtf8(Isolate* isolate,
5483 const char* data,
5484 NewStringType type,
5485 int length) {
5486 return NewString(isolate,
5487 "v8::String::NewFromUtf8()",
5488 "String::NewFromUtf8",
5489 data,
5490 type,
5491 length);
5492}
5493
5494
5495Local<String> String::NewFromOneByte(Isolate* isolate,
5496 const uint8_t* data,
5497 NewStringType type,
5498 int length) {
5499 return NewString(isolate,
5500 "v8::String::NewFromOneByte()",
5501 "String::NewFromOneByte",
5502 data,
5503 type,
5504 length);
5505}
5506
5507
5508Local<String> String::NewFromTwoByte(Isolate* isolate,
5509 const uint16_t* data,
5510 NewStringType type,
5511 int length) {
5512 return NewString(isolate,
5513 "v8::String::NewFromTwoByte()",
5514 "String::NewFromTwoByte",
5515 data,
5516 type,
5517 length);
5518}
5519
Steve Blocka7e24c12009-10-30 11:49:00 +00005520
Steve Block3ce2e202009-11-05 08:53:23 +00005521Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00005522 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01005523 i::Isolate* isolate = left_string->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005524 LOG_API(isolate, "String::New(char)");
5525 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00005526 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005527 // If we are steering towards a range error, do not wait for the error to be
5528 // thrown, and return the null handle instead.
5529 if (left_string->length() + right_string->length() > i::String::kMaxLength) {
5530 return Local<String>();
5531 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005532 i::Handle<i::String> result = isolate->factory()->NewConsString(
5533 left_string, right_string).ToHandleChecked();
Steve Block3ce2e202009-11-05 08:53:23 +00005534 return Utils::ToLocal(result);
5535}
5536
5537
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005538static i::MaybeHandle<i::String> NewExternalStringHandle(
5539 i::Isolate* isolate, v8::String::ExternalStringResource* resource) {
5540 return isolate->factory()->NewExternalStringFromTwoByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00005541}
5542
5543
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005544static i::MaybeHandle<i::String> NewExternalOneByteStringHandle(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005545 i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005546 return isolate->factory()->NewExternalStringFromOneByte(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00005547}
5548
5549
Steve Blocka7e24c12009-10-30 11:49:00 +00005550Local<String> v8::String::NewExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005551 Isolate* isolate,
5552 v8::String::ExternalStringResource* resource) {
5553 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5554 LOG_API(i_isolate, "String::NewExternal");
5555 ENTER_V8(i_isolate);
5556 CHECK(resource && resource->data());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005557 EXCEPTION_PREAMBLE(i_isolate);
5558 i::Handle<i::String> string;
5559 has_pending_exception =
5560 !NewExternalStringHandle(i_isolate, resource).ToHandle(&string);
5561 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
5562 i_isolate->heap()->external_string_table()->AddString(*string);
5563 return Utils::ToLocal(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005564}
5565
5566
5567bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005568 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005569 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005570 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005571 return false; // Already an external string.
5572 }
5573 ENTER_V8(isolate);
5574 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5575 return false;
5576 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005577 if (isolate->heap()->IsInGCPostProcessing()) {
5578 return false;
5579 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005580 CHECK(resource && resource->data());
5581
Steve Blocka7e24c12009-10-30 11:49:00 +00005582 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005583 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5584 DCHECK(!CanMakeExternal() || result);
5585 if (result) {
5586 DCHECK(obj->IsExternalString());
Steve Block44f0eee2011-05-26 01:26:41 +01005587 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005588 }
5589 return result;
5590}
5591
5592
5593Local<String> v8::String::NewExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005594 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5595 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5596 LOG_API(i_isolate, "String::NewExternal");
5597 ENTER_V8(i_isolate);
5598 CHECK(resource && resource->data());
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005599 EXCEPTION_PREAMBLE(i_isolate);
5600 i::Handle<i::String> string;
5601 has_pending_exception =
5602 !NewExternalOneByteStringHandle(i_isolate, resource).ToHandle(&string);
5603 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
5604 i_isolate->heap()->external_string_table()->AddString(*string);
5605 return Utils::ToLocal(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005606}
5607
5608
5609bool v8::String::MakeExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005610 v8::String::ExternalOneByteStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005611 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005612 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005613 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005614 return false; // Already an external string.
5615 }
5616 ENTER_V8(isolate);
5617 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5618 return false;
5619 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005620 if (isolate->heap()->IsInGCPostProcessing()) {
5621 return false;
5622 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005623 CHECK(resource && resource->data());
5624
Steve Blocka7e24c12009-10-30 11:49:00 +00005625 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005626 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5627 DCHECK(!CanMakeExternal() || result);
5628 if (result) {
5629 DCHECK(obj->IsExternalString());
Steve Block44f0eee2011-05-26 01:26:41 +01005630 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005631 }
5632 return result;
5633}
5634
5635
5636bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005637 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005638 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005639
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005640 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00005641 int size = obj->Size(); // Byte size of the original string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005642 if (size < i::ExternalString::kShortSize) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00005643 i::StringShape shape(*obj);
5644 return !shape.IsExternal();
5645}
5646
5647
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005648Isolate* v8::Object::GetIsolate() {
5649 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
5650 return reinterpret_cast<Isolate*>(i_isolate);
5651}
5652
5653
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005654Local<v8::Object> v8::Object::New(Isolate* isolate) {
5655 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5656 LOG_API(i_isolate, "Object::New");
5657 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005658 i::Handle<i::JSObject> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005659 i_isolate->factory()->NewJSObject(i_isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00005660 return Utils::ToLocal(obj);
5661}
5662
5663
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005664Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
5665 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5666 LOG_API(i_isolate, "NumberObject::New");
5667 ENTER_V8(i_isolate);
5668 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
5669 i::Handle<i::Object> obj =
5670 i::Object::ToObject(i_isolate, number).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005671 return Utils::ToLocal(obj);
5672}
5673
5674
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005675double v8::NumberObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005676 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5677 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005678 i::Isolate* isolate = jsvalue->GetIsolate();
5679 LOG_API(isolate, "NumberObject::NumberValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005680 return jsvalue->value()->Number();
5681}
5682
5683
5684Local<v8::Value> v8::BooleanObject::New(bool value) {
5685 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005686 LOG_API(isolate, "BooleanObject::New");
5687 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005688 i::Handle<i::Object> boolean(value
5689 ? isolate->heap()->true_value()
5690 : isolate->heap()->false_value(),
5691 isolate);
5692 i::Handle<i::Object> obj =
5693 i::Object::ToObject(isolate, boolean).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005694 return Utils::ToLocal(obj);
5695}
5696
5697
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005698bool v8::BooleanObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005699 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5700 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005701 i::Isolate* isolate = jsvalue->GetIsolate();
5702 LOG_API(isolate, "BooleanObject::BooleanValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005703 return jsvalue->value()->IsTrue();
5704}
5705
5706
5707Local<v8::Value> v8::StringObject::New(Handle<String> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005708 i::Handle<i::String> string = Utils::OpenHandle(*value);
5709 i::Isolate* isolate = string->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005710 LOG_API(isolate, "StringObject::New");
5711 ENTER_V8(isolate);
5712 i::Handle<i::Object> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005713 i::Object::ToObject(isolate, string).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005714 return Utils::ToLocal(obj);
5715}
5716
5717
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005718Local<v8::String> v8::StringObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005719 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5720 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005721 i::Isolate* isolate = jsvalue->GetIsolate();
5722 LOG_API(isolate, "StringObject::StringValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005723 return Utils::ToLocal(
5724 i::Handle<i::String>(i::String::cast(jsvalue->value())));
5725}
5726
5727
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005728Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
5729 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5730 LOG_API(i_isolate, "SymbolObject::New");
5731 ENTER_V8(i_isolate);
5732 i::Handle<i::Object> obj = i::Object::ToObject(
5733 i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00005734 return Utils::ToLocal(obj);
5735}
5736
5737
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005738Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
5739 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5740 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5741 i::Isolate* isolate = jsvalue->GetIsolate();
5742 LOG_API(isolate, "SymbolObject::SymbolValue");
5743 return Utils::ToLocal(
5744 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
5745}
5746
5747
5748Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
5749 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5750 LOG_API(i_isolate, "Date::New");
5751 if (std::isnan(time)) {
5752 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5753 time = base::OS::nan_value();
5754 }
5755 ENTER_V8(i_isolate);
5756 EXCEPTION_PREAMBLE(i_isolate);
5757 i::Handle<i::Object> obj;
5758 has_pending_exception = !i::Execution::NewDate(
5759 i_isolate, time).ToHandle(&obj);
5760 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::Value>());
5761 return Utils::ToLocal(obj);
5762}
5763
5764
5765double v8::Date::ValueOf() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005766 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005767 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005768 i::Isolate* isolate = jsdate->GetIsolate();
5769 LOG_API(isolate, "Date::NumberValue");
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005770 return jsdate->value()->Number();
Steve Blocka7e24c12009-10-30 11:49:00 +00005771}
5772
5773
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005774void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
5775 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005776 ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
Steve Block44f0eee2011-05-26 01:26:41 +01005777 return);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005778 LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
5779 ENTER_V8(i_isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005780
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005781 i_isolate->date_cache()->ResetDateCache();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005782
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005783 if (!i_isolate->eternal_handles()->Exists(
5784 i::EternalHandles::DATE_CACHE_VERSION)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005785 return;
5786 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005787 i::Handle<i::FixedArray> date_cache_version =
5788 i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
5789 i::EternalHandles::DATE_CACHE_VERSION));
5790 DCHECK_EQ(1, date_cache_version->length());
5791 CHECK(date_cache_version->get(0)->IsSmi());
5792 date_cache_version->set(
5793 0,
5794 i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005795}
5796
5797
Ben Murdochf87a2032010-10-22 12:50:53 +01005798static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005799 i::Isolate* isolate = i::Isolate::Current();
5800 uint8_t flags_buf[3];
Ben Murdochf87a2032010-10-22 12:50:53 +01005801 int num_flags = 0;
5802 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
5803 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
5804 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005805 DCHECK(num_flags <= static_cast<int>(arraysize(flags_buf)));
5806 return isolate->factory()->InternalizeOneByteString(
5807 i::Vector<const uint8_t>(flags_buf, num_flags));
Ben Murdochf87a2032010-10-22 12:50:53 +01005808}
5809
5810
5811Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
5812 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01005813 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005814 LOG_API(isolate, "RegExp::New");
5815 ENTER_V8(isolate);
5816 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005817 i::Handle<i::JSRegExp> obj;
5818 has_pending_exception = !i::Execution::NewJSRegExp(
Ben Murdochf87a2032010-10-22 12:50:53 +01005819 Utils::OpenHandle(*pattern),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005820 RegExpFlagsToString(flags)).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01005821 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01005822 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
5823}
5824
5825
5826Local<v8::String> v8::RegExp::GetSource() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01005827 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5828 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
5829}
5830
5831
5832// Assert that the static flags cast in GetFlags is valid.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005833#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
5834 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
Ben Murdochf87a2032010-10-22 12:50:53 +01005835 static_cast<int>(i::JSRegExp::internal_flag))
5836REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
5837REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
5838REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
5839REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
5840#undef REGEXP_FLAG_ASSERT_EQ
5841
5842v8::RegExp::Flags v8::RegExp::GetFlags() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01005843 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5844 return static_cast<RegExp::Flags>(obj->GetFlags().value());
5845}
5846
5847
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005848Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
5849 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5850 LOG_API(i_isolate, "Array::New");
5851 ENTER_V8(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005852 int real_length = length > 0 ? length : 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005853 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01005854 i::Handle<i::Object> length_obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005855 i_isolate->factory()->NewNumberFromInt(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01005856 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005857 return Utils::ToLocal(obj);
5858}
5859
5860
5861uint32_t v8::Array::Length() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005862 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
5863 i::Object* length = obj->length();
5864 if (length->IsSmi()) {
5865 return i::Smi::cast(length)->value();
5866 } else {
5867 return static_cast<uint32_t>(length->Number());
5868 }
5869}
5870
5871
5872Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005873 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
5874 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005875 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005876 if (!self->HasFastObjectElements()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005877 return Local<Object>();
5878 }
5879 i::FixedArray* elms = i::FixedArray::cast(self->elements());
5880 i::Object* paragon = elms->get(index);
5881 if (!paragon->IsJSObject()) {
5882 return Local<Object>();
5883 }
5884 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01005885 EXCEPTION_PREAMBLE(isolate);
5886 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005887 i::Handle<i::JSObject> result =
5888 isolate->factory()->CopyJSObject(paragon_handle);
Steve Blocka7e24c12009-10-30 11:49:00 +00005889 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01005890 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005891 return Utils::ToLocal(result);
5892}
5893
5894
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005895bool Value::IsPromise() const {
5896 i::Handle<i::Object> val = Utils::OpenHandle(this);
5897 if (!val->IsJSObject()) return false;
5898 i::Handle<i::JSObject> obj = i::Handle<i::JSObject>::cast(val);
5899 i::Isolate* isolate = obj->GetIsolate();
5900 LOG_API(isolate, "IsPromise");
Steve Block44f0eee2011-05-26 01:26:41 +01005901 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005902 EXCEPTION_PREAMBLE(isolate);
5903 i::Handle<i::Object> argv[] = { obj };
5904 i::Handle<i::Object> b;
5905 has_pending_exception = !i::Execution::Call(
5906 isolate,
5907 isolate->is_promise(),
5908 isolate->factory()->undefined_value(),
5909 arraysize(argv), argv,
5910 false).ToHandle(&b);
5911 EXCEPTION_BAILOUT_CHECK(isolate, false);
5912 return b->BooleanValue();
5913}
5914
5915
5916Local<Promise::Resolver> Promise::Resolver::New(Isolate* v8_isolate) {
5917 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5918 LOG_API(isolate, "Promise::Resolver::New");
5919 ENTER_V8(isolate);
5920 EXCEPTION_PREAMBLE(isolate);
5921 i::Handle<i::Object> result;
5922 has_pending_exception = !i::Execution::Call(
5923 isolate,
5924 isolate->promise_create(),
5925 isolate->factory()->undefined_value(),
5926 0, NULL,
5927 false).ToHandle(&result);
5928 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise::Resolver>());
5929 return Local<Promise::Resolver>::Cast(Utils::ToLocal(result));
5930}
5931
5932
5933Local<Promise> Promise::Resolver::GetPromise() {
5934 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5935 return Local<Promise>::Cast(Utils::ToLocal(promise));
5936}
5937
5938
5939void Promise::Resolver::Resolve(Handle<Value> value) {
5940 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5941 i::Isolate* isolate = promise->GetIsolate();
5942 LOG_API(isolate, "Promise::Resolver::Resolve");
5943 ENTER_V8(isolate);
5944 EXCEPTION_PREAMBLE(isolate);
5945 i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
5946 has_pending_exception = i::Execution::Call(
5947 isolate,
5948 isolate->promise_resolve(),
5949 isolate->factory()->undefined_value(),
5950 arraysize(argv), argv,
5951 false).is_null();
5952 EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
5953}
5954
5955
5956void Promise::Resolver::Reject(Handle<Value> value) {
5957 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5958 i::Isolate* isolate = promise->GetIsolate();
5959 LOG_API(isolate, "Promise::Resolver::Reject");
5960 ENTER_V8(isolate);
5961 EXCEPTION_PREAMBLE(isolate);
5962 i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
5963 has_pending_exception = i::Execution::Call(
5964 isolate,
5965 isolate->promise_reject(),
5966 isolate->factory()->undefined_value(),
5967 arraysize(argv), argv,
5968 false).is_null();
5969 EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
5970}
5971
5972
5973Local<Promise> Promise::Chain(Handle<Function> handler) {
5974 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5975 i::Isolate* isolate = promise->GetIsolate();
5976 LOG_API(isolate, "Promise::Chain");
5977 ENTER_V8(isolate);
5978 EXCEPTION_PREAMBLE(isolate);
5979 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5980 i::Handle<i::Object> result;
5981 has_pending_exception = !i::Execution::Call(
5982 isolate,
5983 isolate->promise_chain(),
5984 promise,
5985 arraysize(argv), argv,
5986 false).ToHandle(&result);
5987 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
5988 return Local<Promise>::Cast(Utils::ToLocal(result));
5989}
5990
5991
5992Local<Promise> Promise::Catch(Handle<Function> handler) {
5993 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5994 i::Isolate* isolate = promise->GetIsolate();
5995 LOG_API(isolate, "Promise::Catch");
5996 ENTER_V8(isolate);
5997 EXCEPTION_PREAMBLE(isolate);
5998 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5999 i::Handle<i::Object> result;
6000 has_pending_exception = !i::Execution::Call(
6001 isolate,
6002 isolate->promise_catch(),
6003 promise,
6004 arraysize(argv), argv,
6005 false).ToHandle(&result);
6006 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
6007 return Local<Promise>::Cast(Utils::ToLocal(result));
6008}
6009
6010
6011Local<Promise> Promise::Then(Handle<Function> handler) {
6012 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
6013 i::Isolate* isolate = promise->GetIsolate();
6014 LOG_API(isolate, "Promise::Then");
6015 ENTER_V8(isolate);
6016 EXCEPTION_PREAMBLE(isolate);
6017 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
6018 i::Handle<i::Object> result;
6019 has_pending_exception = !i::Execution::Call(
6020 isolate,
6021 isolate->promise_then(),
6022 promise,
6023 arraysize(argv), argv,
6024 false).ToHandle(&result);
6025 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
6026 return Local<Promise>::Cast(Utils::ToLocal(result));
6027}
6028
6029
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006030bool Promise::HasHandler() {
6031 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
6032 i::Isolate* isolate = promise->GetIsolate();
6033 LOG_API(isolate, "Promise::HasRejectHandler");
6034 ENTER_V8(isolate);
6035 i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol();
6036 return i::JSObject::GetDataProperty(promise, key)->IsTrue();
6037}
6038
6039
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006040bool v8::ArrayBuffer::IsExternal() const {
6041 return Utils::OpenHandle(this)->is_external();
6042}
6043
6044
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006045bool v8::ArrayBuffer::IsNeuterable() const {
6046 return Utils::OpenHandle(this)->is_neuterable();
6047}
6048
6049
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006050v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
6051 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6052 Utils::ApiCheck(!obj->is_external(),
6053 "v8::ArrayBuffer::Externalize",
6054 "ArrayBuffer already externalized");
6055 obj->set_is_external(true);
6056 size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
6057 Contents contents;
6058 contents.data_ = obj->backing_store();
6059 contents.byte_length_ = byte_length;
6060 return contents;
6061}
6062
6063
6064void v8::ArrayBuffer::Neuter() {
6065 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6066 i::Isolate* isolate = obj->GetIsolate();
6067 Utils::ApiCheck(obj->is_external(),
6068 "v8::ArrayBuffer::Neuter",
6069 "Only externalized ArrayBuffers can be neutered");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006070 Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
6071 "Only neuterable ArrayBuffers can be neutered");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006072 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
6073 ENTER_V8(isolate);
6074 i::Runtime::NeuterArrayBuffer(obj);
6075}
6076
6077
6078size_t v8::ArrayBuffer::ByteLength() const {
6079 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6080 return static_cast<size_t>(obj->byte_length()->Number());
6081}
6082
6083
6084Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
6085 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6086 LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
6087 ENTER_V8(i_isolate);
6088 i::Handle<i::JSArrayBuffer> obj =
6089 i_isolate->factory()->NewJSArrayBuffer();
6090 i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length);
6091 return Utils::ToLocal(obj);
6092}
6093
6094
6095Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
6096 size_t byte_length) {
6097 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6098 LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
6099 ENTER_V8(i_isolate);
6100 i::Handle<i::JSArrayBuffer> obj =
6101 i_isolate->factory()->NewJSArrayBuffer();
6102 i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
6103 return Utils::ToLocal(obj);
6104}
6105
6106
6107Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
6108 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6109 i::Handle<i::JSArrayBuffer> buffer;
6110 if (obj->IsJSDataView()) {
6111 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj));
6112 DCHECK(data_view->buffer()->IsJSArrayBuffer());
6113 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()));
6114 } else {
6115 DCHECK(obj->IsJSTypedArray());
6116 buffer = i::JSTypedArray::cast(*obj)->GetBuffer();
6117 }
6118 return Utils::ToLocal(buffer);
6119}
6120
6121
6122size_t v8::ArrayBufferView::ByteOffset() {
6123 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6124 return static_cast<size_t>(obj->byte_offset()->Number());
6125}
6126
6127
6128size_t v8::ArrayBufferView::ByteLength() {
6129 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6130 return static_cast<size_t>(obj->byte_length()->Number());
6131}
6132
6133
6134size_t v8::TypedArray::Length() {
6135 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
6136 return static_cast<size_t>(obj->length()->Number());
6137}
6138
6139
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006140#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
6141 Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006142 size_t byte_offset, size_t length) { \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006143 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
6144 LOG_API(isolate, \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006145 "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006146 ENTER_V8(isolate); \
6147 if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006148 "v8::" #Type \
6149 "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \
6150 "length exceeds max allowed value")) { \
6151 return Local<Type##Array>(); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006152 } \
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006153 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
6154 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
6155 v8::kExternal##Type##Array, buffer, byte_offset, length); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006156 return Utils::ToLocal##Type##Array(obj); \
6157 }
6158
6159
6160TYPED_ARRAYS(TYPED_ARRAY_NEW)
6161#undef TYPED_ARRAY_NEW
6162
6163Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
6164 size_t byte_offset, size_t byte_length) {
6165 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6166 i::Isolate* isolate = buffer->GetIsolate();
6167 LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
6168 ENTER_V8(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006169 i::Handle<i::JSDataView> obj =
6170 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006171 return Utils::ToLocal(obj);
6172}
6173
6174
6175Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
6176 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6177 LOG_API(i_isolate, "Symbol::New()");
6178 ENTER_V8(i_isolate);
6179 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6180 if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
Steve Blocka7e24c12009-10-30 11:49:00 +00006181 return Utils::ToLocal(result);
6182}
6183
6184
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006185static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
6186 i::Handle<i::String> name,
6187 i::Handle<i::String> part) {
6188 i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
6189 i::Handle<i::JSObject> symbols =
6190 i::Handle<i::JSObject>::cast(
6191 i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6192 i::Handle<i::Object> symbol =
6193 i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
6194 if (!symbol->IsSymbol()) {
6195 DCHECK(symbol->IsUndefined());
6196 symbol = isolate->factory()->NewSymbol();
6197 i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
6198 i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert();
Steve Blockd0582a62009-12-15 09:54:21 +00006199 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006200 return i::Handle<i::Symbol>::cast(symbol);
6201}
6202
6203
6204Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
6205 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6206 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6207 i::Handle<i::String> part = i_isolate->factory()->for_string();
6208 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6209}
6210
6211
6212Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
6213 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6214 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6215 i::Handle<i::String> part = i_isolate->factory()->for_api_string();
6216 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6217}
6218
6219
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006220Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006221 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6222 return Utils::ToLocal(i_isolate->factory()->iterator_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006223}
6224
6225
6226Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006227 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6228 return Utils::ToLocal(i_isolate->factory()->unscopables_symbol());
6229}
6230
6231
6232Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) {
6233 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6234 return Utils::ToLocal(i_isolate->factory()->to_string_tag_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006235}
6236
6237
6238Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
6239 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6240 LOG_API(i_isolate, "Private::New()");
6241 ENTER_V8(i_isolate);
6242 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
6243 if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
6244 Local<Symbol> result = Utils::ToLocal(symbol);
6245 return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
6246}
6247
6248
6249Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
6250 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6251 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6252 i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
6253 i::Handle<i::String> part = i_isolate->factory()->private_api_string();
6254 i::Handle<i::JSObject> privates =
6255 i::Handle<i::JSObject>::cast(
6256 i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6257 i::Handle<i::Object> symbol =
6258 i::Object::GetPropertyOrElement(privates, i_name).ToHandleChecked();
6259 if (!symbol->IsSymbol()) {
6260 DCHECK(symbol->IsUndefined());
6261 symbol = i_isolate->factory()->NewPrivateSymbol();
6262 i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
6263 i::JSObject::SetProperty(privates, i_name, symbol, i::STRICT).Assert();
6264 }
6265 Local<Symbol> result = Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
6266 return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
6267}
6268
6269
6270Local<Number> v8::Number::New(Isolate* isolate, double value) {
6271 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006272 if (std::isnan(value)) {
6273 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6274 value = base::OS::nan_value();
6275 }
6276 ENTER_V8(internal_isolate);
6277 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006278 return Utils::NumberToLocal(result);
6279}
6280
6281
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006282Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
6283 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006284 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01006285 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006286 internal_isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00006287 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006288 ENTER_V8(internal_isolate);
6289 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006290 return Utils::IntegerToLocal(result);
6291}
6292
6293
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006294Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
6295 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00006296 bool fits_into_int32_t = (value & (1 << 31)) == 0;
6297 if (fits_into_int32_t) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006298 return Integer::New(isolate, static_cast<int32_t>(value));
Steve Block3ce2e202009-11-05 08:53:23 +00006299 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006300 ENTER_V8(internal_isolate);
6301 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00006302 return Utils::IntegerToLocal(result);
6303}
6304
6305
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006306void Isolate::CollectAllGarbage(const char* gc_reason) {
6307 reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
6308 i::Heap::kNoGCFlags, gc_reason);
Steve Blocka7e24c12009-10-30 11:49:00 +00006309}
6310
6311
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006312HeapProfiler* Isolate::GetHeapProfiler() {
6313 i::HeapProfiler* heap_profiler =
6314 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
6315 return reinterpret_cast<HeapProfiler*>(heap_profiler);
Steve Blocka7e24c12009-10-30 11:49:00 +00006316}
6317
6318
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006319CpuProfiler* Isolate::GetCpuProfiler() {
6320 i::CpuProfiler* cpu_profiler =
6321 reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
6322 return reinterpret_cast<CpuProfiler*>(cpu_profiler);
6323}
6324
6325
6326bool Isolate::InContext() {
6327 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6328 return isolate->context() != NULL;
6329}
6330
6331
6332v8::Local<v8::Context> Isolate::GetCurrentContext() {
6333 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6334 i::Context* context = isolate->context();
6335 if (context == NULL) return Local<Context>();
6336 i::Context* native_context = context->native_context();
6337 if (native_context == NULL) return Local<Context>();
6338 return Utils::ToLocal(i::Handle<i::Context>(native_context));
6339}
6340
6341
6342v8::Local<v8::Context> Isolate::GetCallingContext() {
6343 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6344 i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
6345 if (calling.is_null()) return Local<Context>();
6346 return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
6347}
6348
6349
6350v8::Local<v8::Context> Isolate::GetEnteredContext() {
6351 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6352 i::Handle<i::Object> last =
6353 isolate->handle_scope_implementer()->LastEnteredContext();
6354 if (last.is_null()) return Local<Context>();
6355 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
6356}
6357
6358
6359v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
6360 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6361 ENTER_V8(isolate);
6362 // If we're passed an empty handle, we throw an undefined exception
6363 // to deal more gracefully with out of memory situations.
6364 if (value.IsEmpty()) {
6365 isolate->ScheduleThrow(isolate->heap()->undefined_value());
6366 } else {
6367 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Block44f0eee2011-05-26 01:26:41 +01006368 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006369 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00006370}
6371
6372
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006373void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
6374 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6375 internal_isolate->global_handles()->SetObjectGroupId(
6376 v8::internal::Handle<v8::internal::Object>(object).location(),
6377 id);
Steve Blocka7e24c12009-10-30 11:49:00 +00006378}
6379
6380
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006381void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
6382 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6383 internal_isolate->global_handles()->SetReferenceFromGroup(
6384 id,
6385 v8::internal::Handle<v8::internal::Object>(object).location());
6386}
6387
6388
6389void Isolate::SetReference(internal::Object** parent,
6390 internal::Object** child) {
6391 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6392 i::Object** parent_location =
6393 v8::internal::Handle<v8::internal::Object>(parent).location();
6394 internal_isolate->global_handles()->SetReference(
6395 reinterpret_cast<i::HeapObject**>(parent_location),
6396 v8::internal::Handle<v8::internal::Object>(child).location());
6397}
6398
6399
6400void Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
6401 GCType gc_type) {
6402 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6403 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
6404}
6405
6406
6407void Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
6408 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6409 isolate->heap()->RemoveGCPrologueCallback(callback);
6410}
6411
6412
6413void Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
6414 GCType gc_type) {
6415 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6416 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
6417}
6418
6419
6420void Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
6421 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6422 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00006423}
6424
6425
Steve Block6ded16b2010-05-10 14:33:55 +01006426void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01006427 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006428 isolate->heap()->AddGCPrologueCallback(
6429 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
6430 gc_type,
6431 false);
Steve Block6ded16b2010-05-10 14:33:55 +01006432}
6433
6434
Steve Block6ded16b2010-05-10 14:33:55 +01006435void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01006436 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006437 isolate->heap()->AddGCEpilogueCallback(
6438 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
6439 gc_type,
6440 false);
Steve Block6ded16b2010-05-10 14:33:55 +01006441}
6442
6443
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006444void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
6445 ObjectSpace space,
6446 AllocationAction action) {
6447 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01006448 isolate->memory_allocator()->AddMemoryAllocationCallback(
6449 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01006450}
6451
6452
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006453void Isolate::RemoveMemoryAllocationCallback(
6454 MemoryAllocationCallback callback) {
6455 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01006456 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
6457 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01006458}
6459
6460
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006461void Isolate::TerminateExecution() {
6462 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6463 isolate->stack_guard()->RequestTerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00006464}
6465
6466
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006467bool Isolate::IsExecutionTerminating() {
6468 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6469 return IsExecutionTerminatingCheck(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01006470}
6471
6472
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006473void Isolate::CancelTerminateExecution() {
6474 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6475 isolate->stack_guard()->ClearTerminateExecution();
6476 isolate->CancelTerminateExecution();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006477}
6478
6479
6480void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006481 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6482 isolate->RequestInterrupt(callback, data);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006483}
6484
6485
6486void Isolate::ClearInterrupt() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006487}
6488
6489
6490void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
6491 CHECK(i::FLAG_expose_gc);
6492 if (type == kMinorGarbageCollection) {
6493 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
6494 i::NEW_SPACE, "Isolate::RequestGarbageCollection",
6495 kGCCallbackFlagForced);
6496 } else {
6497 DCHECK_EQ(kFullGarbageCollection, type);
6498 reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
6499 i::Heap::kAbortIncrementalMarkingMask,
6500 "Isolate::RequestGarbageCollection", kGCCallbackFlagForced);
6501 }
6502}
6503
6504
Steve Block44f0eee2011-05-26 01:26:41 +01006505Isolate* Isolate::GetCurrent() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006506 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006507 return reinterpret_cast<Isolate*>(isolate);
6508}
6509
6510
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006511Isolate* Isolate::New(const Isolate::CreateParams& params) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006512 i::Isolate* isolate = new i::Isolate(params.enable_serializer);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006513 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
6514 if (params.entry_hook) {
6515 isolate->set_function_entry_hook(params.entry_hook);
6516 }
6517 if (params.code_event_handler) {
6518 isolate->InitializeLoggingAndCounters();
6519 isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
6520 params.code_event_handler);
6521 }
6522 SetResourceConstraints(isolate, params.constraints);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006523 // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
6524 Isolate::Scope isolate_scope(v8_isolate);
6525 if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
6526 // If the isolate has a function entry hook, it needs to re-build all its
6527 // code stubs with entry hooks embedded, so don't deserialize a snapshot.
6528 isolate->Init(NULL);
6529 }
6530 return v8_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +01006531}
6532
6533
6534void Isolate::Dispose() {
6535 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006536 if (!Utils::ApiCheck(!isolate->IsInUse(),
6537 "v8::Isolate::Dispose()",
6538 "Disposing the isolate that is entered by a thread.")) {
Steve Block44f0eee2011-05-26 01:26:41 +01006539 return;
Steve Block6ded16b2010-05-10 14:33:55 +01006540 }
Steve Block44f0eee2011-05-26 01:26:41 +01006541 isolate->TearDown();
6542}
6543
6544
6545void Isolate::Enter() {
6546 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6547 isolate->Enter();
6548}
6549
6550
6551void Isolate::Exit() {
6552 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6553 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01006554}
6555
6556
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006557Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
6558 Isolate* isolate,
6559 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
6560 : on_failure_(on_failure) {
6561 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6562 if (on_failure_ == CRASH_ON_FAILURE) {
6563 internal_ = reinterpret_cast<void*>(
6564 new i::DisallowJavascriptExecution(i_isolate));
6565 } else {
6566 DCHECK_EQ(THROW_ON_FAILURE, on_failure);
6567 internal_ = reinterpret_cast<void*>(
6568 new i::ThrowOnJavascriptExecution(i_isolate));
6569 }
Ben Murdoch257744e2011-11-30 15:57:28 +00006570}
6571
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006572
6573Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
6574 if (on_failure_ == CRASH_ON_FAILURE) {
6575 delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
6576 } else {
6577 delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
6578 }
6579}
6580
6581
6582Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
6583 Isolate* isolate) {
6584 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6585 internal_assert_ = reinterpret_cast<void*>(
6586 new i::AllowJavascriptExecution(i_isolate));
6587 internal_throws_ = reinterpret_cast<void*>(
6588 new i::NoThrowOnJavascriptExecution(i_isolate));
6589}
6590
6591
6592Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
6593 delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
6594 delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
6595}
6596
6597
6598Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
6599 Isolate* isolate)
6600 : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
6601 isolate_->handle_scope_implementer()->IncrementCallDepth();
6602}
6603
6604
6605Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
6606 isolate_->handle_scope_implementer()->DecrementCallDepth();
6607}
6608
6609
6610void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
Ben Murdoch257744e2011-11-30 15:57:28 +00006611 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006612 i::Heap* heap = isolate->heap();
6613 heap_statistics->total_heap_size_ = heap->CommittedMemory();
6614 heap_statistics->total_heap_size_executable_ =
6615 heap->CommittedMemoryExecutable();
6616 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
6617 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
6618 heap_statistics->heap_size_limit_ = heap->MaxReserved();
6619}
6620
6621
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006622void Isolate::GetStackSample(const RegisterState& state, void** frames,
6623 size_t frames_limit, SampleInfo* sample_info) {
6624 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6625 i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame,
6626 frames, frames_limit, sample_info);
6627}
6628
6629
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006630void Isolate::SetEventLogger(LogEventCallback that) {
6631 // Do not overwrite the event logger if we want to log explicitly.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006632 if (i::FLAG_log_internal_timer_events) return;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006633 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6634 isolate->set_event_logger(that);
6635}
6636
6637
6638void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
6639 if (callback == NULL) return;
6640 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6641 isolate->AddCallCompletedCallback(callback);
6642}
6643
6644
6645void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
6646 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6647 isolate->RemoveCallCompletedCallback(callback);
6648}
6649
6650
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006651void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
6652 if (callback == NULL) return;
6653 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6654 isolate->SetPromiseRejectCallback(callback);
6655}
6656
6657
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006658void Isolate::RunMicrotasks() {
6659 reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
6660}
6661
6662
6663void Isolate::EnqueueMicrotask(Handle<Function> microtask) {
6664 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6665 isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
6666}
6667
6668
6669void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
6670 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6671 i::HandleScope scope(isolate);
6672 i::Handle<i::CallHandlerInfo> callback_info =
6673 i::Handle<i::CallHandlerInfo>::cast(
6674 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE));
6675 SET_FIELD_WRAPPED(callback_info, set_callback, microtask);
6676 SET_FIELD_WRAPPED(callback_info, set_data, data);
6677 isolate->EnqueueMicrotask(callback_info);
6678}
6679
6680
6681void Isolate::SetAutorunMicrotasks(bool autorun) {
6682 reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
6683}
6684
6685
6686bool Isolate::WillAutorunMicrotasks() const {
6687 return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks();
6688}
6689
6690
6691void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
6692 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
6693}
6694
6695
6696void Isolate::SetCounterFunction(CounterLookupCallback callback) {
6697 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6698 isolate->stats_table()->SetCounterFunction(callback);
6699 isolate->InitializeLoggingAndCounters();
6700 isolate->counters()->ResetCounters();
6701}
6702
6703
6704void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
6705 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6706 isolate->stats_table()->SetCreateHistogramFunction(callback);
6707 isolate->InitializeLoggingAndCounters();
6708 isolate->counters()->ResetHistograms();
6709}
6710
6711
6712void Isolate::SetAddHistogramSampleFunction(
6713 AddHistogramSampleCallback callback) {
6714 reinterpret_cast<i::Isolate*>(this)
6715 ->stats_table()
6716 ->SetAddHistogramSampleFunction(callback);
6717}
6718
6719
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006720bool Isolate::IdleNotification(int idle_time_in_ms) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006721 // Returning true tells the caller that it need not
6722 // continue to call IdleNotification.
6723 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6724 if (!i::FLAG_use_idle_notification) return true;
6725 return isolate->heap()->IdleNotification(idle_time_in_ms);
6726}
6727
6728
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006729bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
6730 // Returning true tells the caller that it need not
6731 // continue to call IdleNotification.
6732 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6733 if (!i::FLAG_use_idle_notification) return true;
6734 return isolate->heap()->IdleNotification(deadline_in_seconds);
6735}
6736
6737
6738void Isolate::LowMemoryNotification() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006739 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6740 {
6741 i::HistogramTimerScope idle_notification_scope(
6742 isolate->counters()->gc_low_memory_notification());
6743 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
6744 }
6745}
6746
6747
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006748int Isolate::ContextDisposedNotification(bool dependant_context) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006749 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006750 return isolate->heap()->NotifyContextDisposed(dependant_context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006751}
6752
6753
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006754void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
6755 JitCodeEventHandler event_handler) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006756 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6757 // Ensure that logging is initialized for our isolate.
6758 isolate->InitializeLoggingAndCounters();
6759 isolate->logger()->SetCodeEventHandler(options, event_handler);
6760}
6761
6762
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006763void Isolate::SetStackLimit(uintptr_t stack_limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006764 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6765 CHECK(stack_limit);
6766 isolate->stack_guard()->SetStackLimit(stack_limit);
Ben Murdoch257744e2011-11-30 15:57:28 +00006767}
6768
6769
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006770void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
6771 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6772 if (isolate->code_range()->valid()) {
6773 *start = isolate->code_range()->start();
6774 *length_in_bytes = isolate->code_range()->size();
6775 } else {
6776 *start = NULL;
6777 *length_in_bytes = 0;
6778 }
6779}
6780
6781
6782void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
6783 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6784 isolate->set_exception_behavior(that);
6785}
6786
6787
6788void Isolate::SetAllowCodeGenerationFromStringsCallback(
6789 AllowCodeGenerationFromStringsCallback callback) {
6790 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6791 isolate->set_allow_code_gen_callback(callback);
6792}
6793
6794
6795bool Isolate::IsDead() {
6796 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6797 return isolate->IsDead();
6798}
6799
6800
6801bool Isolate::AddMessageListener(MessageCallback that, Handle<Value> data) {
6802 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6803 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
6804 ENTER_V8(isolate);
6805 i::HandleScope scope(isolate);
6806 NeanderArray listeners(isolate->factory()->message_listeners());
6807 NeanderObject obj(isolate, 2);
6808 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
6809 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
6810 : *Utils::OpenHandle(*data));
6811 listeners.add(isolate, obj.value());
6812 return true;
6813}
6814
6815
6816void Isolate::RemoveMessageListeners(MessageCallback that) {
6817 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6818 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
6819 ENTER_V8(isolate);
6820 i::HandleScope scope(isolate);
6821 NeanderArray listeners(isolate->factory()->message_listeners());
6822 for (int i = 0; i < listeners.length(); i++) {
6823 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
6824
6825 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
6826 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
6827 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
6828 listeners.set(i, isolate->heap()->undefined_value());
6829 }
6830 }
6831}
6832
6833
6834void Isolate::SetFailedAccessCheckCallbackFunction(
6835 FailedAccessCheckCallback callback) {
6836 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6837 isolate->SetFailedAccessCheckCallback(callback);
6838}
6839
6840
6841void Isolate::SetCaptureStackTraceForUncaughtExceptions(
6842 bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
6843 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6844 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
6845 options);
6846}
6847
6848
6849void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
6850 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6851 isolate->heap()->VisitExternalResources(visitor);
6852}
6853
6854
6855class VisitorAdapter : public i::ObjectVisitor {
6856 public:
6857 explicit VisitorAdapter(PersistentHandleVisitor* visitor)
6858 : visitor_(visitor) {}
6859 virtual void VisitPointers(i::Object** start, i::Object** end) {
6860 UNREACHABLE();
6861 }
6862 virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
6863 Value* value = ToApi<Value>(i::Handle<i::Object>(p));
6864 visitor_->VisitPersistentHandle(
6865 reinterpret_cast<Persistent<Value>*>(&value), class_id);
6866 }
6867
6868 private:
6869 PersistentHandleVisitor* visitor_;
6870};
6871
6872
6873void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
6874 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6875 i::DisallowHeapAllocation no_allocation;
6876 VisitorAdapter visitor_adapter(visitor);
6877 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
6878}
6879
6880
6881void Isolate::VisitHandlesForPartialDependence(
6882 PersistentHandleVisitor* visitor) {
6883 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6884 i::DisallowHeapAllocation no_allocation;
6885 VisitorAdapter visitor_adapter(visitor);
6886 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
6887 &visitor_adapter);
6888}
6889
6890
Ben Murdoch257744e2011-11-30 15:57:28 +00006891String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
6892 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01006893 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00006894 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01006895 ENTER_V8(isolate);
6896 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006897 TryCatch try_catch;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006898 Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
Ben Murdoch257744e2011-11-30 15:57:28 +00006899 if (str.IsEmpty()) return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006900 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006901 length_ = v8::Utf8Length(*i_str, isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00006902 str_ = i::NewArray<char>(length_ + 1);
6903 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00006904}
6905
6906
6907String::Utf8Value::~Utf8Value() {
6908 i::DeleteArray(str_);
6909}
6910
6911
Ben Murdoch257744e2011-11-30 15:57:28 +00006912String::Value::Value(v8::Handle<v8::Value> obj)
6913 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01006914 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00006915 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01006916 ENTER_V8(isolate);
6917 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006918 TryCatch try_catch;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006919 Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
Ben Murdoch257744e2011-11-30 15:57:28 +00006920 if (str.IsEmpty()) return;
6921 length_ = str->Length();
6922 str_ = i::NewArray<uint16_t>(length_ + 1);
6923 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00006924}
6925
6926
6927String::Value::~Value() {
6928 i::DeleteArray(str_);
6929}
6930
Steve Blocka7e24c12009-10-30 11:49:00 +00006931
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006932#define DEFINE_ERROR(NAME) \
6933 Local<Value> Exception::NAME(v8::Handle<v8::String> raw_message) { \
6934 i::Isolate* isolate = i::Isolate::Current(); \
6935 LOG_API(isolate, #NAME); \
6936 ON_BAILOUT(isolate, "v8::Exception::" #NAME "()", return Local<Value>()); \
6937 ENTER_V8(isolate); \
6938 i::Object* error; \
6939 { \
6940 i::HandleScope scope(isolate); \
6941 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
6942 i::Handle<i::Object> result; \
6943 EXCEPTION_PREAMBLE(isolate); \
6944 i::MaybeHandle<i::Object> maybe_result = \
6945 isolate->factory()->New##NAME(message); \
6946 has_pending_exception = !maybe_result.ToHandle(&result); \
6947 /* TODO(yangguo): crbug/403509. Return empty handle instead. */ \
6948 EXCEPTION_BAILOUT_CHECK( \
6949 isolate, v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate))); \
6950 error = *result; \
6951 } \
6952 i::Handle<i::Object> result(error, isolate); \
6953 return Utils::ToLocal(result); \
Steve Blocka7e24c12009-10-30 11:49:00 +00006954 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006955
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006956DEFINE_ERROR(RangeError)
6957DEFINE_ERROR(ReferenceError)
6958DEFINE_ERROR(SyntaxError)
6959DEFINE_ERROR(TypeError)
6960DEFINE_ERROR(Error)
Steve Blocka7e24c12009-10-30 11:49:00 +00006961
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006962#undef DEFINE_ERROR
Steve Blocka7e24c12009-10-30 11:49:00 +00006963
6964
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006965Local<Message> Exception::CreateMessage(Handle<Value> exception) {
6966 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
6967 if (!obj->IsHeapObject()) return Local<Message>();
6968 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
6969 ENTER_V8(isolate);
6970 i::HandleScope scope(isolate);
6971 return Utils::MessageToLocal(
6972 scope.CloseAndEscape(isolate->CreateMessage(obj, NULL)));
6973}
6974
6975
6976Local<StackTrace> Exception::GetStackTrace(Handle<Value> exception) {
6977 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
6978 if (!obj->IsJSObject()) return Local<StackTrace>();
6979 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
6980 i::Isolate* isolate = js_obj->GetIsolate();
6981 ENTER_V8(isolate);
6982 return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
6983}
6984
6985
Steve Blocka7e24c12009-10-30 11:49:00 +00006986// --- D e b u g S u p p o r t ---
6987
Steve Blocka7e24c12009-10-30 11:49:00 +00006988bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01006989 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006990 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
6991 ENTER_V8(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01006992 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00006993 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00006994 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00006995 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00006996 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006997 isolate->debug()->SetEventListener(foreign,
6998 Utils::OpenHandle(*data, true));
Steve Blocka7e24c12009-10-30 11:49:00 +00006999 return true;
7000}
7001
7002
Steve Block44f0eee2011-05-26 01:26:41 +01007003void Debug::DebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007004 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
Steve Blocka7e24c12009-10-30 11:49:00 +00007005}
7006
7007
Steve Block44f0eee2011-05-26 01:26:41 +01007008void Debug::CancelDebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007009 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7010 internal_isolate->stack_guard()->ClearDebugBreak();
Ben Murdochf87a2032010-10-22 12:50:53 +01007011}
7012
7013
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007014bool Debug::CheckDebugBreak(Isolate* isolate) {
7015 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7016 return internal_isolate->stack_guard()->CheckDebugBreak();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007017}
7018
7019
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007020void Debug::DebugBreakForCommand(Isolate* isolate, ClientData* data) {
7021 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7022 internal_isolate->debug()->EnqueueDebugCommand(data);
7023}
7024
7025
7026void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01007027 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01007028 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007029 isolate->debug()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00007030}
7031
7032
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007033void Debug::SendCommand(Isolate* isolate,
7034 const uint16_t* command,
7035 int length,
7036 ClientData* client_data) {
7037 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7038 internal_isolate->debug()->EnqueueCommandMessage(
7039 i::Vector<const uint16_t>(command, length), client_data);
Steve Blockd0582a62009-12-15 09:54:21 +00007040}
7041
7042
Steve Blocka7e24c12009-10-30 11:49:00 +00007043Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
7044 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01007045 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01007046 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
7047 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007048 i::MaybeHandle<i::Object> maybe_result;
Steve Block44f0eee2011-05-26 01:26:41 +01007049 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00007050 if (data.IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007051 maybe_result = isolate->debug()->Call(
7052 Utils::OpenHandle(*fun), isolate->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00007053 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007054 maybe_result = isolate->debug()->Call(
7055 Utils::OpenHandle(*fun), Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00007056 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007057 i::Handle<i::Object> result;
7058 has_pending_exception = !maybe_result.ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01007059 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00007060 return Utils::ToLocal(result);
7061}
7062
7063
7064Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01007065 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01007066 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
7067 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007068 v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Block44f0eee2011-05-26 01:26:41 +01007069 i::Debug* isolate_debug = isolate->debug();
Steve Block44f0eee2011-05-26 01:26:41 +01007070 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007071 has_pending_exception = !isolate_debug->Load();
7072 v8::Local<v8::Value> result;
7073 if (!has_pending_exception) {
7074 i::Handle<i::JSObject> debug(
7075 isolate_debug->debug_context()->global_object());
7076 i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
7077 STATIC_CHAR_VECTOR("MakeMirror"));
7078 i::Handle<i::Object> fun_obj =
7079 i::Object::GetProperty(debug, name).ToHandleChecked();
7080 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
7081 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
7082 const int kArgc = 1;
7083 v8::Handle<v8::Value> argv[kArgc] = { obj };
7084 result = v8_fun->Call(Utils::ToLocal(debug), kArgc, argv);
7085 has_pending_exception = result.IsEmpty();
7086 }
Steve Block44f0eee2011-05-26 01:26:41 +01007087 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007088 return scope.Escape(result);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007089}
7090
7091
Leon Clarkee46be812010-01-19 14:06:41 +00007092void Debug::ProcessDebugMessages() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007093 i::Isolate::Current()->debug()->ProcessDebugMessages(true);
Leon Clarkee46be812010-01-19 14:06:41 +00007094}
7095
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007096
Steve Block6ded16b2010-05-10 14:33:55 +01007097Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01007098 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01007099 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007100 return Utils::ToLocal(i::Isolate::Current()->debug()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01007101}
7102
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007103
7104void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
7105 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7106 internal_isolate->debug()->set_live_edit_enabled(enable);
7107}
Steve Blocka7e24c12009-10-30 11:49:00 +00007108
Steve Block6ded16b2010-05-10 14:33:55 +01007109
Steve Block6ded16b2010-05-10 14:33:55 +01007110Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007111 i::Isolate* isolate = i::Isolate::Current();
Steve Block6ded16b2010-05-10 14:33:55 +01007112 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7113 const i::CodeEntry* entry = node->entry();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007114 i::Handle<i::String> name =
7115 isolate->factory()->InternalizeUtf8String(entry->name());
Steve Block6ded16b2010-05-10 14:33:55 +01007116 if (!entry->has_name_prefix()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007117 return ToApiHandle<String>(name);
Steve Block6ded16b2010-05-10 14:33:55 +01007118 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007119 // We do not expect this to fail. Change this if it does.
7120 i::Handle<i::String> cons = isolate->factory()->NewConsString(
7121 isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
7122 name).ToHandleChecked();
7123 return ToApiHandle<String>(cons);
Steve Block6ded16b2010-05-10 14:33:55 +01007124 }
7125}
7126
7127
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007128int CpuProfileNode::GetScriptId() const {
7129 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7130 const i::CodeEntry* entry = node->entry();
7131 return entry->script_id();
7132}
7133
7134
Steve Block6ded16b2010-05-10 14:33:55 +01007135Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007136 i::Isolate* isolate = i::Isolate::Current();
Steve Block6ded16b2010-05-10 14:33:55 +01007137 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007138 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
7139 node->entry()->resource_name()));
Steve Block6ded16b2010-05-10 14:33:55 +01007140}
7141
7142
7143int CpuProfileNode::GetLineNumber() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007144 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
7145}
7146
7147
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007148int CpuProfileNode::GetColumnNumber() const {
7149 return reinterpret_cast<const i::ProfileNode*>(this)->
7150 entry()->column_number();
Steve Block6ded16b2010-05-10 14:33:55 +01007151}
7152
7153
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007154unsigned int CpuProfileNode::GetHitLineCount() const {
7155 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7156 return node->GetHitLineCount();
7157}
7158
7159
7160bool CpuProfileNode::GetLineTicks(LineTick* entries,
7161 unsigned int length) const {
7162 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7163 return node->GetLineTicks(entries, length);
7164}
7165
7166
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007167const char* CpuProfileNode::GetBailoutReason() const {
7168 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7169 return node->entry()->bailout_reason();
Steve Block6ded16b2010-05-10 14:33:55 +01007170}
7171
7172
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007173unsigned CpuProfileNode::GetHitCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007174 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
7175}
7176
7177
7178unsigned CpuProfileNode::GetCallUid() const {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007179 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01007180}
7181
7182
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007183unsigned CpuProfileNode::GetNodeId() const {
7184 return reinterpret_cast<const i::ProfileNode*>(this)->id();
7185}
7186
7187
Steve Block6ded16b2010-05-10 14:33:55 +01007188int CpuProfileNode::GetChildrenCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007189 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
7190}
7191
7192
7193const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block6ded16b2010-05-10 14:33:55 +01007194 const i::ProfileNode* child =
7195 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
7196 return reinterpret_cast<const CpuProfileNode*>(child);
7197}
7198
7199
Steve Block44f0eee2011-05-26 01:26:41 +01007200void CpuProfile::Delete() {
7201 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007202 i::CpuProfiler* profiler = isolate->cpu_profiler();
7203 DCHECK(profiler != NULL);
7204 profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
Steve Block6ded16b2010-05-10 14:33:55 +01007205}
7206
7207
7208Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007209 i::Isolate* isolate = i::Isolate::Current();
Steve Block6ded16b2010-05-10 14:33:55 +01007210 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007211 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
7212 profile->title()));
Steve Block6ded16b2010-05-10 14:33:55 +01007213}
7214
7215
7216const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007217 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7218 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
7219}
7220
7221
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007222const CpuProfileNode* CpuProfile::GetSample(int index) const {
7223 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7224 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
Steve Block6ded16b2010-05-10 14:33:55 +01007225}
7226
7227
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007228int64_t CpuProfile::GetSampleTimestamp(int index) const {
7229 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7230 return (profile->sample_timestamp(index) - base::TimeTicks())
7231 .InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01007232}
7233
7234
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007235int64_t CpuProfile::GetStartTime() const {
7236 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7237 return (profile->start_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01007238}
7239
7240
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007241int64_t CpuProfile::GetEndTime() const {
7242 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7243 return (profile->end_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01007244}
7245
7246
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007247int CpuProfile::GetSamplesCount() const {
7248 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
7249}
7250
7251
7252void CpuProfiler::SetSamplingInterval(int us) {
7253 DCHECK(us >= 0);
7254 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
7255 base::TimeDelta::FromMicroseconds(us));
7256}
7257
7258
7259void CpuProfiler::StartProfiling(Handle<String> title, bool record_samples) {
7260 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
7261 *Utils::OpenHandle(*title), record_samples);
7262}
7263
7264
7265void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
7266 StartProfiling(title, record_samples);
7267}
7268
7269
7270CpuProfile* CpuProfiler::StopProfiling(Handle<String> title) {
7271 return reinterpret_cast<CpuProfile*>(
7272 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
Leon Clarkef7060e22010-06-03 12:02:55 +01007273 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01007274}
7275
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007276
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007277const CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title) {
7278 return StopProfiling(title);
7279}
7280
7281
7282void CpuProfiler::SetIdle(bool is_idle) {
7283 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007284 v8::StateTag state = isolate->current_vm_state();
7285 DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007286 if (isolate->js_entry_sp() != NULL) return;
7287 if (is_idle) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007288 isolate->set_current_vm_state(v8::IDLE);
7289 } else if (state == v8::IDLE) {
7290 isolate->set_current_vm_state(v8::EXTERNAL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007291 }
Steve Block44f0eee2011-05-26 01:26:41 +01007292}
7293
7294
Iain Merrick75681382010-08-19 15:07:18 +01007295static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
7296 return const_cast<i::HeapGraphEdge*>(
7297 reinterpret_cast<const i::HeapGraphEdge*>(edge));
7298}
7299
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007300
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007301HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01007302 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007303}
7304
7305
7306Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007307 i::Isolate* isolate = i::Isolate::Current();
Iain Merrick75681382010-08-19 15:07:18 +01007308 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007309 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01007310 case i::HeapGraphEdge::kContextVariable:
7311 case i::HeapGraphEdge::kInternal:
7312 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08007313 case i::HeapGraphEdge::kShortcut:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007314 case i::HeapGraphEdge::kWeak:
7315 return ToApiHandle<String>(
7316 isolate->factory()->InternalizeUtf8String(edge->name()));
Iain Merrick75681382010-08-19 15:07:18 +01007317 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08007318 case i::HeapGraphEdge::kHidden:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007319 return ToApiHandle<Number>(
7320 isolate->factory()->NewNumberFromInt(edge->index()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007321 default: UNREACHABLE();
7322 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007323 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007324}
7325
7326
7327const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007328 const i::HeapEntry* from = ToInternal(this)->from();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007329 return reinterpret_cast<const HeapGraphNode*>(from);
7330}
7331
7332
7333const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Iain Merrick75681382010-08-19 15:07:18 +01007334 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007335 return reinterpret_cast<const HeapGraphNode*>(to);
7336}
7337
7338
Iain Merrick75681382010-08-19 15:07:18 +01007339static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
7340 return const_cast<i::HeapEntry*>(
7341 reinterpret_cast<const i::HeapEntry*>(entry));
7342}
7343
7344
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007345HeapGraphNode::Type HeapGraphNode::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01007346 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007347}
7348
7349
7350Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007351 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007352 return ToApiHandle<String>(
7353 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007354}
7355
7356
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007357SnapshotObjectId HeapGraphNode::GetId() const {
Iain Merrick75681382010-08-19 15:07:18 +01007358 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007359}
7360
7361
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007362int HeapGraphNode::GetSelfSize() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007363 size_t size = ToInternal(this)->self_size();
7364 CHECK(size <= static_cast<size_t>(internal::kMaxInt));
7365 return static_cast<int>(size);
7366}
7367
7368
7369size_t HeapGraphNode::GetShallowSize() const {
Iain Merrick75681382010-08-19 15:07:18 +01007370 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007371}
7372
7373
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007374int HeapGraphNode::GetChildrenCount() const {
Iain Merrick75681382010-08-19 15:07:18 +01007375 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007376}
7377
7378
7379const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007380 return reinterpret_cast<const HeapGraphEdge*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007381 ToInternal(this)->children()[index]);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007382}
7383
7384
Iain Merrick75681382010-08-19 15:07:18 +01007385static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
7386 return const_cast<i::HeapSnapshot*>(
7387 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
7388}
7389
7390
Steve Block44f0eee2011-05-26 01:26:41 +01007391void HeapSnapshot::Delete() {
7392 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007393 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
Steve Block44f0eee2011-05-26 01:26:41 +01007394 ToInternal(this)->Delete();
7395 } else {
7396 // If this is the last snapshot, clean up all accessory data as well.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007397 isolate->heap_profiler()->DeleteAllSnapshots();
Steve Block44f0eee2011-05-26 01:26:41 +01007398 }
7399}
7400
7401
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007402unsigned HeapSnapshot::GetUid() const {
Iain Merrick75681382010-08-19 15:07:18 +01007403 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007404}
7405
7406
7407Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007408 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007409 return ToApiHandle<String>(
7410 isolate->factory()->InternalizeUtf8String(ToInternal(this)->title()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007411}
7412
7413
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007414const HeapGraphNode* HeapSnapshot::GetRoot() const {
Iain Merrick75681382010-08-19 15:07:18 +01007415 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007416}
7417
7418
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007419const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
Ben Murdochb0fe1622011-05-05 13:52:32 +01007420 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007421 ToInternal(this)->GetEntryById(id));
Ben Murdochb0fe1622011-05-05 13:52:32 +01007422}
7423
7424
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007425int HeapSnapshot::GetNodesCount() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007426 return ToInternal(this)->entries().length();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007427}
7428
7429
7430const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007431 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007432 &ToInternal(this)->entries().at(index));
7433}
7434
7435
7436SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
7437 return ToInternal(this)->max_snapshot_js_object_id();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007438}
7439
7440
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007441void HeapSnapshot::Serialize(OutputStream* stream,
7442 HeapSnapshot::SerializationFormat format) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007443 Utils::ApiCheck(format == kJSON,
7444 "v8::HeapSnapshot::Serialize",
7445 "Unknown serialization format");
7446 Utils::ApiCheck(stream->GetChunkSize() > 0,
7447 "v8::HeapSnapshot::Serialize",
7448 "Invalid stream chunk size");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007449 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
7450 serializer.Serialize(stream);
7451}
7452
7453
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007454int HeapProfiler::GetSnapshotCount() {
7455 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007456}
7457
7458
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007459const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007460 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007461 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007462}
7463
7464
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007465SnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
7466 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
7467 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
7468}
7469
7470
7471Handle<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
7472 i::Handle<i::Object> obj =
7473 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
7474 if (obj.is_null()) return Local<Value>();
7475 return Utils::ToLocal(obj);
7476}
7477
7478
7479void HeapProfiler::ClearObjectIds() {
7480 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
7481}
7482
7483
7484const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
7485 Handle<String> title,
7486 ActivityControl* control,
7487 ObjectNameResolver* resolver) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007488 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007489 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
7490 *Utils::OpenHandle(*title), control, resolver));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007491}
7492
7493
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007494void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
7495 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
7496 track_allocations);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007497}
7498
Steve Block44f0eee2011-05-26 01:26:41 +01007499
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007500void HeapProfiler::StopTrackingHeapObjects() {
7501 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
Steve Block44f0eee2011-05-26 01:26:41 +01007502}
7503
7504
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007505SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
7506 return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
Steve Block44f0eee2011-05-26 01:26:41 +01007507}
7508
Steve Block6ded16b2010-05-10 14:33:55 +01007509
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007510void HeapProfiler::DeleteAllHeapSnapshots() {
7511 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
7512}
7513
7514
7515void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
7516 WrapperInfoCallback callback) {
7517 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
7518 callback);
7519}
7520
7521
7522size_t HeapProfiler::GetProfilerMemorySize() {
7523 return reinterpret_cast<i::HeapProfiler*>(this)->
7524 GetMemorySizeUsedByProfiler();
7525}
7526
7527
7528void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
7529 RetainedObjectInfo* info) {
7530 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007531}
7532
Steve Block6ded16b2010-05-10 14:33:55 +01007533
Ben Murdochb0fe1622011-05-05 13:52:32 +01007534v8::Testing::StressType internal::Testing::stress_type_ =
7535 v8::Testing::kStressTypeOpt;
7536
7537
7538void Testing::SetStressRunType(Testing::StressType type) {
7539 internal::Testing::set_stress_type(type);
7540}
7541
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007542
Ben Murdochb0fe1622011-05-05 13:52:32 +01007543int Testing::GetStressRuns() {
7544 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
7545#ifdef DEBUG
7546 // In debug mode the code runs much slower so stressing will only make two
7547 // runs.
7548 return 2;
7549#else
7550 return 5;
7551#endif
7552}
7553
7554
7555static void SetFlagsFromString(const char* flags) {
7556 V8::SetFlagsFromString(flags, i::StrLength(flags));
7557}
7558
7559
7560void Testing::PrepareStressRun(int run) {
7561 static const char* kLazyOptimizations =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007562 "--prepare-always-opt "
7563 "--max-inlined-source-size=999999 "
7564 "--max-inlined-nodes=999999 "
7565 "--max-inlined-nodes-cumulative=999999 "
7566 "--noalways-opt";
Ben Murdochb0fe1622011-05-05 13:52:32 +01007567 static const char* kForcedOptimizations = "--always-opt";
7568
7569 // If deoptimization stressed turn on frequent deoptimization. If no value
7570 // is spefified through --deopt-every-n-times use a default default value.
7571 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
7572 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
7573 internal::FLAG_deopt_every_n_times == 0) {
7574 SetFlagsFromString(kDeoptEvery13Times);
7575 }
7576
7577#ifdef DEBUG
7578 // As stressing in debug mode only make two runs skip the deopt stressing
7579 // here.
7580 if (run == GetStressRuns() - 1) {
7581 SetFlagsFromString(kForcedOptimizations);
7582 } else {
Ben Murdochb0fe1622011-05-05 13:52:32 +01007583 SetFlagsFromString(kLazyOptimizations);
7584 }
7585#else
7586 if (run == GetStressRuns() - 1) {
7587 SetFlagsFromString(kForcedOptimizations);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007588 } else if (run != GetStressRuns() - 2) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01007589 SetFlagsFromString(kLazyOptimizations);
7590 }
7591#endif
7592}
7593
7594
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007595// TODO(svenpanne) Deprecate this.
Steve Block44f0eee2011-05-26 01:26:41 +01007596void Testing::DeoptimizeAll() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007597 i::Isolate* isolate = i::Isolate::Current();
7598 i::HandleScope scope(isolate);
7599 internal::Deoptimizer::DeoptimizeAll(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00007600}
7601
7602
Steve Block44f0eee2011-05-26 01:26:41 +01007603namespace internal {
7604
7605
Steve Blocka7e24c12009-10-30 11:49:00 +00007606void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01007607 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00007608}
7609
7610
7611char* HandleScopeImplementer::ArchiveThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007612 HandleScopeData* current = isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00007613 handle_scope_data_ = *current;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007614 MemCopy(storage, this, sizeof(*this));
Steve Blocka7e24c12009-10-30 11:49:00 +00007615
7616 ResetAfterArchive();
7617 current->Initialize();
7618
7619 return storage + ArchiveSpacePerThread();
7620}
7621
7622
7623int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01007624 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00007625}
7626
7627
7628char* HandleScopeImplementer::RestoreThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007629 MemCopy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00007630 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00007631 return storage + ArchiveSpacePerThread();
7632}
7633
7634
7635void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007636#ifdef DEBUG
7637 bool found_block_before_deferred = false;
7638#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00007639 // Iterate over all handles in the blocks except for the last.
7640 for (int i = blocks()->length() - 2; i >= 0; --i) {
7641 Object** block = blocks()->at(i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007642 if (last_handle_before_deferred_block_ != NULL &&
7643 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
7644 (last_handle_before_deferred_block_ >= block)) {
7645 v->VisitPointers(block, last_handle_before_deferred_block_);
7646 DCHECK(!found_block_before_deferred);
7647#ifdef DEBUG
7648 found_block_before_deferred = true;
7649#endif
7650 } else {
7651 v->VisitPointers(block, &block[kHandleBlockSize]);
7652 }
Steve Blocka7e24c12009-10-30 11:49:00 +00007653 }
7654
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007655 DCHECK(last_handle_before_deferred_block_ == NULL ||
7656 found_block_before_deferred);
7657
Steve Blocka7e24c12009-10-30 11:49:00 +00007658 // Iterate over live handles in the last block (if any).
7659 if (!blocks()->is_empty()) {
7660 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
7661 }
7662
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007663 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
7664 for (unsigned i = 0; i < arraysize(context_lists); i++) {
7665 if (context_lists[i]->is_empty()) continue;
7666 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
7667 v->VisitPointers(start, start + context_lists[i]->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00007668 }
7669}
7670
7671
7672void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007673 HandleScopeData* current = isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01007674 handle_scope_data_ = *current;
7675 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00007676}
7677
7678
7679char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01007680 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00007681 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01007682 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00007683 return storage + ArchiveSpacePerThread();
7684}
7685
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007686
7687DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
7688 DeferredHandles* deferred =
7689 new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
7690
7691 while (!blocks_.is_empty()) {
7692 Object** block_start = blocks_.last();
7693 Object** block_limit = &block_start[kHandleBlockSize];
7694 // We should not need to check for SealHandleScope here. Assert this.
7695 DCHECK(prev_limit == block_limit ||
7696 !(block_start <= prev_limit && prev_limit <= block_limit));
7697 if (prev_limit == block_limit) break;
7698 deferred->blocks_.Add(blocks_.last());
7699 blocks_.RemoveLast();
7700 }
7701
7702 // deferred->blocks_ now contains the blocks installed on the
7703 // HandleScope stack since BeginDeferredScope was called, but in
7704 // reverse order.
7705
7706 DCHECK(prev_limit == NULL || !blocks_.is_empty());
7707
7708 DCHECK(!blocks_.is_empty() && prev_limit != NULL);
7709 DCHECK(last_handle_before_deferred_block_ != NULL);
7710 last_handle_before_deferred_block_ = NULL;
7711 return deferred;
7712}
7713
7714
7715void HandleScopeImplementer::BeginDeferredScope() {
7716 DCHECK(last_handle_before_deferred_block_ == NULL);
7717 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
7718}
7719
7720
7721DeferredHandles::~DeferredHandles() {
7722 isolate_->UnlinkDeferredHandles(this);
7723
7724 for (int i = 0; i < blocks_.length(); i++) {
7725#ifdef ENABLE_HANDLE_ZAPPING
7726 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
7727#endif
7728 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
7729 }
7730}
7731
7732
7733void DeferredHandles::Iterate(ObjectVisitor* v) {
7734 DCHECK(!blocks_.is_empty());
7735
7736 DCHECK((first_block_limit_ >= blocks_.first()) &&
7737 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
7738
7739 v->VisitPointers(blocks_.first(), first_block_limit_);
7740
7741 for (int i = 1; i < blocks_.length(); i++) {
7742 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
7743 }
7744}
7745
7746
7747void InvokeAccessorGetterCallback(
7748 v8::Local<v8::Name> property,
7749 const v8::PropertyCallbackInfo<v8::Value>& info,
7750 v8::AccessorNameGetterCallback getter) {
7751 // Leaving JavaScript.
7752 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7753 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
7754 getter));
7755 VMState<EXTERNAL> state(isolate);
7756 ExternalCallbackScope call_scope(isolate, getter_address);
7757 getter(property, info);
7758}
7759
7760
7761void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
7762 v8::FunctionCallback callback) {
7763 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7764 Address callback_address =
7765 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
7766 VMState<EXTERNAL> state(isolate);
7767 ExternalCallbackScope call_scope(isolate, callback_address);
7768 callback(info);
7769}
7770
7771
Steve Blocka7e24c12009-10-30 11:49:00 +00007772} } // namespace v8::internal