blob: e11d14084b3e292c749d2597a2e51e7b49199c4b [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"
17#include "src/base/platform/platform.h"
18#include "src/base/platform/time.h"
19#include "src/base/utils/random-number-generator.h"
20#include "src/bootstrapper.h"
21#include "src/code-stubs.h"
22#include "src/compiler.h"
23#include "src/conversions-inl.h"
24#include "src/counters.h"
25#include "src/cpu-profiler.h"
26#include "src/debug.h"
27#include "src/deoptimizer.h"
28#include "src/execution.h"
29#include "src/global-handles.h"
30#include "src/heap-profiler.h"
31#include "src/heap-snapshot-generator-inl.h"
32#include "src/icu_util.h"
33#include "src/json-parser.h"
34#include "src/messages.h"
35#include "src/natives.h"
36#include "src/parser.h"
37#include "src/profile-generator-inl.h"
38#include "src/property.h"
39#include "src/property-details.h"
40#include "src/prototype.h"
41#include "src/runtime.h"
42#include "src/runtime-profiler.h"
43#include "src/scanner-character-streams.h"
44#include "src/simulator.h"
45#include "src/snapshot.h"
46#include "src/unicode-inl.h"
47#include "src/v8threads.h"
48#include "src/version.h"
49#include "src/vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000050
51
Steve Block44f0eee2011-05-26 01:26:41 +010052#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000053
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054#define ENTER_V8(isolate) \
55 DCHECK((isolate)->IsInitialized()); \
56 i::VMState<i::OTHER> __state__((isolate))
Steve Blocka7e24c12009-10-30 11:49:00 +000057
58namespace v8 {
59
Steve Block44f0eee2011-05-26 01:26:41 +010060#define ON_BAILOUT(isolate, location, code) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 if (IsExecutionTerminatingCheck(isolate)) { \
Leon Clarkef7060e22010-06-03 12:02:55 +010062 code; \
63 UNREACHABLE(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000064 }
65
66
Steve Block44f0eee2011-05-26 01:26:41 +010067#define EXCEPTION_PREAMBLE(isolate) \
68 (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 DCHECK(!(isolate)->external_caught_exception()); \
Steve Blocka7e24c12009-10-30 11:49:00 +000070 bool has_pending_exception = false
71
72
Ben Murdoch3ef787d2012-04-12 10:51:47 +010073#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback) \
Steve Blocka7e24c12009-10-30 11:49:00 +000074 do { \
Steve Block44f0eee2011-05-26 01:26:41 +010075 i::HandleScopeImplementer* handle_scope_implementer = \
76 (isolate)->handle_scope_implementer(); \
77 handle_scope_implementer->DecrementCallDepth(); \
Steve Blocka7e24c12009-10-30 11:49:00 +000078 if (has_pending_exception) { \
Steve Block44f0eee2011-05-26 01:26:41 +010079 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
80 (isolate)->OptionalRescheduleException(call_depth_is_zero); \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010081 do_callback \
Steve Blocka7e24c12009-10-30 11:49:00 +000082 return value; \
83 } \
Ben Murdoch3ef787d2012-04-12 10:51:47 +010084 do_callback \
Steve Blocka7e24c12009-10-30 11:49:00 +000085 } while (false)
86
87
Ben Murdoch3ef787d2012-04-12 10:51:47 +010088#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
89 EXCEPTION_BAILOUT_CHECK_GENERIC( \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090 isolate, value, isolate->FireCallCompletedCallback();)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010091
92
93#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
94 EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
95
96
Steve Blocka7e24c12009-10-30 11:49:00 +000097// --- E x c e p t i o n B e h a v i o r ---
98
99
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800100void i::FatalProcessOutOfMemory(const char* location) {
101 i::V8::FatalProcessOutOfMemory(location, false);
102}
103
Steve Blocka7e24c12009-10-30 11:49:00 +0000104
105// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
106// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100107void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Steve Blockd0582a62009-12-15 09:54:21 +0000108 i::HeapStats heap_stats;
109 int start_marker;
110 heap_stats.start_marker = &start_marker;
111 int new_space_size;
112 heap_stats.new_space_size = &new_space_size;
113 int new_space_capacity;
114 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100115 intptr_t old_pointer_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000116 heap_stats.old_pointer_space_size = &old_pointer_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100117 intptr_t old_pointer_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000118 heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100119 intptr_t old_data_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000120 heap_stats.old_data_space_size = &old_data_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100121 intptr_t old_data_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000122 heap_stats.old_data_space_capacity = &old_data_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100123 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000124 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100125 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000126 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100127 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000128 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100129 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000130 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100131 intptr_t cell_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000132 heap_stats.cell_space_size = &cell_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100133 intptr_t cell_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000134 heap_stats.cell_space_capacity = &cell_space_capacity;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 intptr_t property_cell_space_size;
136 heap_stats.property_cell_space_size = &property_cell_space_size;
137 intptr_t property_cell_space_capacity;
138 heap_stats.property_cell_space_capacity = &property_cell_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100139 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000140 heap_stats.lo_space_size = &lo_space_size;
141 int global_handle_count;
142 heap_stats.global_handle_count = &global_handle_count;
143 int weak_global_handle_count;
144 heap_stats.weak_global_handle_count = &weak_global_handle_count;
145 int pending_global_handle_count;
146 heap_stats.pending_global_handle_count = &pending_global_handle_count;
147 int near_death_global_handle_count;
148 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000149 int free_global_handle_count;
150 heap_stats.free_global_handle_count = &free_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100151 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100152 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100153 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100154 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
155 int objects_per_type[LAST_TYPE + 1] = {0};
156 heap_stats.objects_per_type = objects_per_type;
157 int size_per_type[LAST_TYPE + 1] = {0};
158 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100159 int os_error;
160 heap_stats.os_error = &os_error;
Steve Blockd0582a62009-12-15 09:54:21 +0000161 int end_marker;
162 heap_stats.end_marker = &end_marker;
Steve Block44f0eee2011-05-26 01:26:41 +0100163 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000164 if (isolate->heap()->HasBeenSetUp()) {
165 // BUG(1718): Don't use the take_snapshot since we don't support
166 // HeapIterator here without doing a special GC.
167 isolate->heap()->RecordStats(&heap_stats, false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000168 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000169 Utils::ApiCheck(false, location, "Allocation failed - process out of memory");
170 // If the fatal error handler returns, we stop execution.
171 FATAL("API fatal error handler returned after process out of memory");
Steve Blocka7e24c12009-10-30 11:49:00 +0000172}
173
174
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175void Utils::ReportApiFailure(const char* location, const char* message) {
176 i::Isolate* isolate = i::Isolate::Current();
177 FatalErrorCallback callback = isolate->exception_behavior();
178 if (callback == NULL) {
179 base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
180 message);
181 base::OS::Abort();
182 } else {
183 callback(location, message);
184 }
185 isolate->SignalFatalError();
Steve Blocka7e24c12009-10-30 11:49:00 +0000186}
187
188
189bool V8::IsDead() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 i::Isolate* isolate = i::Isolate::Current();
191 return isolate->IsDead();
Steve Blocka7e24c12009-10-30 11:49:00 +0000192}
193
194
Steve Block44f0eee2011-05-26 01:26:41 +0100195static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
196 if (!isolate->IsInitialized()) return false;
197 if (isolate->has_scheduled_exception()) {
198 return isolate->scheduled_exception() ==
199 isolate->heap()->termination_exception();
200 }
201 return false;
202}
203
204
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000205StartupDataDecompressor::StartupDataDecompressor()
206 : raw_data(i::NewArray<char*>(V8::GetCompressedStartupDataCount())) {
207 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
208 raw_data[i] = NULL;
209 }
210}
211
212
213StartupDataDecompressor::~StartupDataDecompressor() {
214 for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) {
215 i::DeleteArray(raw_data[i]);
216 }
217 i::DeleteArray(raw_data);
218}
219
220
221int StartupDataDecompressor::Decompress() {
222 int compressed_data_count = V8::GetCompressedStartupDataCount();
223 StartupData* compressed_data =
224 i::NewArray<StartupData>(compressed_data_count);
225 V8::GetCompressedStartupData(compressed_data);
226 for (int i = 0; i < compressed_data_count; ++i) {
227 char* decompressed = raw_data[i] =
228 i::NewArray<char>(compressed_data[i].raw_size);
229 if (compressed_data[i].compressed_size != 0) {
230 int result = DecompressData(decompressed,
231 &compressed_data[i].raw_size,
232 compressed_data[i].data,
233 compressed_data[i].compressed_size);
234 if (result != 0) return result;
235 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236 DCHECK_EQ(0, compressed_data[i].raw_size);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000237 }
238 compressed_data[i].data = decompressed;
239 }
240 V8::SetDecompressedStartupData(compressed_data);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100241 i::DeleteArray(compressed_data);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000242 return 0;
243}
244
245
Ben Murdoch257744e2011-11-30 15:57:28 +0000246StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() {
247#ifdef COMPRESS_STARTUP_DATA_BZ2
248 return StartupData::kBZip2;
249#else
250 return StartupData::kUncompressed;
251#endif
252}
253
254
255enum CompressedStartupDataItems {
256 kSnapshot = 0,
257 kSnapshotContext,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000258 kLibraries,
259 kExperimentalLibraries,
Ben Murdoch257744e2011-11-30 15:57:28 +0000260 kCompressedStartupDataCount
261};
262
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000263
Ben Murdoch257744e2011-11-30 15:57:28 +0000264int V8::GetCompressedStartupDataCount() {
265#ifdef COMPRESS_STARTUP_DATA_BZ2
266 return kCompressedStartupDataCount;
267#else
268 return 0;
269#endif
270}
271
272
273void V8::GetCompressedStartupData(StartupData* compressed_data) {
274#ifdef COMPRESS_STARTUP_DATA_BZ2
275 compressed_data[kSnapshot].data =
276 reinterpret_cast<const char*>(i::Snapshot::data());
277 compressed_data[kSnapshot].compressed_size = i::Snapshot::size();
278 compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size();
279
280 compressed_data[kSnapshotContext].data =
281 reinterpret_cast<const char*>(i::Snapshot::context_data());
282 compressed_data[kSnapshotContext].compressed_size =
283 i::Snapshot::context_size();
284 compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000285
286 i::Vector<const i::byte> libraries_source = i::Natives::GetScriptsSource();
287 compressed_data[kLibraries].data =
288 reinterpret_cast<const char*>(libraries_source.start());
289 compressed_data[kLibraries].compressed_size = libraries_source.length();
290 compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize();
291
292 i::Vector<const i::byte> exp_libraries_source =
293 i::ExperimentalNatives::GetScriptsSource();
294 compressed_data[kExperimentalLibraries].data =
295 reinterpret_cast<const char*>(exp_libraries_source.start());
296 compressed_data[kExperimentalLibraries].compressed_size =
297 exp_libraries_source.length();
298 compressed_data[kExperimentalLibraries].raw_size =
299 i::ExperimentalNatives::GetRawScriptsSize();
Ben Murdoch257744e2011-11-30 15:57:28 +0000300#endif
301}
302
303
304void V8::SetDecompressedStartupData(StartupData* decompressed_data) {
305#ifdef COMPRESS_STARTUP_DATA_BZ2
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000306 DCHECK_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size);
Ben Murdoch257744e2011-11-30 15:57:28 +0000307 i::Snapshot::set_raw_data(
308 reinterpret_cast<const i::byte*>(decompressed_data[kSnapshot].data));
309
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310 DCHECK_EQ(i::Snapshot::context_raw_size(),
Ben Murdoch257744e2011-11-30 15:57:28 +0000311 decompressed_data[kSnapshotContext].raw_size);
312 i::Snapshot::set_context_raw_data(
313 reinterpret_cast<const i::byte*>(
314 decompressed_data[kSnapshotContext].data));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000315
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000316 DCHECK_EQ(i::Natives::GetRawScriptsSize(),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000317 decompressed_data[kLibraries].raw_size);
318 i::Vector<const char> libraries_source(
319 decompressed_data[kLibraries].data,
320 decompressed_data[kLibraries].raw_size);
321 i::Natives::SetRawScriptsSource(libraries_source);
322
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000323 DCHECK_EQ(i::ExperimentalNatives::GetRawScriptsSize(),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000324 decompressed_data[kExperimentalLibraries].raw_size);
325 i::Vector<const char> exp_libraries_source(
326 decompressed_data[kExperimentalLibraries].data,
327 decompressed_data[kExperimentalLibraries].raw_size);
328 i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source);
Ben Murdoch257744e2011-11-30 15:57:28 +0000329#endif
330}
331
332
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000333void V8::SetNativesDataBlob(StartupData* natives_blob) {
334#ifdef V8_USE_EXTERNAL_STARTUP_DATA
335 i::SetNativesFromFile(natives_blob);
336#else
337 CHECK(false);
338#endif
339}
340
341
342void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
343#ifdef V8_USE_EXTERNAL_STARTUP_DATA
344 i::SetSnapshotFromFile(snapshot_blob);
345#else
346 CHECK(false);
347#endif
348}
349
350
Steve Block44f0eee2011-05-26 01:26:41 +0100351void V8::SetFatalErrorHandler(FatalErrorCallback that) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +0100353 isolate->set_exception_behavior(that);
Steve Blocka7e24c12009-10-30 11:49:00 +0000354}
355
356
Ben Murdoch257744e2011-11-30 15:57:28 +0000357void V8::SetAllowCodeGenerationFromStringsCallback(
358 AllowCodeGenerationFromStringsCallback callback) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +0000360 isolate->set_allow_code_gen_callback(callback);
361}
362
363
Steve Blocka7e24c12009-10-30 11:49:00 +0000364void V8::SetFlagsFromString(const char* str, int length) {
365 i::FlagList::SetFlagsFromString(str, length);
366}
367
368
369void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
370 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
371}
372
373
Steve Blocka7e24c12009-10-30 11:49:00 +0000374RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
375
376
377RegisteredExtension::RegisteredExtension(Extension* extension)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100378 : extension_(extension) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000379
380
381void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100382 that->next_ = first_extension_;
383 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000384}
385
386
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387void RegisteredExtension::UnregisterAll() {
388 RegisteredExtension* re = first_extension_;
389 while (re != NULL) {
390 RegisteredExtension* next = re->next();
391 delete re;
392 re = next;
393 }
394 first_extension_ = NULL;
395}
396
397
Steve Blocka7e24c12009-10-30 11:49:00 +0000398void RegisterExtension(Extension* that) {
399 RegisteredExtension* extension = new RegisteredExtension(that);
400 RegisteredExtension::Register(extension);
401}
402
403
404Extension::Extension(const char* name,
405 const char* source,
406 int dep_count,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100407 const char** deps,
408 int source_length)
Steve Blocka7e24c12009-10-30 11:49:00 +0000409 : name_(name),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100410 source_length_(source_length >= 0 ?
411 source_length :
412 (source ? static_cast<int>(strlen(source)) : 0)),
413 source_(source, source_length_),
Steve Blocka7e24c12009-10-30 11:49:00 +0000414 dep_count_(dep_count),
415 deps_(deps),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000416 auto_enable_(false) {
417 CHECK(source != NULL || source_length_ == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000418}
419
420
421ResourceConstraints::ResourceConstraints()
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000422 : max_semi_space_size_(0),
423 max_old_space_size_(0),
424 max_executable_size_(0),
425 stack_limit_(NULL),
426 max_available_threads_(0),
427 code_range_size_(0) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000428
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000429void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
430 uint64_t virtual_memory_limit,
431 uint32_t number_of_processors) {
432#if V8_OS_ANDROID
433 // Android has higher physical memory requirements before raising the maximum
434 // heap size limits since it has no swap space.
435 const uint64_t low_limit = 512ul * i::MB;
436 const uint64_t medium_limit = 1ul * i::GB;
437 const uint64_t high_limit = 2ul * i::GB;
438#else
439 const uint64_t low_limit = 512ul * i::MB;
440 const uint64_t medium_limit = 768ul * i::MB;
441 const uint64_t high_limit = 1ul * i::GB;
442#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000443
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000444 if (physical_memory <= low_limit) {
445 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice);
446 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
447 set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
448 } else if (physical_memory <= medium_limit) {
449 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice);
450 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
451 set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
452 } else if (physical_memory <= high_limit) {
453 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice);
454 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
455 set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
456 } else {
457 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice);
458 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
459 set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
Steve Blocka7e24c12009-10-30 11:49:00 +0000460 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000461
462 set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u));
463
464 if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
465 // Reserve no more than 1/8 of the memory for the code range, but at most
466 // kMaximalCodeRangeSize.
467 set_code_range_size(
468 i::Min(i::kMaximalCodeRangeSize / i::MB,
469 static_cast<size_t>((virtual_memory_limit >> 3) / i::MB)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000470 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000471}
472
473
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474void SetResourceConstraints(i::Isolate* isolate,
475 const ResourceConstraints& constraints) {
476 int semi_space_size = constraints.max_semi_space_size();
477 int old_space_size = constraints.max_old_space_size();
478 int max_executable_size = constraints.max_executable_size();
479 size_t code_range_size = constraints.code_range_size();
480 if (semi_space_size != 0 || old_space_size != 0 ||
481 max_executable_size != 0 || code_range_size != 0) {
482 isolate->heap()->ConfigureHeap(semi_space_size, old_space_size,
483 max_executable_size, code_range_size);
484 }
485 if (constraints.stack_limit() != NULL) {
486 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
487 isolate->stack_guard()->SetStackLimit(limit);
488 }
489
490 isolate->set_max_available_threads(constraints.max_available_threads());
491}
492
493
494i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100495 LOG_API(isolate, "Persistent::New");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000496 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
497#ifdef DEBUG
498 (*obj)->ObjectVerify();
499#endif // DEBUG
Steve Blocka7e24c12009-10-30 11:49:00 +0000500 return result.location();
501}
502
503
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000504i::Object** V8::CopyPersistent(i::Object** obj) {
505 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
506#ifdef DEBUG
507 (*obj)->ObjectVerify();
508#endif // DEBUG
509 return result.location();
Steve Blocka7e24c12009-10-30 11:49:00 +0000510}
511
512
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000513void V8::MakeWeak(i::Object** object,
514 void* parameters,
515 WeakCallback weak_callback) {
516 i::GlobalHandles::MakeWeak(object, parameters, weak_callback);
Steve Blocka7e24c12009-10-30 11:49:00 +0000517}
518
519
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000520void* V8::ClearWeak(i::Object** obj) {
521 return i::GlobalHandles::ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000522}
523
524
525void V8::DisposeGlobal(i::Object** obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 i::GlobalHandles::Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000527}
528
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000529
530void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
531 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
532 i::Object* object = *Utils::OpenHandle(value);
533 isolate->eternal_handles()->Create(isolate, object, index);
534}
535
536
537Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
538 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
539 return Utils::ToLocal(isolate->eternal_handles()->Get(index));
540}
541
542
Steve Blocka7e24c12009-10-30 11:49:00 +0000543// --- H a n d l e s ---
544
545
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000546HandleScope::HandleScope(Isolate* isolate) {
547 Initialize(isolate);
548}
549
550
551void HandleScope::Initialize(Isolate* isolate) {
552 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
553 // We do not want to check the correct usage of the Locker class all over the
554 // place, so we do it only here: Without a HandleScope, an embedder can do
555 // almost nothing, so it is enough to check in this central place.
556 Utils::ApiCheck(!v8::Locker::IsActive() ||
557 internal_isolate->thread_manager()->IsLockedByCurrentThread(),
558 "HandleScope::HandleScope",
559 "Entering the V8 API without proper locking in place");
560 i::HandleScopeData* current = internal_isolate->handle_scope_data();
561 isolate_ = internal_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +0100562 prev_next_ = current->next;
563 prev_limit_ = current->limit;
Steve Block44f0eee2011-05-26 01:26:41 +0100564 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000565}
566
567
568HandleScope::~HandleScope() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000569 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
570}
571
572
573int HandleScope::NumberOfHandles(Isolate* isolate) {
574 return i::HandleScope::NumberOfHandles(
575 reinterpret_cast<i::Isolate*>(isolate));
576}
577
578
579i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
580 return i::HandleScope::CreateHandle(isolate, value);
581}
582
583
584i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
585 i::Object* value) {
586 DCHECK(heap_object->IsHeapObject());
587 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
588}
589
590
591EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
592 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
593 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
594 Initialize(v8_isolate);
595}
596
597
598i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
599 i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
600 Utils::ApiCheck(*escape_slot_ == heap->the_hole_value(),
601 "EscapeableHandleScope::Escape",
602 "Escape value set twice");
603 if (escape_value == NULL) {
604 *escape_slot_ = heap->undefined_value();
605 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000606 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000607 *escape_slot_ = *escape_value;
608 return escape_slot_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000609}
610
611
612void Context::Enter() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000613 i::Handle<i::Context> env = Utils::OpenHandle(this);
614 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100615 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000616 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
617 impl->EnterContext(env);
618 impl->SaveContext(isolate->context());
Steve Block44f0eee2011-05-26 01:26:41 +0100619 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000620}
621
622
623void Context::Exit() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 i::Handle<i::Context> env = Utils::OpenHandle(this);
625 i::Isolate* isolate = env->GetIsolate();
626 ENTER_V8(isolate);
627 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
628 if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
629 "v8::Context::Exit()",
630 "Cannot exit non-entered context")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000631 return;
632 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000633 impl->LeaveContext();
634 isolate->set_context(impl->RestoreContext());
Steve Blocka7e24c12009-10-30 11:49:00 +0000635}
636
637
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000638static void* DecodeSmiToAligned(i::Object* value, const char* location) {
639 Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
640 return reinterpret_cast<void*>(value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000641}
642
643
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000644static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
645 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
646 Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
647 return smi;
648}
649
650
651static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
652 int index,
653 bool can_grow,
654 const char* location) {
655 i::Handle<i::Context> env = Utils::OpenHandle(context);
656 bool ok =
657 Utils::ApiCheck(env->IsNativeContext(),
658 location,
659 "Not a native context") &&
660 Utils::ApiCheck(index >= 0, location, "Negative index");
661 if (!ok) return i::Handle<i::FixedArray>();
662 i::Handle<i::FixedArray> data(env->embedder_data());
663 if (index < data->length()) return data;
664 if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
665 return i::Handle<i::FixedArray>();
Steve Block44f0eee2011-05-26 01:26:41 +0100666 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000667 int new_size = i::Max(index, data->length() << 1) + 1;
668 data = i::FixedArray::CopySize(data, new_size);
669 env->set_embedder_data(*data);
670 return data;
671}
672
673
674v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
675 const char* location = "v8::Context::GetEmbedderData()";
676 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
677 if (data.is_null()) return Local<Value>();
678 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000679 return Utils::ToLocal(result);
680}
681
682
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000683void Context::SetEmbedderData(int index, v8::Handle<Value> value) {
684 const char* location = "v8::Context::SetEmbedderData()";
685 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
686 if (data.is_null()) return;
687 i::Handle<i::Object> val = Utils::OpenHandle(*value);
688 data->set(index, *val);
689 DCHECK_EQ(*Utils::OpenHandle(*value),
690 *Utils::OpenHandle(*GetEmbedderData(index)));
691}
Steve Blocka7e24c12009-10-30 11:49:00 +0000692
Steve Blocka7e24c12009-10-30 11:49:00 +0000693
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000694void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
695 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
696 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
697 if (data.is_null()) return NULL;
698 return DecodeSmiToAligned(data->get(index), location);
699}
Steve Block6ded16b2010-05-10 14:33:55 +0100700
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000701
702void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
703 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
704 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
705 data->set(index, EncodeAlignedAsSmi(value, location));
706 DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
Steve Blocka7e24c12009-10-30 11:49:00 +0000707}
708
709
710// --- N e a n d e r ---
711
712
713// A constructor cannot easily return an error value, therefore it is necessary
714// to check for a dead VM with ON_BAILOUT before constructing any Neander
715// objects. To remind you about this there is no HandleScope in the
716// NeanderObject constructor. When you add one to the site calling the
717// constructor you should check that you ensured the VM was not dead first.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000718NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100719 ENTER_V8(isolate);
720 value_ = isolate->factory()->NewNeanderObject();
721 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000722 value_->set_elements(*elements);
723}
724
725
726int NeanderObject::size() {
727 return i::FixedArray::cast(value_->elements())->length();
728}
729
730
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000731NeanderArray::NeanderArray(v8::internal::Isolate* isolate) : obj_(isolate, 2) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000732 obj_.set(0, i::Smi::FromInt(0));
733}
734
735
736int NeanderArray::length() {
737 return i::Smi::cast(obj_.get(0))->value();
738}
739
740
741i::Object* NeanderArray::get(int offset) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000742 DCHECK(0 <= offset);
743 DCHECK(offset < length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000744 return obj_.get(offset + 1);
745}
746
747
748// This method cannot easily return an error value, therefore it is necessary
749// to check for a dead VM with ON_BAILOUT before calling it. To remind you
750// about this there is no HandleScope in this method. When you add one to the
751// site calling this method you should check that you ensured the VM was not
752// dead first.
753void NeanderArray::add(i::Handle<i::Object> value) {
754 int length = this->length();
755 int size = obj_.size();
756 if (length == size - 1) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000757 i::Factory* factory = i::Isolate::Current()->factory();
758 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000759 for (int i = 0; i < length; i++)
760 new_elms->set(i + 1, get(i));
761 obj_.value()->set_elements(*new_elms);
762 }
763 obj_.set(length + 1, *value);
764 obj_.set(0, i::Smi::FromInt(length + 1));
765}
766
767
768void NeanderArray::set(int index, i::Object* value) {
769 if (index < 0 || index >= this->length()) return;
770 obj_.set(index + 1, value);
771}
772
773
774// --- T e m p l a t e ---
775
776
777static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
778 that->set_tag(i::Smi::FromInt(type));
779}
780
781
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000782static void TemplateSet(i::Isolate* isolate,
783 v8::Template* templ,
784 int length,
785 v8::Handle<v8::Data>* data) {
786 i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000787 if (list->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000788 list = NeanderArray(isolate).value();
789 Utils::OpenHandle(templ)->set_property_list(*list);
Steve Blocka7e24c12009-10-30 11:49:00 +0000790 }
791 NeanderArray array(list);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000792 array.add(isolate->factory()->NewNumberFromInt(length));
793 for (int i = 0; i < length; i++) {
794 i::Handle<i::Object> value = data[i].IsEmpty() ?
795 i::Handle<i::Object>(isolate->factory()->undefined_value()) :
796 Utils::OpenHandle(*data[i]);
797 array.add(value);
798 }
799}
800
801
802void Template::Set(v8::Handle<Name> name,
803 v8::Handle<Data> value,
804 v8::PropertyAttribute attribute) {
805 i::Isolate* isolate = i::Isolate::Current();
806 ENTER_V8(isolate);
807 i::HandleScope scope(isolate);
808 const int kSize = 3;
809 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
810 v8::Handle<v8::Data> data[kSize] = {
811 name,
812 value,
813 v8::Integer::New(v8_isolate, attribute)};
814 TemplateSet(isolate, this, kSize, data);
815}
816
817
818void Template::SetAccessorProperty(
819 v8::Local<v8::Name> name,
820 v8::Local<FunctionTemplate> getter,
821 v8::Local<FunctionTemplate> setter,
822 v8::PropertyAttribute attribute,
823 v8::AccessControl access_control) {
824 // TODO(verwaest): Remove |access_control|.
825 DCHECK_EQ(v8::DEFAULT, access_control);
826 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
827 ENTER_V8(isolate);
828 DCHECK(!name.IsEmpty());
829 DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
830 i::HandleScope scope(isolate);
831 const int kSize = 5;
832 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
833 v8::Handle<v8::Data> data[kSize] = {
834 name,
835 getter,
836 setter,
837 v8::Integer::New(v8_isolate, attribute)};
838 TemplateSet(isolate, this, kSize, data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000839}
840
841
842// --- F u n c t i o n T e m p l a t e ---
843static void InitializeFunctionTemplate(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000844 i::Handle<i::FunctionTemplateInfo> info) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000845 info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
846 info->set_flag(0);
847}
848
849
850Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000851 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
852 ENTER_V8(i_isolate);
853 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
854 i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000855 if (result->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000856 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(i_isolate);
857 result = Utils::OpenHandle(*ObjectTemplate::New(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +0000858 Utils::OpenHandle(this)->set_prototype_template(*result);
859 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000860 return ToApiHandle<ObjectTemplate>(result);
Steve Blocka7e24c12009-10-30 11:49:00 +0000861}
862
863
864void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
Steve Block44f0eee2011-05-26 01:26:41 +0100865 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100866 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000867 Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
868}
869
870
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000871static Local<FunctionTemplate> FunctionTemplateNew(
872 i::Isolate* isolate,
873 FunctionCallback callback,
874 v8::Handle<Value> data,
875 v8::Handle<Signature> signature,
876 int length,
877 bool do_not_cache) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000878 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +0100879 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000880 i::Handle<i::FunctionTemplateInfo> obj =
881 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
882 InitializeFunctionTemplate(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000883 obj->set_do_not_cache(do_not_cache);
884 int next_serial_number = 0;
885 if (!do_not_cache) {
886 next_serial_number = isolate->next_serial_number() + 1;
887 isolate->set_next_serial_number(next_serial_number);
888 }
Steve Block44f0eee2011-05-26 01:26:41 +0100889 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +0000890 if (callback != 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891 if (data.IsEmpty()) {
892 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
893 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000894 Utils::ToLocal(obj)->SetCallHandler(callback, data);
895 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000896 obj->set_length(length);
Steve Blocka7e24c12009-10-30 11:49:00 +0000897 obj->set_undetectable(false);
898 obj->set_needs_access_check(false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000899 if (!signature.IsEmpty())
900 obj->set_signature(*Utils::OpenHandle(*signature));
901 return Utils::ToLocal(obj);
902}
903
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000904Local<FunctionTemplate> FunctionTemplate::New(
905 Isolate* isolate,
906 FunctionCallback callback,
907 v8::Handle<Value> data,
908 v8::Handle<Signature> signature,
909 int length) {
910 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
911 LOG_API(i_isolate, "FunctionTemplate::New");
912 ENTER_V8(i_isolate);
913 return FunctionTemplateNew(
914 i_isolate, callback, data, signature, length, false);
915}
Steve Blocka7e24c12009-10-30 11:49:00 +0000916
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000917
918Local<Signature> Signature::New(Isolate* isolate,
919 Handle<FunctionTemplate> receiver, int argc,
920 Handle<FunctionTemplate> argv[]) {
921 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
922 LOG_API(i_isolate, "Signature::New");
923 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000924 i::Handle<i::Struct> struct_obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000925 i_isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000926 i::Handle<i::SignatureInfo> obj =
927 i::Handle<i::SignatureInfo>::cast(struct_obj);
928 if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
929 if (argc > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000930 i::Handle<i::FixedArray> args = i_isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000931 for (int i = 0; i < argc; i++) {
932 if (!argv[i].IsEmpty())
933 args->set(i, *Utils::OpenHandle(*argv[i]));
934 }
935 obj->set_args(*args);
936 }
937 return Utils::ToLocal(obj);
938}
939
940
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000941Local<AccessorSignature> AccessorSignature::New(
942 Isolate* isolate,
943 Handle<FunctionTemplate> receiver) {
944 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
945}
946
947
948template<typename Operation>
949static Local<Operation> NewDescriptor(
950 Isolate* isolate,
951 const i::DeclaredAccessorDescriptorData& data,
952 Data* previous_descriptor) {
953 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
954 i::Handle<i::DeclaredAccessorDescriptor> previous =
955 i::Handle<i::DeclaredAccessorDescriptor>();
956 if (previous_descriptor != NULL) {
957 previous = Utils::OpenHandle(
958 static_cast<DeclaredAccessorDescriptor*>(previous_descriptor));
959 }
960 i::Handle<i::DeclaredAccessorDescriptor> descriptor =
961 i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous);
962 return Utils::Convert<i::DeclaredAccessorDescriptor, Operation>(descriptor);
963}
964
965
966Local<RawOperationDescriptor>
967ObjectOperationDescriptor::NewInternalFieldDereference(
968 Isolate* isolate,
969 int internal_field) {
970 i::DeclaredAccessorDescriptorData data;
971 data.type = i::kDescriptorObjectDereference;
972 data.object_dereference_descriptor.internal_field = internal_field;
973 return NewDescriptor<RawOperationDescriptor>(isolate, data, NULL);
974}
975
976
977Local<RawOperationDescriptor> RawOperationDescriptor::NewRawShift(
978 Isolate* isolate,
979 int16_t byte_offset) {
980 i::DeclaredAccessorDescriptorData data;
981 data.type = i::kDescriptorPointerShift;
982 data.pointer_shift_descriptor.byte_offset = byte_offset;
983 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
984}
985
986
987Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewHandleDereference(
988 Isolate* isolate) {
989 i::DeclaredAccessorDescriptorData data;
990 data.type = i::kDescriptorReturnObject;
991 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
992}
993
994
995Local<RawOperationDescriptor> RawOperationDescriptor::NewRawDereference(
996 Isolate* isolate) {
997 i::DeclaredAccessorDescriptorData data;
998 data.type = i::kDescriptorPointerDereference;
999 return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
1000}
1001
1002
1003Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPointerCompare(
1004 Isolate* isolate,
1005 void* compare_value) {
1006 i::DeclaredAccessorDescriptorData data;
1007 data.type = i::kDescriptorPointerCompare;
1008 data.pointer_compare_descriptor.compare_value = compare_value;
1009 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1010}
1011
1012
1013Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPrimitiveValue(
1014 Isolate* isolate,
1015 DeclaredAccessorDescriptorDataType data_type,
1016 uint8_t bool_offset) {
1017 i::DeclaredAccessorDescriptorData data;
1018 data.type = i::kDescriptorPrimitiveValue;
1019 data.primitive_value_descriptor.data_type = data_type;
1020 data.primitive_value_descriptor.bool_offset = bool_offset;
1021 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
1022}
1023
1024
1025template<typename T>
1026static Local<DeclaredAccessorDescriptor> NewBitmaskCompare(
1027 Isolate* isolate,
1028 T bitmask,
1029 T compare_value,
1030 RawOperationDescriptor* operation) {
1031 i::DeclaredAccessorDescriptorData data;
1032 data.type = i::kDescriptorBitmaskCompare;
1033 data.bitmask_compare_descriptor.bitmask = bitmask;
1034 data.bitmask_compare_descriptor.compare_value = compare_value;
1035 data.bitmask_compare_descriptor.size = sizeof(T);
1036 return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, operation);
1037}
1038
1039
1040Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare8(
1041 Isolate* isolate,
1042 uint8_t bitmask,
1043 uint8_t compare_value) {
1044 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1045}
1046
1047
1048Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare16(
1049 Isolate* isolate,
1050 uint16_t bitmask,
1051 uint16_t compare_value) {
1052 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1053}
1054
1055
1056Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare32(
1057 Isolate* isolate,
1058 uint32_t bitmask,
1059 uint32_t compare_value) {
1060 return NewBitmaskCompare(isolate, bitmask, compare_value, this);
1061}
1062
1063
Steve Blocka7e24c12009-10-30 11:49:00 +00001064Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
1065 Handle<FunctionTemplate> types[1] = { type };
1066 return TypeSwitch::New(1, types);
1067}
1068
1069
1070Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01001071 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01001072 LOG_API(isolate, "TypeSwitch::New");
1073 ENTER_V8(isolate);
1074 i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
Steve Blocka7e24c12009-10-30 11:49:00 +00001075 for (int i = 0; i < argc; i++)
1076 vector->set(i, *Utils::OpenHandle(*types[i]));
1077 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001078 isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001079 i::Handle<i::TypeSwitchInfo> obj =
1080 i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
1081 obj->set_types(*vector);
1082 return Utils::ToLocal(obj);
1083}
1084
1085
1086int TypeSwitch::match(v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001087 i::Isolate* isolate = i::Isolate::Current();
1088 LOG_API(isolate, "TypeSwitch::match");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001089 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001090 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
1091 i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
1092 i::FixedArray* types = i::FixedArray::cast(info->types());
1093 for (int i = 0; i < types->length(); i++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001094 if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
Steve Blocka7e24c12009-10-30 11:49:00 +00001095 return i + 1;
1096 }
1097 return 0;
1098}
1099
1100
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001101#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
1102 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
1103 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001104 } while (false)
1105
1106
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107void FunctionTemplate::SetCallHandler(FunctionCallback callback,
Steve Blocka7e24c12009-10-30 11:49:00 +00001108 v8::Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001109 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001110 ENTER_V8(isolate);
1111 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001112 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001113 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001114 i::Handle<i::CallHandlerInfo> obj =
1115 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001116 SET_FIELD_WRAPPED(obj, set_callback, callback);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001117 if (data.IsEmpty()) {
1118 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1119 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001120 obj->set_data(*Utils::OpenHandle(*data));
1121 Utils::OpenHandle(this)->set_call_code(*obj);
1122}
1123
1124
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001125static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
1126 i::Handle<i::AccessorInfo> obj,
1127 v8::Handle<Name> name,
1128 v8::AccessControl settings,
1129 v8::PropertyAttribute attributes,
1130 v8::Handle<AccessorSignature> signature) {
Leon Clarkef7060e22010-06-03 12:02:55 +01001131 obj->set_name(*Utils::OpenHandle(*name));
1132 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1133 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
Leon Clarkef7060e22010-06-03 12:02:55 +01001134 obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001135 if (!signature.IsEmpty()) {
1136 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1137 }
Leon Clarkef7060e22010-06-03 12:02:55 +01001138 return obj;
1139}
1140
1141
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001142template<typename Getter, typename Setter>
1143static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1144 v8::Handle<Name> name,
1145 Getter getter,
1146 Setter setter,
1147 v8::Handle<Value> data,
1148 v8::AccessControl settings,
1149 v8::PropertyAttribute attributes,
1150 v8::Handle<AccessorSignature> signature) {
1151 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1152 i::Handle<i::ExecutableAccessorInfo> obj =
1153 isolate->factory()->NewExecutableAccessorInfo();
1154 SET_FIELD_WRAPPED(obj, set_getter, getter);
1155 SET_FIELD_WRAPPED(obj, set_setter, setter);
1156 if (data.IsEmpty()) {
1157 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00001158 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001159 obj->set_data(*Utils::OpenHandle(*data));
1160 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1161}
Steve Blocka7e24c12009-10-30 11:49:00 +00001162
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001163
1164static i::Handle<i::AccessorInfo> MakeAccessorInfo(
1165 v8::Handle<Name> name,
1166 v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
1167 void* setter_ignored,
1168 void* data_ignored,
1169 v8::AccessControl settings,
1170 v8::PropertyAttribute attributes,
1171 v8::Handle<AccessorSignature> signature) {
1172 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
1173 if (descriptor.IsEmpty()) return i::Handle<i::DeclaredAccessorInfo>();
1174 i::Handle<i::DeclaredAccessorInfo> obj =
1175 isolate->factory()->NewDeclaredAccessorInfo();
1176 obj->set_descriptor(*Utils::OpenHandle(*descriptor));
1177 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
Steve Blocka7e24c12009-10-30 11:49:00 +00001178}
1179
1180
1181Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001182 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1183 if (!Utils::ApiCheck(!handle.is_null(),
1184 "v8::FunctionTemplate::InstanceTemplate()",
1185 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001186 return Local<ObjectTemplate>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001187 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001188 i::Isolate* isolate = handle->GetIsolate();
1189 ENTER_V8(isolate);
1190 if (handle->instance_template()->IsUndefined()) {
1191 Local<ObjectTemplate> templ =
1192 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1193 handle->set_instance_template(*Utils::OpenHandle(*templ));
1194 }
1195 i::Handle<i::ObjectTemplateInfo> result(
1196 i::ObjectTemplateInfo::cast(handle->instance_template()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001197 return Utils::ToLocal(result);
1198}
1199
1200
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001201void FunctionTemplate::SetLength(int length) {
1202 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1203 ENTER_V8(isolate);
1204 Utils::OpenHandle(this)->set_length(length);
1205}
1206
1207
Steve Blocka7e24c12009-10-30 11:49:00 +00001208void FunctionTemplate::SetClassName(Handle<String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01001209 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001210 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001211 Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
1212}
1213
1214
1215void FunctionTemplate::SetHiddenPrototype(bool value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001216 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001217 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001218 Utils::OpenHandle(this)->set_hidden_prototype(value);
1219}
1220
1221
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001222void FunctionTemplate::ReadOnlyPrototype() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001223 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001224 ENTER_V8(isolate);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001225 Utils::OpenHandle(this)->set_read_only_prototype(true);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001226}
1227
1228
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001229void FunctionTemplate::RemovePrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01001230 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001231 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001232 Utils::OpenHandle(this)->set_remove_prototype(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001233}
1234
1235
1236// --- O b j e c t T e m p l a t e ---
1237
1238
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001239Local<ObjectTemplate> ObjectTemplate::New(Isolate* isolate) {
1240 return New(reinterpret_cast<i::Isolate*>(isolate), Local<FunctionTemplate>());
1241}
1242
1243
Steve Blocka7e24c12009-10-30 11:49:00 +00001244Local<ObjectTemplate> ObjectTemplate::New() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001245 return New(i::Isolate::Current(), Local<FunctionTemplate>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001246}
1247
1248
1249Local<ObjectTemplate> ObjectTemplate::New(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001250 i::Isolate* isolate,
1251 v8::Handle<FunctionTemplate> constructor) {
Steve Block44f0eee2011-05-26 01:26:41 +01001252 LOG_API(isolate, "ObjectTemplate::New");
1253 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001254 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001255 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001256 i::Handle<i::ObjectTemplateInfo> obj =
1257 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1258 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
1259 if (!constructor.IsEmpty())
1260 obj->set_constructor(*Utils::OpenHandle(*constructor));
1261 obj->set_internal_field_count(i::Smi::FromInt(0));
1262 return Utils::ToLocal(obj);
1263}
1264
1265
1266// Ensure that the object template has a constructor. If no
1267// constructor is available we create one.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001268static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1269 i::Isolate* isolate,
1270 ObjectTemplate* object_template) {
1271 i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1272 if (!obj ->IsUndefined()) {
1273 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1274 return i::Handle<i::FunctionTemplateInfo>(info, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001275 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001276 Local<FunctionTemplate> templ =
1277 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1278 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1279 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1280 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1281 return constructor;
1282}
1283
1284
1285static inline void AddPropertyToTemplate(
1286 i::Handle<i::TemplateInfo> info,
1287 i::Handle<i::AccessorInfo> obj) {
1288 i::Isolate* isolate = info->GetIsolate();
1289 i::Handle<i::Object> list(info->property_accessors(), isolate);
1290 if (list->IsUndefined()) {
1291 list = NeanderArray(isolate).value();
1292 info->set_property_accessors(*list);
1293 }
1294 NeanderArray array(list);
1295 array.add(obj);
1296}
1297
1298
1299static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1300 i::Isolate* isolate,
1301 Template* template_obj) {
1302 return Utils::OpenHandle(template_obj);
1303}
1304
1305
1306// TODO(dcarney): remove this with ObjectTemplate::SetAccessor
1307static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
1308 i::Isolate* isolate,
1309 ObjectTemplate* object_template) {
1310 EnsureConstructor(isolate, object_template);
1311 return Utils::OpenHandle(object_template);
1312}
1313
1314
1315template<typename Getter, typename Setter, typename Data, typename Template>
1316static bool TemplateSetAccessor(
1317 Template* template_obj,
1318 v8::Local<Name> name,
1319 Getter getter,
1320 Setter setter,
1321 Data data,
1322 AccessControl settings,
1323 PropertyAttribute attribute,
1324 v8::Local<AccessorSignature> signature) {
1325 i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
1326 ENTER_V8(isolate);
1327 i::HandleScope scope(isolate);
1328 i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
1329 name, getter, setter, data, settings, attribute, signature);
1330 if (obj.is_null()) return false;
1331 i::Handle<i::TemplateInfo> info = GetTemplateInfo(isolate, template_obj);
1332 AddPropertyToTemplate(info, obj);
1333 return true;
1334}
1335
1336
1337bool Template::SetDeclaredAccessor(
1338 Local<Name> name,
1339 Local<DeclaredAccessorDescriptor> descriptor,
1340 PropertyAttribute attribute,
1341 Local<AccessorSignature> signature,
1342 AccessControl settings) {
1343 void* null = NULL;
1344 return TemplateSetAccessor(
1345 this, name, descriptor, null, null, settings, attribute, signature);
1346}
1347
1348
1349void Template::SetNativeDataProperty(v8::Local<String> name,
1350 AccessorGetterCallback getter,
1351 AccessorSetterCallback setter,
1352 v8::Handle<Value> data,
1353 PropertyAttribute attribute,
1354 v8::Local<AccessorSignature> signature,
1355 AccessControl settings) {
1356 TemplateSetAccessor(
1357 this, name, getter, setter, data, settings, attribute, signature);
1358}
1359
1360
1361void Template::SetNativeDataProperty(v8::Local<Name> name,
1362 AccessorNameGetterCallback getter,
1363 AccessorNameSetterCallback setter,
1364 v8::Handle<Value> data,
1365 PropertyAttribute attribute,
1366 v8::Local<AccessorSignature> signature,
1367 AccessControl settings) {
1368 TemplateSetAccessor(
1369 this, name, getter, setter, data, settings, attribute, signature);
Steve Blocka7e24c12009-10-30 11:49:00 +00001370}
1371
1372
1373void ObjectTemplate::SetAccessor(v8::Handle<String> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001374 AccessorGetterCallback getter,
1375 AccessorSetterCallback setter,
Steve Blocka7e24c12009-10-30 11:49:00 +00001376 v8::Handle<Value> data,
1377 AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001378 PropertyAttribute attribute,
1379 v8::Handle<AccessorSignature> signature) {
1380 TemplateSetAccessor(
1381 this, name, getter, setter, data, settings, attribute, signature);
Steve Blocka7e24c12009-10-30 11:49:00 +00001382}
1383
1384
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001385void ObjectTemplate::SetAccessor(v8::Handle<Name> name,
1386 AccessorNameGetterCallback getter,
1387 AccessorNameSetterCallback setter,
1388 v8::Handle<Value> data,
1389 AccessControl settings,
1390 PropertyAttribute attribute,
1391 v8::Handle<AccessorSignature> signature) {
1392 TemplateSetAccessor(
1393 this, name, getter, setter, data, settings, attribute, signature);
1394}
1395
1396
1397void ObjectTemplate::SetNamedPropertyHandler(
1398 NamedPropertyGetterCallback getter,
1399 NamedPropertySetterCallback setter,
1400 NamedPropertyQueryCallback query,
1401 NamedPropertyDeleterCallback remover,
1402 NamedPropertyEnumeratorCallback enumerator,
1403 Handle<Value> data) {
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);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001411 i::Handle<i::Struct> struct_obj =
1412 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1413 i::Handle<i::InterceptorInfo> obj =
1414 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1415
1416 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1417 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1418 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1419 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1420 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1421
1422 if (data.IsEmpty()) {
1423 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1424 }
1425 obj->set_data(*Utils::OpenHandle(*data));
1426 cons->set_named_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001427}
1428
1429
1430void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001431 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001432 ENTER_V8(isolate);
1433 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001434 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001435 i::FunctionTemplateInfo* constructor =
1436 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1437 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1438 cons->set_undetectable(true);
1439}
1440
1441
1442void ObjectTemplate::SetAccessCheckCallbacks(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001443 NamedSecurityCallback named_callback,
1444 IndexedSecurityCallback indexed_callback,
1445 Handle<Value> data,
1446 bool turned_on_by_default) {
Steve Block44f0eee2011-05-26 01:26:41 +01001447 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001448 ENTER_V8(isolate);
1449 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001450 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001451
1452 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001453 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001454 i::Handle<i::AccessCheckInfo> info =
1455 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001456
1457 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1458 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1459
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001460 if (data.IsEmpty()) {
1461 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1462 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001463 info->set_data(*Utils::OpenHandle(*data));
1464
1465 i::FunctionTemplateInfo* constructor =
1466 i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
1467 i::Handle<i::FunctionTemplateInfo> cons(constructor);
1468 cons->set_access_check_info(*info);
1469 cons->set_needs_access_check(turned_on_by_default);
1470}
1471
1472
1473void ObjectTemplate::SetIndexedPropertyHandler(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001474 IndexedPropertyGetterCallback getter,
1475 IndexedPropertySetterCallback setter,
1476 IndexedPropertyQueryCallback query,
1477 IndexedPropertyDeleterCallback remover,
1478 IndexedPropertyEnumeratorCallback enumerator,
1479 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001480 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001481 ENTER_V8(isolate);
1482 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001483 EnsureConstructor(isolate, this);
1484 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1485 Utils::OpenHandle(this)->constructor());
Steve Blocka7e24c12009-10-30 11:49:00 +00001486 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001487 i::Handle<i::Struct> struct_obj =
1488 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
1489 i::Handle<i::InterceptorInfo> obj =
1490 i::Handle<i::InterceptorInfo>::cast(struct_obj);
1491
1492 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1493 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1494 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1495 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1496 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
1497
1498 if (data.IsEmpty()) {
1499 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1500 }
1501 obj->set_data(*Utils::OpenHandle(*data));
1502 cons->set_indexed_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001503}
1504
1505
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001506void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
Steve Blocka7e24c12009-10-30 11:49:00 +00001507 Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001508 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001509 ENTER_V8(isolate);
1510 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001511 EnsureConstructor(isolate, this);
1512 i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
1513 Utils::OpenHandle(this)->constructor());
Steve Blocka7e24c12009-10-30 11:49:00 +00001514 i::Handle<i::FunctionTemplateInfo> cons(constructor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001515 i::Handle<i::Struct> struct_obj =
1516 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1517 i::Handle<i::CallHandlerInfo> obj =
1518 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1519 SET_FIELD_WRAPPED(obj, set_callback, callback);
1520 if (data.IsEmpty()) {
1521 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1522 }
1523 obj->set_data(*Utils::OpenHandle(*data));
1524 cons->set_instance_call_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001525}
1526
1527
1528int ObjectTemplate::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00001529 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1530}
1531
1532
1533void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001534 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001535 if (!Utils::ApiCheck(i::Smi::IsValid(value),
1536 "v8::ObjectTemplate::SetInternalFieldCount()",
1537 "Invalid internal field count")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001538 return;
1539 }
Steve Block44f0eee2011-05-26 01:26:41 +01001540 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001541 if (value > 0) {
1542 // The internal field count is set by the constructor function's
1543 // construct code, so we ensure that there is a constructor
1544 // function to do the setting.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001545 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001546 }
1547 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1548}
1549
1550
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001551// --- S c r i p t s ---
Steve Blocka7e24c12009-10-30 11:49:00 +00001552
1553
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001554// Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1555// JSFunction.
1556
1557ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1558 BufferPolicy buffer_policy_)
1559 : data(data_), length(length_), buffer_policy(buffer_policy_) {}
1560
1561
1562ScriptCompiler::CachedData::~CachedData() {
1563 if (buffer_policy == BufferOwned) {
1564 delete[] data;
1565 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001566}
1567
1568
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001569ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
1570 Encoding encoding)
1571 : impl_(new i::StreamedSource(stream, encoding)) {}
1572
1573
1574ScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; }
1575
1576
1577const ScriptCompiler::CachedData*
1578ScriptCompiler::StreamedSource::GetCachedData() const {
1579 return impl_->cached_data.get();
1580}
1581
1582
1583Local<Script> UnboundScript::BindToCurrentContext() {
1584 i::Handle<i::HeapObject> obj =
1585 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1586 i::Handle<i::SharedFunctionInfo>
1587 function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
1588 i::Handle<i::JSFunction> function =
1589 obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
1590 function_info, obj->GetIsolate()->global_context());
1591 return ToApiHandle<Script>(function);
1592}
1593
1594
1595int UnboundScript::GetId() {
1596 i::Handle<i::HeapObject> obj =
1597 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1598 i::Isolate* isolate = obj->GetIsolate();
1599 ON_BAILOUT(isolate, "v8::UnboundScript::GetId()", return -1);
1600 LOG_API(isolate, "v8::UnboundScript::GetId");
1601 {
1602 i::HandleScope scope(isolate);
1603 i::Handle<i::SharedFunctionInfo> function_info(
1604 i::SharedFunctionInfo::cast(*obj));
1605 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1606 return script->id()->value();
1607 }
1608}
1609
1610
1611int UnboundScript::GetLineNumber(int code_pos) {
1612 i::Handle<i::SharedFunctionInfo> obj =
1613 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1614 i::Isolate* isolate = obj->GetIsolate();
1615 ON_BAILOUT(isolate, "v8::UnboundScript::GetLineNumber()", return -1);
1616 LOG_API(isolate, "UnboundScript::GetLineNumber");
1617 if (obj->script()->IsScript()) {
1618 i::Handle<i::Script> script(i::Script::cast(obj->script()));
1619 return i::Script::GetLineNumber(script, code_pos);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001620 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001621 return -1;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001622 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001623}
1624
1625
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001626Handle<Value> UnboundScript::GetScriptName() {
1627 i::Handle<i::SharedFunctionInfo> obj =
1628 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1629 i::Isolate* isolate = obj->GetIsolate();
1630 ON_BAILOUT(isolate, "v8::UnboundScript::GetName()",
1631 return Handle<String>());
1632 LOG_API(isolate, "UnboundScript::GetName");
1633 if (obj->script()->IsScript()) {
1634 i::Object* name = i::Script::cast(obj->script())->name();
1635 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1636 } else {
1637 return Handle<String>();
Leon Clarkef7060e22010-06-03 12:02:55 +01001638 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001639}
Leon Clarkef7060e22010-06-03 12:02:55 +01001640
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001641
1642Handle<Value> UnboundScript::GetSourceURL() {
1643 i::Handle<i::SharedFunctionInfo> obj =
1644 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1645 i::Isolate* isolate = obj->GetIsolate();
1646 ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceURL()",
1647 return Handle<String>());
1648 LOG_API(isolate, "UnboundScript::GetSourceURL");
1649 if (obj->script()->IsScript()) {
1650 i::Object* url = i::Script::cast(obj->script())->source_url();
1651 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1652 } else {
1653 return Handle<String>();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001654 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001655}
1656
1657
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001658Handle<Value> UnboundScript::GetSourceMappingURL() {
1659 i::Handle<i::SharedFunctionInfo> obj =
1660 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1661 i::Isolate* isolate = obj->GetIsolate();
1662 ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceMappingURL()",
1663 return Handle<String>());
1664 LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
1665 if (obj->script()->IsScript()) {
1666 i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
1667 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1668 } else {
1669 return Handle<String>();
Ben Murdoch692be652012-01-10 18:47:50 +00001670 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001671}
1672
1673
1674Local<Value> Script::Run() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001675 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
1676 // If execution is terminating, Compile(..)->Run() requires this
1677 // check.
1678 if (obj.is_null()) return Local<Value>();
1679 i::Isolate* isolate = i::Handle<i::HeapObject>::cast(obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001680 ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
1681 LOG_API(isolate, "Script::Run");
1682 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001683 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
1684 i::HandleScope scope(isolate);
1685 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
1686 EXCEPTION_PREAMBLE(isolate);
1687 i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
1688 i::Handle<i::Object> result;
1689 has_pending_exception = !i::Execution::Call(
1690 isolate, fun, receiver, 0, NULL).ToHandle(&result);
1691 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
1692 return Utils::ToLocal(scope.CloseAndEscape(result));
1693}
1694
1695
1696Local<UnboundScript> Script::GetUnboundScript() {
1697 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1698 return ToApiHandle<UnboundScript>(
1699 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
1700}
1701
1702
1703Local<UnboundScript> ScriptCompiler::CompileUnbound(
1704 Isolate* v8_isolate,
1705 Source* source,
1706 CompileOptions options) {
1707 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1708 ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()",
1709 return Local<UnboundScript>());
1710
1711 // Support the old API for a transition period:
1712 // - kProduceToCache -> kProduceParserCache
1713 // - kNoCompileOptions + cached_data != NULL -> kConsumeParserCache
1714 if (options == kProduceDataToCache) {
1715 options = kProduceParserCache;
1716 } else if (options == kNoCompileOptions && source->cached_data) {
1717 options = kConsumeParserCache;
1718 }
1719
1720 i::ScriptData* script_data = NULL;
1721 if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1722 DCHECK(source->cached_data);
1723 // ScriptData takes care of pointer-aligning the data.
1724 script_data = new i::ScriptData(source->cached_data->data,
1725 source->cached_data->length);
1726 }
1727
1728 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
1729 LOG_API(isolate, "ScriptCompiler::CompileUnbound");
1730 ENTER_V8(isolate);
1731 i::SharedFunctionInfo* raw_result = NULL;
1732 { i::HandleScope scope(isolate);
1733 i::Handle<i::Object> name_obj;
1734 int line_offset = 0;
1735 int column_offset = 0;
1736 bool is_shared_cross_origin = false;
1737 if (!source->resource_name.IsEmpty()) {
1738 name_obj = Utils::OpenHandle(*(source->resource_name));
1739 }
1740 if (!source->resource_line_offset.IsEmpty()) {
1741 line_offset = static_cast<int>(source->resource_line_offset->Value());
1742 }
1743 if (!source->resource_column_offset.IsEmpty()) {
1744 column_offset =
1745 static_cast<int>(source->resource_column_offset->Value());
1746 }
1747 if (!source->resource_is_shared_cross_origin.IsEmpty()) {
1748 v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
1749 is_shared_cross_origin =
1750 source->resource_is_shared_cross_origin == v8::True(v8_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001751 }
Steve Block44f0eee2011-05-26 01:26:41 +01001752 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001753 i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript(
1754 str, name_obj, line_offset, column_offset, is_shared_cross_origin,
1755 isolate->global_context(), NULL, &script_data, options,
1756 i::NOT_NATIVES_CODE);
1757 has_pending_exception = result.is_null();
1758 if (has_pending_exception && script_data != NULL) {
1759 // This case won't happen during normal operation; we have compiled
1760 // successfully and produced cached data, and but the second compilation
1761 // of the same source code fails.
1762 delete script_data;
1763 script_data = NULL;
1764 }
1765 EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001766 raw_result = *result;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001767
1768 if ((options == kProduceParserCache || options == kProduceCodeCache) &&
1769 script_data != NULL) {
1770 // script_data now contains the data that was generated. source will
1771 // take the ownership.
1772 source->cached_data = new CachedData(
1773 script_data->data(), script_data->length(), CachedData::BufferOwned);
1774 script_data->ReleaseDataOwnership();
1775 }
1776 delete script_data;
Steve Blocka7e24c12009-10-30 11:49:00 +00001777 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001778 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
1779 return ToApiHandle<UnboundScript>(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001780}
1781
1782
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001783Local<Script> ScriptCompiler::Compile(
1784 Isolate* v8_isolate,
1785 Source* source,
1786 CompileOptions options) {
1787 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1788 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
1789 LOG_API(isolate, "ScriptCompiler::CompiletBound()");
1790 ENTER_V8(isolate);
1791 Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options);
1792 if (generic.IsEmpty()) return Local<Script>();
1793 return generic->BindToCurrentContext();
Steve Block6ded16b2010-05-10 14:33:55 +01001794}
1795
1796
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001797ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
1798 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
1799 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1800 if (!isolate->global_context().is_null() &&
1801 !isolate->global_context()->IsNativeContext()) {
1802 // The context chain is non-trivial, and constructing the corresponding
1803 // non-trivial Scope chain outside the V8 heap is not implemented. Don't
1804 // stream the script. This will only occur if Harmony scoping is enabled and
1805 // a previous script has introduced "let" or "const" variables. TODO(marja):
1806 // Implement externalizing ScopeInfos and constructing non-trivial Scope
1807 // chains independent of the V8 heap so that we can stream also in this
1808 // case.
1809 return NULL;
1810 }
1811 return new i::BackgroundParsingTask(source->impl(), options,
1812 i::FLAG_stack_size, isolate);
1813}
1814
1815
1816Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
1817 StreamedSource* v8_source,
1818 Handle<String> full_source_string,
1819 const ScriptOrigin& origin) {
1820 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
1821 i::StreamedSource* source = v8_source->impl();
1822 ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
1823 LOG_API(isolate, "ScriptCompiler::Compile()");
1824 ENTER_V8(isolate);
1825 i::SharedFunctionInfo* raw_result = NULL;
1826
Steve Blocka7e24c12009-10-30 11:49:00 +00001827 {
Steve Block44f0eee2011-05-26 01:26:41 +01001828 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001829 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
1830 i::Handle<i::Script> script = isolate->factory()->NewScript(str);
1831 if (!origin.ResourceName().IsEmpty()) {
1832 script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
1833 }
1834 if (!origin.ResourceLineOffset().IsEmpty()) {
1835 script->set_line_offset(i::Smi::FromInt(
1836 static_cast<int>(origin.ResourceLineOffset()->Value())));
1837 }
1838 if (!origin.ResourceColumnOffset().IsEmpty()) {
1839 script->set_column_offset(i::Smi::FromInt(
1840 static_cast<int>(origin.ResourceColumnOffset()->Value())));
1841 }
1842 if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) {
1843 script->set_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin() ==
1844 v8::True(v8_isolate));
1845 }
1846 source->info->set_script(script);
1847 source->info->SetContext(isolate->global_context());
1848
1849 EXCEPTION_PREAMBLE(isolate);
1850
1851 // Do the parsing tasks which need to be done on the main thread. This will
1852 // also handle parse errors.
1853 source->parser->Internalize();
1854
1855 i::Handle<i::SharedFunctionInfo> result =
1856 i::Handle<i::SharedFunctionInfo>::null();
1857 if (source->info->function() != NULL) {
1858 // Parsing has succeeded.
1859 result =
1860 i::Compiler::CompileStreamedScript(source->info.get(), str->length());
1861 }
1862 has_pending_exception = result.is_null();
1863 if (has_pending_exception) isolate->ReportPendingMessages();
1864 EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
1865
1866 raw_result = *result;
1867 // The Handle<Script> will go out of scope soon; make sure CompilationInfo
1868 // doesn't point to it.
1869 source->info->set_script(i::Handle<i::Script>());
1870 } // HandleScope goes out of scope.
1871 i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
1872 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
1873 if (generic.IsEmpty()) {
1874 return Local<Script>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001875 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001876 return generic->BindToCurrentContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00001877}
1878
1879
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001880Local<Script> Script::Compile(v8::Handle<String> source,
1881 v8::ScriptOrigin* origin) {
1882 i::Handle<i::String> str = Utils::OpenHandle(*source);
1883 if (origin) {
1884 ScriptCompiler::Source script_source(source, *origin);
1885 return ScriptCompiler::Compile(
1886 reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
1887 &script_source);
Steve Blocka7e24c12009-10-30 11:49:00 +00001888 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001889 ScriptCompiler::Source script_source(source);
1890 return ScriptCompiler::Compile(
1891 reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
1892 &script_source);
1893}
1894
1895
1896Local<Script> Script::Compile(v8::Handle<String> source,
1897 v8::Handle<String> file_name) {
1898 ScriptOrigin origin(file_name);
1899 return Compile(source, &origin);
Steve Blocka7e24c12009-10-30 11:49:00 +00001900}
1901
1902
1903// --- E x c e p t i o n s ---
1904
1905
1906v8::TryCatch::TryCatch()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001907 : isolate_(i::Isolate::Current()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001908 next_(isolate_->try_catch_handler()),
Steve Blocka7e24c12009-10-30 11:49:00 +00001909 is_verbose_(false),
1910 can_continue_(true),
1911 capture_message_(true),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001912 rethrow_(false),
1913 has_terminated_(false) {
1914 ResetInternal();
1915 // Special handling for simulators which have a separate JS stack.
1916 js_stack_comparable_address_ =
1917 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
1918 v8::internal::GetCurrentStackPosition()));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001919 isolate_->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001920}
1921
1922
1923v8::TryCatch::~TryCatch() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001924 DCHECK(isolate_ == i::Isolate::Current());
Steve Blockd0582a62009-12-15 09:54:21 +00001925 if (rethrow_) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001926 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
1927 v8::HandleScope scope(isolate);
1928 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
1929 if (HasCaught() && capture_message_) {
1930 // If an exception was caught and rethrow_ is indicated, the saved
1931 // message, script, and location need to be restored to Isolate TLS
1932 // for reuse. capture_message_ needs to be disabled so that DoThrow()
1933 // does not create a new message.
1934 isolate_->thread_local_top()->rethrowing_message_ = true;
1935 isolate_->RestorePendingMessageFromTryCatch(this);
1936 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001937 isolate_->UnregisterTryCatchHandler(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001938 v8::internal::SimulatorStack::UnregisterCTryCatch();
1939 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
1940 DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
Steve Blockd0582a62009-12-15 09:54:21 +00001941 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001942 if (HasCaught() && isolate_->has_scheduled_exception()) {
1943 // If an exception was caught but is still scheduled because no API call
1944 // promoted it, then it is canceled to prevent it from being propagated.
1945 // Note that this will not cancel termination exceptions.
1946 isolate_->CancelScheduledExceptionFromTryCatch(this);
1947 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001948 isolate_->UnregisterTryCatchHandler(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001949 v8::internal::SimulatorStack::UnregisterCTryCatch();
Steve Blockd0582a62009-12-15 09:54:21 +00001950 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001951}
1952
1953
1954bool v8::TryCatch::HasCaught() const {
1955 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
1956}
1957
1958
1959bool v8::TryCatch::CanContinue() const {
1960 return can_continue_;
1961}
1962
1963
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001964bool v8::TryCatch::HasTerminated() const {
1965 return has_terminated_;
1966}
1967
1968
Steve Blockd0582a62009-12-15 09:54:21 +00001969v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
1970 if (!HasCaught()) return v8::Local<v8::Value>();
1971 rethrow_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001972 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
Steve Blockd0582a62009-12-15 09:54:21 +00001973}
1974
1975
Steve Blocka7e24c12009-10-30 11:49:00 +00001976v8::Local<Value> v8::TryCatch::Exception() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001977 DCHECK(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001978 if (HasCaught()) {
1979 // Check for out of memory exception.
1980 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001981 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00001982 } else {
1983 return v8::Local<Value>();
1984 }
1985}
1986
1987
1988v8::Local<Value> v8::TryCatch::StackTrace() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001989 DCHECK(isolate_ == i::Isolate::Current());
Steve Blocka7e24c12009-10-30 11:49:00 +00001990 if (HasCaught()) {
1991 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
1992 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001993 i::HandleScope scope(isolate_);
1994 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001995 i::Handle<i::String> name = isolate_->factory()->stack_string();
1996 EXCEPTION_PREAMBLE(isolate_);
1997 Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
1998 has_pending_exception = !maybe.has_value;
1999 EXCEPTION_BAILOUT_CHECK(isolate_, v8::Local<Value>());
2000 if (!maybe.value) return v8::Local<Value>();
2001 i::Handle<i::Object> value;
2002 if (!i::Object::GetProperty(obj, name).ToHandle(&value)) {
2003 return v8::Local<Value>();
2004 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002005 return v8::Utils::ToLocal(scope.CloseAndEscape(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00002006 } else {
2007 return v8::Local<Value>();
2008 }
2009}
2010
2011
2012v8::Local<v8::Message> v8::TryCatch::Message() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002013 DCHECK(isolate_ == i::Isolate::Current());
2014 i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2015 DCHECK(message->IsJSMessageObject() || message->IsTheHole());
2016 if (HasCaught() && !message->IsTheHole()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002017 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00002018 } else {
2019 return v8::Local<v8::Message>();
2020 }
2021}
2022
2023
2024void v8::TryCatch::Reset() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002025 DCHECK(isolate_ == i::Isolate::Current());
2026 if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2027 // If an exception was caught but is still scheduled because no API call
2028 // promoted it, then it is canceled to prevent it from being propagated.
2029 // Note that this will not cancel termination exceptions.
2030 isolate_->CancelScheduledExceptionFromTryCatch(this);
2031 }
2032 ResetInternal();
2033}
2034
2035
2036void v8::TryCatch::ResetInternal() {
2037 i::Object* the_hole = isolate_->heap()->the_hole_value();
2038 exception_ = the_hole;
2039 message_obj_ = the_hole;
2040 message_script_ = the_hole;
2041 message_start_pos_ = 0;
2042 message_end_pos_ = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00002043}
2044
2045
2046void v8::TryCatch::SetVerbose(bool value) {
2047 is_verbose_ = value;
2048}
2049
2050
2051void v8::TryCatch::SetCaptureMessage(bool value) {
2052 capture_message_ = value;
2053}
2054
2055
2056// --- M e s s a g e ---
2057
2058
2059Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002060 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2061 ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
2062 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002063 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00002064 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002065 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00002066 Local<String> result = Utils::ToLocal(raw_result);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002067 return scope.Escape(result);
2068}
2069
2070
2071ScriptOrigin Message::GetScriptOrigin() const {
2072 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2073 i::Handle<i::JSMessageObject> message =
2074 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2075 i::Handle<i::Object> script_wraper =
2076 i::Handle<i::Object>(message->script(), isolate);
2077 i::Handle<i::JSValue> script_value =
2078 i::Handle<i::JSValue>::cast(script_wraper);
2079 i::Handle<i::Script> script(i::Script::cast(script_value->value()));
2080 i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
2081 v8::Isolate* v8_isolate =
2082 reinterpret_cast<v8::Isolate*>(script->GetIsolate());
2083 v8::ScriptOrigin origin(
2084 Utils::ToLocal(scriptName),
2085 v8::Integer::New(v8_isolate, script->line_offset()->value()),
2086 v8::Integer::New(v8_isolate, script->column_offset()->value()),
2087 Handle<Boolean>(),
2088 v8::Integer::New(v8_isolate, script->id()->value()));
2089 return origin;
Steve Blocka7e24c12009-10-30 11:49:00 +00002090}
2091
2092
2093v8::Handle<Value> Message::GetScriptResourceName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002094 return GetScriptOrigin().ResourceName();
Steve Blocka7e24c12009-10-30 11:49:00 +00002095}
2096
2097
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002098v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002099 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002100 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002101 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Block1e0659c2011-05-24 12:43:12 +01002102 i::Handle<i::JSMessageObject> message =
2103 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002104 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002105 if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
2106 i::Handle<i::JSArray> stackTrace =
2107 i::Handle<i::JSArray>::cast(stackFramesObj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002108 return scope.Escape(Utils::StackTraceToLocal(stackTrace));
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002109}
2110
2111
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002112MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
2113 const char* name,
2114 i::Handle<i::Object> recv,
2115 int argc,
2116 i::Handle<i::Object> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01002117 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002118 i::Handle<i::Object> object_fun =
2119 i::Object::GetProperty(
2120 isolate, isolate->js_builtins_object(), name).ToHandleChecked();
2121 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(object_fun);
2122 return i::Execution::Call(isolate, fun, recv, argc, argv);
Steve Blocka7e24c12009-10-30 11:49:00 +00002123}
2124
2125
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002126MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
2127 const char* name,
2128 i::Handle<i::Object> data) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002129 i::Handle<i::Object> argv[] = { data };
Steve Blocka7e24c12009-10-30 11:49:00 +00002130 return CallV8HeapFunction(name,
Steve Block44f0eee2011-05-26 01:26:41 +01002131 i::Isolate::Current()->js_builtins_object(),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002132 arraysize(argv),
2133 argv);
Steve Blocka7e24c12009-10-30 11:49:00 +00002134}
2135
2136
2137int Message::GetLineNumber() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002138 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2139 ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
2140 ENTER_V8(isolate);
2141 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01002142
Steve Block44f0eee2011-05-26 01:26:41 +01002143 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002144 i::Handle<i::Object> result;
2145 has_pending_exception = !CallV8HeapFunction(
2146 "GetLineNumber", Utils::OpenHandle(this)).ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01002147 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002148 return static_cast<int>(result->Number());
2149}
2150
2151
2152int Message::GetStartPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002153 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002154 ENTER_V8(isolate);
2155 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01002156 i::Handle<i::JSMessageObject> message =
2157 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2158 return message->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002159}
2160
2161
2162int Message::GetEndPosition() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002163 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002164 ENTER_V8(isolate);
2165 i::HandleScope scope(isolate);
Steve Block1e0659c2011-05-24 12:43:12 +01002166 i::Handle<i::JSMessageObject> message =
2167 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2168 return message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002169}
2170
2171
2172int Message::GetStartColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002173 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002174 ON_BAILOUT(isolate, "v8::Message::GetStartColumn()", return kNoColumnInfo);
Steve Block44f0eee2011-05-26 01:26:41 +01002175 ENTER_V8(isolate);
2176 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002177 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002178 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002179 i::Handle<i::Object> start_col_obj;
2180 has_pending_exception = !CallV8HeapFunction(
2181 "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002182 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002183 return static_cast<int>(start_col_obj->Number());
2184}
2185
2186
2187int Message::GetEndColumn() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002188 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002189 ON_BAILOUT(isolate, "v8::Message::GetEndColumn()", return kNoColumnInfo);
Steve Block44f0eee2011-05-26 01:26:41 +01002190 ENTER_V8(isolate);
2191 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002192 i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01002193 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002194 i::Handle<i::Object> start_col_obj;
2195 has_pending_exception = !CallV8HeapFunction(
2196 "GetPositionInLine", data_obj).ToHandle(&start_col_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002197 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Block1e0659c2011-05-24 12:43:12 +01002198 i::Handle<i::JSMessageObject> message =
2199 i::Handle<i::JSMessageObject>::cast(data_obj);
2200 int start = message->start_position();
2201 int end = message->end_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002202 return static_cast<int>(start_col_obj->Number()) + (end - start);
2203}
2204
2205
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002206bool Message::IsSharedCrossOrigin() const {
2207 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2208 ENTER_V8(isolate);
2209 i::HandleScope scope(isolate);
2210 i::Handle<i::JSMessageObject> message =
2211 i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2212 i::Handle<i::JSValue> script =
2213 i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
2214 isolate));
2215 return i::Script::cast(script->value())->is_shared_cross_origin();
2216}
2217
2218
Steve Blocka7e24c12009-10-30 11:49:00 +00002219Local<String> Message::GetSourceLine() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002220 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2221 ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
2222 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002223 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Block44f0eee2011-05-26 01:26:41 +01002224 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002225 i::Handle<i::Object> result;
2226 has_pending_exception = !CallV8HeapFunction(
2227 "GetSourceLine", Utils::OpenHandle(this)).ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01002228 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002229 if (result->IsString()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002230 return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
Steve Blocka7e24c12009-10-30 11:49:00 +00002231 } else {
2232 return Local<String>();
2233 }
2234}
2235
2236
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002237void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
2238 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2239 ENTER_V8(i_isolate);
2240 i_isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00002241}
2242
2243
Kristian Monsen25f61362010-05-21 11:50:48 +01002244// --- S t a c k T r a c e ---
2245
2246Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002247 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002248 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002249 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Kristian Monsen25f61362010-05-21 11:50:48 +01002250 i::Handle<i::JSArray> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002251 i::Handle<i::Object> obj =
2252 i::Object::GetElement(isolate, self, index).ToHandleChecked();
2253 i::Handle<i::JSObject> jsobj = i::Handle<i::JSObject>::cast(obj);
2254 return scope.Escape(Utils::StackFrameToLocal(jsobj));
Kristian Monsen25f61362010-05-21 11:50:48 +01002255}
2256
2257
2258int StackTrace::GetFrameCount() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002259 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002260 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002261 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2262}
2263
2264
2265Local<Array> StackTrace::AsArray() {
Steve Block44f0eee2011-05-26 01:26:41 +01002266 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002267 ENTER_V8(isolate);
Kristian Monsen25f61362010-05-21 11:50:48 +01002268 return Utils::ToLocal(Utils::OpenHandle(this));
2269}
2270
2271
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002272Local<StackTrace> StackTrace::CurrentStackTrace(
2273 Isolate* isolate,
2274 int frame_limit,
Kristian Monsen25f61362010-05-21 11:50:48 +01002275 StackTraceOptions options) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002276 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2277 ENTER_V8(i_isolate);
2278 // TODO(dcarney): remove when ScriptDebugServer is fixed.
2279 options = static_cast<StackTraceOptions>(
2280 static_cast<int>(options) | kExposeFramesAcrossSecurityOrigins);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002281 i::Handle<i::JSArray> stackTrace =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002282 i_isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002283 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01002284}
2285
2286
2287// --- S t a c k F r a m e ---
2288
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002289static int getIntProperty(const StackFrame* f, const char* propertyName,
2290 int defaultValue) {
2291 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002292 ENTER_V8(isolate);
2293 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002294 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2295 i::Handle<i::Object> obj =
2296 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2297 return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue;
2298}
2299
2300
2301int StackFrame::GetLineNumber() const {
2302 return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo);
Kristian Monsen25f61362010-05-21 11:50:48 +01002303}
2304
2305
2306int StackFrame::GetColumn() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002307 return getIntProperty(this, "column", Message::kNoColumnInfo);
2308}
2309
2310
2311int StackFrame::GetScriptId() const {
2312 return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo);
2313}
2314
2315
2316static Local<String> getStringProperty(const StackFrame* f,
2317 const char* propertyName) {
2318 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002319 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002320 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2321 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2322 i::Handle<i::Object> obj =
2323 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2324 return obj->IsString()
2325 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
2326 : Local<String>();
Kristian Monsen25f61362010-05-21 11:50:48 +01002327}
2328
2329
2330Local<String> StackFrame::GetScriptName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002331 return getStringProperty(this, "scriptName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002332}
2333
2334
Ben Murdochf87a2032010-10-22 12:50:53 +01002335Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002336 return getStringProperty(this, "scriptNameOrSourceURL");
Ben Murdochf87a2032010-10-22 12:50:53 +01002337}
2338
2339
Kristian Monsen25f61362010-05-21 11:50:48 +01002340Local<String> StackFrame::GetFunctionName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002341 return getStringProperty(this, "functionName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002342}
2343
2344
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002345static bool getBoolProperty(const StackFrame* f, const char* propertyName) {
2346 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002347 ENTER_V8(isolate);
2348 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002349 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2350 i::Handle<i::Object> obj =
2351 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2352 return obj->IsTrue();
Kristian Monsen25f61362010-05-21 11:50:48 +01002353}
2354
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002355bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
2356
Kristian Monsen25f61362010-05-21 11:50:48 +01002357
2358bool StackFrame::IsConstructor() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002359 return getBoolProperty(this, "isConstructor");
2360}
2361
2362
2363// --- J S O N ---
2364
2365Local<Value> JSON::Parse(Local<String> json_string) {
2366 i::Handle<i::String> string = Utils::OpenHandle(*json_string);
2367 i::Isolate* isolate = string->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002368 ENTER_V8(isolate);
2369 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002370 i::Handle<i::String> source = i::String::Flatten(string);
2371 EXCEPTION_PREAMBLE(isolate);
2372 i::MaybeHandle<i::Object> maybe_result =
2373 source->IsSeqOneByteString() ? i::JsonParser<true>::Parse(source)
2374 : i::JsonParser<false>::Parse(source);
2375 i::Handle<i::Object> result;
2376 has_pending_exception = !maybe_result.ToHandle(&result);
2377 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
2378 return Utils::ToLocal(
2379 i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
Kristian Monsen25f61362010-05-21 11:50:48 +01002380}
2381
2382
Steve Blocka7e24c12009-10-30 11:49:00 +00002383// --- D a t a ---
2384
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002385bool Value::FullIsUndefined() const {
2386 bool result = Utils::OpenHandle(this)->IsUndefined();
2387 DCHECK_EQ(result, QuickIsUndefined());
2388 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002389}
2390
2391
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002392bool Value::FullIsNull() const {
2393 bool result = Utils::OpenHandle(this)->IsNull();
2394 DCHECK_EQ(result, QuickIsNull());
2395 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002396}
2397
2398
2399bool Value::IsTrue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002400 return Utils::OpenHandle(this)->IsTrue();
2401}
2402
2403
2404bool Value::IsFalse() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002405 return Utils::OpenHandle(this)->IsFalse();
2406}
2407
2408
2409bool Value::IsFunction() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002410 return Utils::OpenHandle(this)->IsJSFunction();
2411}
2412
2413
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002414bool Value::IsName() const {
2415 return Utils::OpenHandle(this)->IsName();
2416}
2417
2418
Steve Blocka7e24c12009-10-30 11:49:00 +00002419bool Value::FullIsString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002420 bool result = Utils::OpenHandle(this)->IsString();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002421 DCHECK_EQ(result, QuickIsString());
Steve Blocka7e24c12009-10-30 11:49:00 +00002422 return result;
2423}
2424
2425
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002426bool Value::IsSymbol() const {
2427 return Utils::OpenHandle(this)->IsSymbol();
2428}
2429
2430
Steve Blocka7e24c12009-10-30 11:49:00 +00002431bool Value::IsArray() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002432 return Utils::OpenHandle(this)->IsJSArray();
2433}
2434
2435
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002436bool Value::IsArrayBuffer() const {
2437 return Utils::OpenHandle(this)->IsJSArrayBuffer();
2438}
2439
2440
2441bool Value::IsArrayBufferView() const {
2442 return Utils::OpenHandle(this)->IsJSArrayBufferView();
2443}
2444
2445
2446bool Value::IsTypedArray() const {
2447 return Utils::OpenHandle(this)->IsJSTypedArray();
2448}
2449
2450
2451#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
2452 bool Value::Is##Type##Array() const { \
2453 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2454 return obj->IsJSTypedArray() && \
2455 i::JSTypedArray::cast(*obj)->type() == kExternal##Type##Array; \
2456 }
2457
2458TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
2459
2460#undef VALUE_IS_TYPED_ARRAY
2461
2462
2463bool Value::IsDataView() const {
2464 return Utils::OpenHandle(this)->IsJSDataView();
2465}
2466
2467
Steve Blocka7e24c12009-10-30 11:49:00 +00002468bool Value::IsObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002469 return Utils::OpenHandle(this)->IsJSObject();
2470}
2471
2472
2473bool Value::IsNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002474 return Utils::OpenHandle(this)->IsNumber();
2475}
2476
2477
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002478#define VALUE_IS_SPECIFIC_TYPE(Type, Class) \
2479 bool Value::Is##Type() const { \
2480 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2481 if (!obj->IsHeapObject()) return false; \
2482 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); \
2483 return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
Steve Block44f0eee2011-05-26 01:26:41 +01002484 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002485
2486VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
2487VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
2488VALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
2489VALUE_IS_SPECIFIC_TYPE(StringObject, String)
2490VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
2491VALUE_IS_SPECIFIC_TYPE(Date, Date)
2492VALUE_IS_SPECIFIC_TYPE(Map, Map)
2493VALUE_IS_SPECIFIC_TYPE(Set, Set)
2494VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
2495VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
2496
2497#undef VALUE_IS_SPECIFIC_TYPE
2498
2499
2500bool Value::IsBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002501 return Utils::OpenHandle(this)->IsBoolean();
2502}
2503
2504
2505bool Value::IsExternal() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002506 return Utils::OpenHandle(this)->IsExternal();
Steve Blocka7e24c12009-10-30 11:49:00 +00002507}
2508
2509
2510bool Value::IsInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002511 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2512 if (obj->IsSmi()) return true;
2513 if (obj->IsNumber()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002514 return i::IsInt32Double(obj->Number());
Steve Blocka7e24c12009-10-30 11:49:00 +00002515 }
2516 return false;
2517}
2518
2519
Steve Block6ded16b2010-05-10 14:33:55 +01002520bool Value::IsUint32() const {
Steve Block6ded16b2010-05-10 14:33:55 +01002521 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2522 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2523 if (obj->IsNumber()) {
2524 double value = obj->Number();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002525 return !i::IsMinusZero(value) &&
2526 value >= 0 &&
2527 value <= i::kMaxUInt32 &&
2528 value == i::FastUI2D(i::FastD2UI(value));
Steve Block6ded16b2010-05-10 14:33:55 +01002529 }
2530 return false;
2531}
2532
2533
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002534static bool CheckConstructor(i::Isolate* isolate,
2535 i::Handle<i::JSObject> obj,
2536 const char* class_name) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002537 i::Handle<i::Object> constr(obj->map()->constructor(), isolate);
2538 if (!constr->IsJSFunction()) return false;
2539 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(constr);
2540 return func->shared()->native() && constr.is_identical_to(
2541 i::Object::GetProperty(isolate,
2542 isolate->js_builtins_object(),
2543 class_name).ToHandleChecked());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002544}
2545
2546
2547bool Value::IsNativeError() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002548 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2549 if (obj->IsJSObject()) {
2550 i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002551 i::Isolate* isolate = js_obj->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002552 return CheckConstructor(isolate, js_obj, "$Error") ||
2553 CheckConstructor(isolate, js_obj, "$EvalError") ||
2554 CheckConstructor(isolate, js_obj, "$RangeError") ||
2555 CheckConstructor(isolate, js_obj, "$ReferenceError") ||
2556 CheckConstructor(isolate, js_obj, "$SyntaxError") ||
2557 CheckConstructor(isolate, js_obj, "$TypeError") ||
2558 CheckConstructor(isolate, js_obj, "$URIError");
2559 } else {
2560 return false;
2561 }
2562}
2563
2564
Iain Merrick75681382010-08-19 15:07:18 +01002565bool Value::IsRegExp() const {
Iain Merrick75681382010-08-19 15:07:18 +01002566 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2567 return obj->IsJSRegExp();
2568}
2569
2570
Steve Blocka7e24c12009-10-30 11:49:00 +00002571Local<String> Value::ToString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002572 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2573 i::Handle<i::Object> str;
2574 if (obj->IsString()) {
2575 str = obj;
2576 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002577 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01002578 LOG_API(isolate, "ToString");
2579 ENTER_V8(isolate);
2580 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002581 has_pending_exception = !i::Execution::ToString(
2582 isolate, obj).ToHandle(&str);
Steve Block44f0eee2011-05-26 01:26:41 +01002583 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002584 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002585 return ToApiHandle<String>(str);
Steve Blocka7e24c12009-10-30 11:49:00 +00002586}
2587
2588
2589Local<String> Value::ToDetailString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002590 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2591 i::Handle<i::Object> str;
2592 if (obj->IsString()) {
2593 str = obj;
2594 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002595 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01002596 LOG_API(isolate, "ToDetailString");
2597 ENTER_V8(isolate);
2598 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002599 has_pending_exception = !i::Execution::ToDetailString(
2600 isolate, obj).ToHandle(&str);
Steve Block44f0eee2011-05-26 01:26:41 +01002601 EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002602 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002603 return ToApiHandle<String>(str);
Steve Blocka7e24c12009-10-30 11:49:00 +00002604}
2605
2606
2607Local<v8::Object> Value::ToObject() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002608 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2609 i::Handle<i::Object> val;
2610 if (obj->IsJSObject()) {
2611 val = obj;
2612 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002613 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01002614 LOG_API(isolate, "ToObject");
2615 ENTER_V8(isolate);
2616 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002617 has_pending_exception = !i::Execution::ToObject(
2618 isolate, obj).ToHandle(&val);
Steve Block44f0eee2011-05-26 01:26:41 +01002619 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002620 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002621 return ToApiHandle<Object>(val);
Steve Blocka7e24c12009-10-30 11:49:00 +00002622}
2623
2624
2625Local<Boolean> Value::ToBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002626 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2627 if (obj->IsBoolean()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002628 return ToApiHandle<Boolean>(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00002629 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002630 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01002631 LOG_API(isolate, "ToBoolean");
2632 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002633 i::Handle<i::Object> val =
2634 isolate->factory()->ToBoolean(obj->BooleanValue());
2635 return ToApiHandle<Boolean>(val);
Steve Blocka7e24c12009-10-30 11:49:00 +00002636 }
2637}
2638
2639
2640Local<Number> Value::ToNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002641 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2642 i::Handle<i::Object> num;
2643 if (obj->IsNumber()) {
2644 num = obj;
2645 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002646 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002647 LOG_API(isolate, "ToNumber");
2648 ENTER_V8(isolate);
2649 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002650 has_pending_exception = !i::Execution::ToNumber(
2651 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002652 EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002653 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002654 return ToApiHandle<Number>(num);
Steve Blocka7e24c12009-10-30 11:49:00 +00002655}
2656
2657
2658Local<Integer> Value::ToInteger() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002659 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2660 i::Handle<i::Object> num;
2661 if (obj->IsSmi()) {
2662 num = obj;
2663 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002664 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002665 LOG_API(isolate, "ToInteger");
2666 ENTER_V8(isolate);
2667 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002668 has_pending_exception = !i::Execution::ToInteger(
2669 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002670 EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002671 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002672 return ToApiHandle<Integer>(num);
2673}
2674
2675
2676void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
2677 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
2678 Utils::ApiCheck(isolate != NULL &&
2679 isolate->IsInitialized() &&
2680 !isolate->IsDead(),
2681 "v8::internal::Internals::CheckInitialized()",
2682 "Isolate is not initialized or V8 has died");
Steve Blocka7e24c12009-10-30 11:49:00 +00002683}
2684
2685
2686void External::CheckCast(v8::Value* that) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002687 Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(),
2688 "v8::External::Cast()",
2689 "Could not convert to external");
Steve Blocka7e24c12009-10-30 11:49:00 +00002690}
2691
2692
2693void v8::Object::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002694 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002695 Utils::ApiCheck(obj->IsJSObject(),
2696 "v8::Object::Cast()",
2697 "Could not convert to object");
Steve Blocka7e24c12009-10-30 11:49:00 +00002698}
2699
2700
2701void v8::Function::CheckCast(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->IsJSFunction(),
2704 "v8::Function::Cast()",
2705 "Could not convert to function");
2706}
2707
2708
2709void v8::Name::CheckCast(v8::Value* that) {
2710 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2711 Utils::ApiCheck(obj->IsName(),
2712 "v8::Name::Cast()",
2713 "Could not convert to name");
Steve Blocka7e24c12009-10-30 11:49:00 +00002714}
2715
2716
2717void v8::String::CheckCast(v8::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->IsString(),
2720 "v8::String::Cast()",
2721 "Could not convert to string");
2722}
2723
2724
2725void v8::Symbol::CheckCast(v8::Value* that) {
2726 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2727 Utils::ApiCheck(obj->IsSymbol(),
2728 "v8::Symbol::Cast()",
2729 "Could not convert to symbol");
Steve Blocka7e24c12009-10-30 11:49:00 +00002730}
2731
2732
2733void v8::Number::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002734 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002735 Utils::ApiCheck(obj->IsNumber(),
2736 "v8::Number::Cast()",
2737 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00002738}
2739
2740
2741void v8::Integer::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002742 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002743 Utils::ApiCheck(obj->IsNumber(),
2744 "v8::Integer::Cast()",
2745 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00002746}
2747
2748
2749void v8::Array::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002750 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002751 Utils::ApiCheck(obj->IsJSArray(),
2752 "v8::Array::Cast()",
2753 "Could not convert to array");
2754}
2755
2756
2757void v8::Promise::CheckCast(Value* that) {
2758 Utils::ApiCheck(that->IsPromise(),
2759 "v8::Promise::Cast()",
2760 "Could not convert to promise");
2761}
2762
2763
2764void v8::Promise::Resolver::CheckCast(Value* that) {
2765 Utils::ApiCheck(that->IsPromise(),
2766 "v8::Promise::Resolver::Cast()",
2767 "Could not convert to promise resolver");
2768}
2769
2770
2771void v8::ArrayBuffer::CheckCast(Value* that) {
2772 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2773 Utils::ApiCheck(obj->IsJSArrayBuffer(),
2774 "v8::ArrayBuffer::Cast()",
2775 "Could not convert to ArrayBuffer");
2776}
2777
2778
2779void v8::ArrayBufferView::CheckCast(Value* that) {
2780 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2781 Utils::ApiCheck(obj->IsJSArrayBufferView(),
2782 "v8::ArrayBufferView::Cast()",
2783 "Could not convert to ArrayBufferView");
2784}
2785
2786
2787void v8::TypedArray::CheckCast(Value* that) {
2788 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2789 Utils::ApiCheck(obj->IsJSTypedArray(),
2790 "v8::TypedArray::Cast()",
2791 "Could not convert to TypedArray");
2792}
2793
2794
2795#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \
2796 void v8::Type##Array::CheckCast(Value* that) { \
2797 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
2798 Utils::ApiCheck(obj->IsJSTypedArray() && \
2799 i::JSTypedArray::cast(*obj)->type() == \
2800 kExternal##Type##Array, \
2801 "v8::" #Type "Array::Cast()", \
2802 "Could not convert to " #Type "Array"); \
2803 }
2804
2805
2806TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
2807
2808#undef CHECK_TYPED_ARRAY_CAST
2809
2810
2811void v8::DataView::CheckCast(Value* that) {
2812 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2813 Utils::ApiCheck(obj->IsJSDataView(),
2814 "v8::DataView::Cast()",
2815 "Could not convert to DataView");
Steve Blocka7e24c12009-10-30 11:49:00 +00002816}
2817
2818
2819void v8::Date::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002820 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002821 i::Isolate* isolate = NULL;
2822 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2823 Utils::ApiCheck(isolate != NULL &&
2824 obj->HasSpecificClassOf(isolate->heap()->Date_string()),
2825 "v8::Date::Cast()",
2826 "Could not convert to date");
Steve Blocka7e24c12009-10-30 11:49:00 +00002827}
2828
2829
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002830void v8::StringObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002831 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002832 i::Isolate* isolate = NULL;
2833 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2834 Utils::ApiCheck(isolate != NULL &&
2835 obj->HasSpecificClassOf(isolate->heap()->String_string()),
2836 "v8::StringObject::Cast()",
2837 "Could not convert to StringObject");
2838}
2839
2840
2841void v8::SymbolObject::CheckCast(v8::Value* that) {
2842 i::Handle<i::Object> obj = Utils::OpenHandle(that);
2843 i::Isolate* isolate = NULL;
2844 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2845 Utils::ApiCheck(isolate != NULL &&
2846 obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
2847 "v8::SymbolObject::Cast()",
2848 "Could not convert to SymbolObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002849}
2850
2851
2852void v8::NumberObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002853 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002854 i::Isolate* isolate = NULL;
2855 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2856 Utils::ApiCheck(isolate != NULL &&
2857 obj->HasSpecificClassOf(isolate->heap()->Number_string()),
2858 "v8::NumberObject::Cast()",
2859 "Could not convert to NumberObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002860}
2861
2862
2863void v8::BooleanObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002864 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002865 i::Isolate* isolate = NULL;
2866 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
2867 Utils::ApiCheck(isolate != NULL &&
2868 obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
2869 "v8::BooleanObject::Cast()",
2870 "Could not convert to BooleanObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002871}
2872
2873
Ben Murdochf87a2032010-10-22 12:50:53 +01002874void v8::RegExp::CheckCast(v8::Value* that) {
Ben Murdochf87a2032010-10-22 12:50:53 +01002875 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002876 Utils::ApiCheck(obj->IsJSRegExp(),
2877 "v8::RegExp::Cast()",
2878 "Could not convert to regular expression");
Ben Murdochf87a2032010-10-22 12:50:53 +01002879}
2880
2881
Steve Blocka7e24c12009-10-30 11:49:00 +00002882bool Value::BooleanValue() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002883 return Utils::OpenHandle(this)->BooleanValue();
Steve Blocka7e24c12009-10-30 11:49:00 +00002884}
2885
2886
2887double Value::NumberValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002888 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2889 i::Handle<i::Object> num;
2890 if (obj->IsNumber()) {
2891 num = obj;
2892 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002893 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002894 LOG_API(isolate, "NumberValue");
2895 ENTER_V8(isolate);
2896 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002897 has_pending_exception = !i::Execution::ToNumber(
2898 isolate, obj).ToHandle(&num);
2899 EXCEPTION_BAILOUT_CHECK(isolate, base::OS::nan_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00002900 }
2901 return num->Number();
2902}
2903
2904
2905int64_t Value::IntegerValue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002906 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2907 i::Handle<i::Object> num;
2908 if (obj->IsNumber()) {
2909 num = obj;
2910 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002911 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002912 LOG_API(isolate, "IntegerValue");
2913 ENTER_V8(isolate);
2914 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002915 has_pending_exception = !i::Execution::ToInteger(
2916 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002917 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002918 }
2919 if (num->IsSmi()) {
2920 return i::Smi::cast(*num)->value();
2921 } else {
2922 return static_cast<int64_t>(num->Number());
2923 }
2924}
2925
2926
2927Local<Int32> Value::ToInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002928 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2929 i::Handle<i::Object> num;
2930 if (obj->IsSmi()) {
2931 num = obj;
2932 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002933 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002934 LOG_API(isolate, "ToInt32");
2935 ENTER_V8(isolate);
2936 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002937 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002938 EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002939 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002940 return ToApiHandle<Int32>(num);
Steve Blocka7e24c12009-10-30 11:49:00 +00002941}
2942
2943
2944Local<Uint32> Value::ToUint32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002945 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2946 i::Handle<i::Object> num;
2947 if (obj->IsSmi()) {
2948 num = obj;
2949 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002950 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002951 LOG_API(isolate, "ToUInt32");
2952 ENTER_V8(isolate);
2953 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002954 has_pending_exception = !i::Execution::ToUint32(
2955 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01002956 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002957 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002958 return ToApiHandle<Uint32>(num);
Steve Blocka7e24c12009-10-30 11:49:00 +00002959}
2960
2961
2962Local<Uint32> Value::ToArrayIndex() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002963 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2964 if (obj->IsSmi()) {
2965 if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
2966 return Local<Uint32>();
2967 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002968 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002969 LOG_API(isolate, "ToArrayIndex");
2970 ENTER_V8(isolate);
2971 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002972 i::Handle<i::Object> string_obj;
2973 has_pending_exception = !i::Execution::ToString(
2974 isolate, obj).ToHandle(&string_obj);
Steve Block44f0eee2011-05-26 01:26:41 +01002975 EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002976 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
2977 uint32_t index;
2978 if (str->AsArrayIndex(&index)) {
2979 i::Handle<i::Object> value;
2980 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002981 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00002982 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01002983 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00002984 }
2985 return Utils::Uint32ToLocal(value);
2986 }
2987 return Local<Uint32>();
2988}
2989
2990
2991int32_t Value::Int32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002992 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2993 if (obj->IsSmi()) {
2994 return i::Smi::cast(*obj)->value();
2995 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002996 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002997 LOG_API(isolate, "Int32Value (slow)");
2998 ENTER_V8(isolate);
2999 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003000 i::Handle<i::Object> num;
3001 has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01003002 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00003003 if (num->IsSmi()) {
3004 return i::Smi::cast(*num)->value();
3005 } else {
3006 return static_cast<int32_t>(num->Number());
3007 }
3008 }
3009}
3010
3011
3012bool Value::Equals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003013 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003014 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
3015 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3016 "v8::Value::Equals()",
3017 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003018 return false;
3019 }
Steve Block44f0eee2011-05-26 01:26:41 +01003020 LOG_API(isolate, "Equals");
3021 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003022 i::Handle<i::Object> other = Utils::OpenHandle(*that);
Steve Block1e0659c2011-05-24 12:43:12 +01003023 // If both obj and other are JSObjects, we'd better compare by identity
3024 // immediately when going into JS builtin. The reason is Invoke
3025 // would overwrite global object receiver with global proxy.
3026 if (obj->IsJSObject() && other->IsJSObject()) {
3027 return *obj == *other;
3028 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003029 i::Handle<i::Object> args[] = { other };
Steve Block44f0eee2011-05-26 01:26:41 +01003030 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003031 i::Handle<i::Object> result;
3032 has_pending_exception = !CallV8HeapFunction(
3033 "EQUALS", obj, arraysize(args), args).ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01003034 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003035 return *result == i::Smi::FromInt(i::EQUAL);
3036}
3037
3038
3039bool Value::StrictEquals(Handle<Value> that) const {
Steve Block44f0eee2011-05-26 01:26:41 +01003040 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003041 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
3042 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3043 "v8::Value::StrictEquals()",
3044 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003045 return false;
3046 }
Steve Block44f0eee2011-05-26 01:26:41 +01003047 LOG_API(isolate, "StrictEquals");
Steve Blocka7e24c12009-10-30 11:49:00 +00003048 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3049 // Must check HeapNumber first, since NaN !== NaN.
3050 if (obj->IsHeapNumber()) {
3051 if (!other->IsNumber()) return false;
3052 double x = obj->Number();
3053 double y = other->Number();
3054 // Must check explicitly for NaN:s on Windows, but -0 works fine.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003055 return x == y && !std::isnan(x) && !std::isnan(y);
Steve Blocka7e24c12009-10-30 11:49:00 +00003056 } else if (*obj == *other) { // Also covers Booleans.
3057 return true;
3058 } else if (obj->IsSmi()) {
3059 return other->IsNumber() && obj->Number() == other->Number();
3060 } else if (obj->IsString()) {
3061 return other->IsString() &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003062 i::String::Equals(i::Handle<i::String>::cast(obj),
3063 i::Handle<i::String>::cast(other));
Steve Blocka7e24c12009-10-30 11:49:00 +00003064 } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
3065 return other->IsUndefined() || other->IsUndetectableObject();
3066 } else {
3067 return false;
3068 }
3069}
3070
3071
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003072bool Value::SameValue(Handle<Value> that) const {
3073 i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
3074 if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
3075 "v8::Value::SameValue()",
3076 "Reading from empty handle")) {
3077 return false;
3078 }
3079 i::Handle<i::Object> other = Utils::OpenHandle(*that);
3080 return obj->SameValue(*other);
3081}
3082
3083
Steve Blocka7e24c12009-10-30 11:49:00 +00003084uint32_t Value::Uint32Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00003085 i::Handle<i::Object> obj = Utils::OpenHandle(this);
3086 if (obj->IsSmi()) {
3087 return i::Smi::cast(*obj)->value();
3088 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003089 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01003090 LOG_API(isolate, "Uint32Value");
3091 ENTER_V8(isolate);
3092 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003093 i::Handle<i::Object> num;
3094 has_pending_exception = !i::Execution::ToUint32(
3095 isolate, obj).ToHandle(&num);
Steve Block44f0eee2011-05-26 01:26:41 +01003096 EXCEPTION_BAILOUT_CHECK(isolate, 0);
Steve Blocka7e24c12009-10-30 11:49:00 +00003097 if (num->IsSmi()) {
3098 return i::Smi::cast(*num)->value();
3099 } else {
3100 return static_cast<uint32_t>(num->Number());
3101 }
3102 }
3103}
3104
3105
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003106bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003107 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3108 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
3109 ENTER_V8(isolate);
3110 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003111 i::Handle<i::Object> self = Utils::OpenHandle(this);
3112 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3113 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003114 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003115 has_pending_exception =
3116 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
3117 i::SLOPPY).is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003118 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003119 return true;
3120}
3121
3122
Steve Block6ded16b2010-05-10 14:33:55 +01003123bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003124 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3125 ON_BAILOUT(isolate, "v8::Object::Set()", return false);
3126 ENTER_V8(isolate);
3127 i::HandleScope scope(isolate);
Steve Block6ded16b2010-05-10 14:33:55 +01003128 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3129 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003130 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003131 has_pending_exception = i::JSObject::SetElement(
3132 self, index, value_obj, NONE, i::SLOPPY).is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003133 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Block6ded16b2010-05-10 14:33:55 +01003134 return true;
3135}
3136
3137
Steve Blocka7e24c12009-10-30 11:49:00 +00003138bool v8::Object::ForceSet(v8::Handle<Value> key,
3139 v8::Handle<Value> value,
3140 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01003141 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3142 ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
3143 ENTER_V8(isolate);
3144 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003145 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3146 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3147 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Steve Block44f0eee2011-05-26 01:26:41 +01003148 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003149 has_pending_exception = i::Runtime::DefineObjectProperty(
Steve Blocka7e24c12009-10-30 11:49:00 +00003150 self,
3151 key_obj,
3152 value_obj,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003153 static_cast<PropertyAttributes>(attribs)).is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003154 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003155 return true;
3156}
3157
3158
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003159bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
3160 return ForceSet(v8::Handle<Value>(reinterpret_cast<Value*>(*key)),
3161 value, DontEnum);
3162}
3163
3164
Steve Blocka7e24c12009-10-30 11:49:00 +00003165bool v8::Object::ForceDelete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003166 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3167 ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
3168 ENTER_V8(isolate);
3169 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003170 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3171 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb0fe1622011-05-05 13:52:32 +01003172
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003173 // When deleting a property on the global object using ForceDelete
3174 // deoptimize all functions as optimized code does not check for the hole
3175 // value with DontDelete properties. We have to deoptimize all contexts
3176 // because of possible cross-context inlined functions.
3177 if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
3178 i::Deoptimizer::DeoptimizeAll(isolate);
3179 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01003180
Steve Block44f0eee2011-05-26 01:26:41 +01003181 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003182 i::Handle<i::Object> obj;
3183 has_pending_exception = !i::Runtime::DeleteObjectProperty(
3184 isolate, self, key_obj, i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01003185 EXCEPTION_BAILOUT_CHECK(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003186 return obj->IsTrue();
3187}
3188
3189
3190Local<Value> v8::Object::Get(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003191 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3192 ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
3193 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003194 i::Handle<i::Object> self = Utils::OpenHandle(this);
3195 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Steve Block44f0eee2011-05-26 01:26:41 +01003196 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003197 i::Handle<i::Object> result;
3198 has_pending_exception =
3199 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01003200 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003201 return Utils::ToLocal(result);
3202}
3203
3204
Steve Block6ded16b2010-05-10 14:33:55 +01003205Local<Value> v8::Object::Get(uint32_t index) {
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 Block6ded16b2010-05-10 14:33:55 +01003209 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003210 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003211 i::Handle<i::Object> result;
3212 has_pending_exception =
3213 !i::Object::GetElement(isolate, self, index).ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01003214 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Block6ded16b2010-05-10 14:33:55 +01003215 return Utils::ToLocal(result);
3216}
3217
3218
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003219Local<Value> v8::Object::GetPrivate(v8::Handle<Private> key) {
3220 return Get(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3221}
3222
3223
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003224PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
3225 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003226 ON_BAILOUT(isolate, "v8::Object::GetPropertyAttributes()",
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003227 return static_cast<PropertyAttribute>(NONE));
3228 ENTER_V8(isolate);
3229 i::HandleScope scope(isolate);
3230 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3231 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003232 if (!key_obj->IsName()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003233 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003234 has_pending_exception = !i::Execution::ToString(
3235 isolate, key_obj).ToHandle(&key_obj);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003236 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3237 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003238 i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
3239 EXCEPTION_PREAMBLE(isolate);
3240 Maybe<PropertyAttributes> result =
3241 i::JSReceiver::GetPropertyAttributes(self, key_name);
3242 has_pending_exception = !result.has_value;
3243 EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
3244 if (result.value == ABSENT) return static_cast<PropertyAttribute>(NONE);
3245 return static_cast<PropertyAttribute>(result.value);
3246}
3247
3248
3249Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) {
3250 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3251 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyDescriptor()",
3252 return Local<Value>());
3253 ENTER_V8(isolate);
3254 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3255 i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
3256 i::Handle<i::Object> args[] = { obj, key_name };
3257 EXCEPTION_PREAMBLE(isolate);
3258 i::Handle<i::Object> result;
3259 has_pending_exception = !CallV8HeapFunction(
3260 "ObjectGetOwnPropertyDescriptor",
3261 isolate->factory()->undefined_value(),
3262 arraysize(args),
3263 args).ToHandle(&result);
3264 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3265 return Utils::ToLocal(result);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003266}
3267
3268
Steve Blocka7e24c12009-10-30 11:49:00 +00003269Local<Value> v8::Object::GetPrototype() {
Steve Block44f0eee2011-05-26 01:26:41 +01003270 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003271 ON_BAILOUT(isolate, "v8::Object::GetPrototype()", return Local<v8::Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01003272 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003273 i::Handle<i::Object> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003274 i::PrototypeIterator iter(isolate, self);
3275 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
Steve Blocka7e24c12009-10-30 11:49:00 +00003276}
3277
3278
Andrei Popescu402d9372010-02-26 13:31:12 +00003279bool v8::Object::SetPrototype(Handle<Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003280 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3281 ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
3282 ENTER_V8(isolate);
Andrei Popescu402d9372010-02-26 13:31:12 +00003283 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3284 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003285 // We do not allow exceptions thrown while setting the prototype
3286 // to propagate outside.
3287 TryCatch try_catch;
Steve Block44f0eee2011-05-26 01:26:41 +01003288 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003289 i::MaybeHandle<i::Object> result =
3290 i::JSObject::SetPrototype(self, value_obj, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00003291 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003292 EXCEPTION_BAILOUT_CHECK(isolate, false);
Andrei Popescu402d9372010-02-26 13:31:12 +00003293 return true;
3294}
3295
3296
Steve Blocka7e24c12009-10-30 11:49:00 +00003297Local<Object> v8::Object::FindInstanceInPrototypeChain(
3298 v8::Handle<FunctionTemplate> tmpl) {
Steve Block44f0eee2011-05-26 01:26:41 +01003299 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3300 ON_BAILOUT(isolate,
3301 "v8::Object::FindInstanceInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003302 return Local<v8::Object>());
Steve Block44f0eee2011-05-26 01:26:41 +01003303 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003304 i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this),
3305 i::PrototypeIterator::START_AT_RECEIVER);
Steve Blocka7e24c12009-10-30 11:49:00 +00003306 i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003307 while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) {
3308 iter.Advance();
3309 if (iter.IsAtEnd()) {
3310 return Local<Object>();
3311 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003312 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003313 return Utils::ToLocal(
3314 i::handle(i::JSObject::cast(iter.GetCurrent()), isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00003315}
3316
3317
3318Local<Array> v8::Object::GetPropertyNames() {
Steve Block44f0eee2011-05-26 01:26:41 +01003319 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3320 ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
3321 return Local<v8::Array>());
3322 ENTER_V8(isolate);
3323 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003324 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003325 EXCEPTION_PREAMBLE(isolate);
3326 i::Handle<i::FixedArray> value;
3327 has_pending_exception = !i::JSReceiver::GetKeys(
3328 self, i::JSReceiver::INCLUDE_PROTOS).ToHandle(&value);
3329 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003330 // Because we use caching to speed up enumeration it is important
3331 // to never change the result of the basic enumeration function so
3332 // we clone the result.
Steve Block44f0eee2011-05-26 01:26:41 +01003333 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3334 i::Handle<i::JSArray> result =
3335 isolate->factory()->NewJSArrayWithElements(elms);
3336 return Utils::ToLocal(scope.CloseAndEscape(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003337}
3338
3339
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003340Local<Array> v8::Object::GetOwnPropertyNames() {
3341 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3342 ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
3343 return Local<v8::Array>());
3344 ENTER_V8(isolate);
3345 i::HandleScope scope(isolate);
3346 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003347 EXCEPTION_PREAMBLE(isolate);
3348 i::Handle<i::FixedArray> value;
3349 has_pending_exception = !i::JSReceiver::GetKeys(
3350 self, i::JSReceiver::OWN_ONLY).ToHandle(&value);
3351 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003352 // Because we use caching to speed up enumeration it is important
3353 // to never change the result of the basic enumeration function so
3354 // we clone the result.
3355 i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
3356 i::Handle<i::JSArray> result =
3357 isolate->factory()->NewJSArrayWithElements(elms);
3358 return Utils::ToLocal(scope.CloseAndEscape(result));
3359}
3360
3361
Steve Blocka7e24c12009-10-30 11:49:00 +00003362Local<String> v8::Object::ObjectProtoToString() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003363 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
3364 Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
3365 ON_BAILOUT(i_isolate, "v8::Object::ObjectProtoToString()",
Steve Block44f0eee2011-05-26 01:26:41 +01003366 return Local<v8::String>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003367 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003368 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3369
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003370 i::Handle<i::Object> name(self->class_name(), i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003371
3372 // Native implementation of Object.prototype.toString (v8natives.js):
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003373 // var c = %_ClassOf(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003374 // if (c === 'Arguments') c = 'Object';
3375 // return "[object " + c + "]";
3376
3377 if (!name->IsString()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003378 return v8::String::NewFromUtf8(isolate, "[object ]");
Steve Blocka7e24c12009-10-30 11:49:00 +00003379 } else {
3380 i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003381 if (i::String::Equals(class_name,
3382 i_isolate->factory()->Arguments_string())) {
3383 return v8::String::NewFromUtf8(isolate, "[object Object]");
Steve Blocka7e24c12009-10-30 11:49:00 +00003384 } else {
3385 const char* prefix = "[object ";
3386 Local<String> str = Utils::ToLocal(class_name);
3387 const char* postfix = "]";
3388
Steve Blockd0582a62009-12-15 09:54:21 +00003389 int prefix_len = i::StrLength(prefix);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003390 int str_len = str->Utf8Length();
Steve Blockd0582a62009-12-15 09:54:21 +00003391 int postfix_len = i::StrLength(postfix);
Steve Blocka7e24c12009-10-30 11:49:00 +00003392
Steve Blockd0582a62009-12-15 09:54:21 +00003393 int buf_len = prefix_len + str_len + postfix_len;
Kristian Monsen25f61362010-05-21 11:50:48 +01003394 i::ScopedVector<char> buf(buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00003395
3396 // Write prefix.
Kristian Monsen25f61362010-05-21 11:50:48 +01003397 char* ptr = buf.start();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003398 i::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003399 ptr += prefix_len;
3400
3401 // Write real content.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003402 str->WriteUtf8(ptr, str_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00003403 ptr += str_len;
3404
3405 // Write postfix.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003406 i::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
Steve Blocka7e24c12009-10-30 11:49:00 +00003407
3408 // Copy the buffer into a heap-allocated string and return it.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003409 Local<String> result = v8::String::NewFromUtf8(
3410 isolate, buf.start(), String::kNormalString, buf_len);
Steve Blocka7e24c12009-10-30 11:49:00 +00003411 return result;
3412 }
3413 }
3414}
3415
3416
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003417Local<String> v8::Object::GetConstructorName() {
Steve Block44f0eee2011-05-26 01:26:41 +01003418 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3419 ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
3420 return Local<v8::String>());
3421 ENTER_V8(isolate);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003422 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
3423 i::Handle<i::String> name(self->constructor_name());
3424 return Utils::ToLocal(name);
3425}
3426
3427
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003428bool v8::Object::Delete(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003429 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3430 ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
3431 ENTER_V8(isolate);
3432 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003433 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003434 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3435 EXCEPTION_PREAMBLE(isolate);
3436 i::Handle<i::Object> obj;
3437 has_pending_exception = !i::Runtime::DeleteObjectProperty(
3438 isolate, self, key_obj, i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
3439 EXCEPTION_BAILOUT_CHECK(isolate, false);
3440 return obj->IsTrue();
Steve Blocka7e24c12009-10-30 11:49:00 +00003441}
3442
3443
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003444bool v8::Object::DeletePrivate(v8::Handle<Private> key) {
3445 return Delete(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
3446}
3447
3448
3449bool v8::Object::Has(v8::Handle<Value> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003450 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3451 ON_BAILOUT(isolate, "v8::Object::Has()", return false);
3452 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003453 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3454 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3455 EXCEPTION_PREAMBLE(isolate);
3456 i::Handle<i::Object> obj;
3457 has_pending_exception = !i::Runtime::HasObjectProperty(
3458 isolate, self, key_obj).ToHandle(&obj);
3459 EXCEPTION_BAILOUT_CHECK(isolate, false);
3460 return obj->IsTrue();
3461}
3462
3463
3464bool v8::Object::HasPrivate(v8::Handle<Private> key) {
3465 // TODO(rossberg): this should use HasOwnProperty, but we'd need to
3466 // generalise that to a (noy yet existant) Name argument first.
3467 return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
Steve Blocka7e24c12009-10-30 11:49:00 +00003468}
3469
3470
3471bool v8::Object::Delete(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01003472 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3473 ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
3474 return false);
3475 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003476 HandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00003477 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003478
3479 EXCEPTION_PREAMBLE(isolate);
3480 i::Handle<i::Object> obj;
3481 has_pending_exception =
3482 !i::JSReceiver::DeleteElement(self, index).ToHandle(&obj);
3483 EXCEPTION_BAILOUT_CHECK(isolate, false);
3484 return obj->IsTrue();
Steve Blocka7e24c12009-10-30 11:49:00 +00003485}
3486
3487
3488bool v8::Object::Has(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01003489 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3490 ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003491 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003492 EXCEPTION_PREAMBLE(isolate);
3493 Maybe<bool> maybe = i::JSReceiver::HasElement(self, index);
3494 has_pending_exception = !maybe.has_value;
3495 EXCEPTION_BAILOUT_CHECK(isolate, false);
3496 return maybe.value;
3497}
3498
3499
3500template<typename Getter, typename Setter, typename Data>
3501static inline bool ObjectSetAccessor(Object* obj,
3502 Handle<Name> name,
3503 Getter getter,
3504 Setter setter,
3505 Data data,
3506 AccessControl settings,
3507 PropertyAttribute attributes) {
3508 i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate();
3509 ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
3510 ENTER_V8(isolate);
3511 i::HandleScope scope(isolate);
3512 v8::Handle<AccessorSignature> signature;
3513 i::Handle<i::AccessorInfo> info = MakeAccessorInfo(
3514 name, getter, setter, data, settings, attributes, signature);
3515 if (info.is_null()) return false;
3516 bool fast = Utils::OpenHandle(obj)->HasFastProperties();
3517 i::Handle<i::Object> result;
3518 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
3519 isolate, result,
3520 i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
3521 false);
3522 if (result->IsUndefined()) return false;
3523 if (fast) i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0);
3524 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003525}
3526
3527
Leon Clarkef7060e22010-06-03 12:02:55 +01003528bool Object::SetAccessor(Handle<String> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003529 AccessorGetterCallback getter,
3530 AccessorSetterCallback setter,
Leon Clarkef7060e22010-06-03 12:02:55 +01003531 v8::Handle<Value> data,
3532 AccessControl settings,
3533 PropertyAttribute attributes) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003534 return ObjectSetAccessor(
3535 this, name, getter, setter, data, settings, attributes);
3536}
3537
3538
3539bool Object::SetAccessor(Handle<Name> name,
3540 AccessorNameGetterCallback getter,
3541 AccessorNameSetterCallback setter,
3542 v8::Handle<Value> data,
3543 AccessControl settings,
3544 PropertyAttribute attributes) {
3545 return ObjectSetAccessor(
3546 this, name, getter, setter, data, settings, attributes);
3547}
3548
3549
3550bool Object::SetDeclaredAccessor(Local<Name> name,
3551 Local<DeclaredAccessorDescriptor> descriptor,
3552 PropertyAttribute attributes,
3553 AccessControl settings) {
3554 void* null = NULL;
3555 return ObjectSetAccessor(
3556 this, name, descriptor, null, null, settings, attributes);
3557}
3558
3559
3560void Object::SetAccessorProperty(Local<Name> name,
3561 Local<Function> getter,
3562 Handle<Function> setter,
3563 PropertyAttribute attribute,
3564 AccessControl settings) {
3565 // TODO(verwaest): Remove |settings|.
3566 DCHECK_EQ(v8::DEFAULT, settings);
Steve Block44f0eee2011-05-26 01:26:41 +01003567 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003568 ON_BAILOUT(isolate, "v8::Object::SetAccessorProperty()", return);
Steve Block44f0eee2011-05-26 01:26:41 +01003569 ENTER_V8(isolate);
3570 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003571 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
3572 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
3573 if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
3574 i::JSObject::DefineAccessor(v8::Utils::OpenHandle(this),
3575 v8::Utils::OpenHandle(*name),
3576 getter_i,
3577 setter_i,
3578 static_cast<PropertyAttributes>(attribute));
Leon Clarkef7060e22010-06-03 12:02:55 +01003579}
3580
3581
Ben Murdoch257744e2011-11-30 15:57:28 +00003582bool v8::Object::HasOwnProperty(Handle<String> key) {
3583 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3584 ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
3585 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003586 EXCEPTION_PREAMBLE(isolate);
3587 Maybe<bool> maybe = i::JSReceiver::HasOwnProperty(Utils::OpenHandle(this),
3588 Utils::OpenHandle(*key));
3589 has_pending_exception = !maybe.has_value;
3590 EXCEPTION_BAILOUT_CHECK(isolate, false);
3591 return maybe.value;
Ben Murdoch257744e2011-11-30 15:57:28 +00003592}
3593
3594
Steve Blocka7e24c12009-10-30 11:49:00 +00003595bool v8::Object::HasRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003596 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3597 ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
3598 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003599 EXCEPTION_PREAMBLE(isolate);
3600 Maybe<bool> maybe = i::JSObject::HasRealNamedProperty(
3601 Utils::OpenHandle(this), Utils::OpenHandle(*key));
3602 has_pending_exception = !maybe.has_value;
3603 EXCEPTION_BAILOUT_CHECK(isolate, false);
3604 return maybe.value;
Steve Blocka7e24c12009-10-30 11:49:00 +00003605}
3606
3607
3608bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003609 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3610 ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
Steve Block44f0eee2011-05-26 01:26:41 +01003611 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003612 EXCEPTION_PREAMBLE(isolate);
3613 Maybe<bool> maybe =
3614 i::JSObject::HasRealElementProperty(Utils::OpenHandle(this), index);
3615 has_pending_exception = !maybe.has_value;
3616 EXCEPTION_BAILOUT_CHECK(isolate, false);
3617 return maybe.value;
Steve Blocka7e24c12009-10-30 11:49:00 +00003618}
3619
3620
3621bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003622 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3623 ON_BAILOUT(isolate,
3624 "v8::Object::HasRealNamedCallbackProperty()",
3625 return false);
3626 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003627 EXCEPTION_PREAMBLE(isolate);
3628 Maybe<bool> maybe = i::JSObject::HasRealNamedCallbackProperty(
3629 Utils::OpenHandle(this), Utils::OpenHandle(*key));
3630 has_pending_exception = !maybe.has_value;
3631 EXCEPTION_BAILOUT_CHECK(isolate, false);
3632 return maybe.value;
Steve Blocka7e24c12009-10-30 11:49:00 +00003633}
3634
3635
3636bool v8::Object::HasNamedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003637 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3638 ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
3639 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003640 return Utils::OpenHandle(this)->HasNamedInterceptor();
3641}
3642
3643
3644bool v8::Object::HasIndexedLookupInterceptor() {
Steve Block44f0eee2011-05-26 01:26:41 +01003645 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3646 ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
3647 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003648 return Utils::OpenHandle(this)->HasIndexedInterceptor();
3649}
3650
3651
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003652static Local<Value> GetPropertyByLookup(i::LookupIterator* it) {
3653 // If the property being looked up is a callback, it can throw an exception.
3654 EXCEPTION_PREAMBLE(it->isolate());
3655 i::Handle<i::Object> result;
3656 has_pending_exception = !i::Object::GetProperty(it).ToHandle(&result);
3657 EXCEPTION_BAILOUT_CHECK(it->isolate(), Local<Value>());
Ben Murdoch8b112d22011-06-08 16:22:53 +01003658
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003659 if (it->IsFound()) return Utils::ToLocal(result);
3660 return Local<Value>();
Ben Murdoch8b112d22011-06-08 16:22:53 +01003661}
3662
3663
Steve Blocka7e24c12009-10-30 11:49:00 +00003664Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003665 Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003666 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3667 ON_BAILOUT(isolate,
3668 "v8::Object::GetRealNamedPropertyInPrototypeChain()",
Steve Blocka7e24c12009-10-30 11:49:00 +00003669 return Local<Value>());
Steve Block44f0eee2011-05-26 01:26:41 +01003670 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003671 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3672 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003673 i::PrototypeIterator iter(isolate, self_obj);
3674 if (iter.IsAtEnd()) return Local<Value>();
3675 i::Handle<i::Object> proto = i::PrototypeIterator::GetCurrent(iter);
3676 i::LookupIterator it(self_obj, key_obj, i::Handle<i::JSReceiver>::cast(proto),
3677 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3678 return GetPropertyByLookup(&it);
Steve Blocka7e24c12009-10-30 11:49:00 +00003679}
3680
3681
3682Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003683 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3684 ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
3685 return Local<Value>());
3686 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003687 i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
3688 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003689 i::LookupIterator it(self_obj, key_obj,
3690 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
3691 return GetPropertyByLookup(&it);
Steve Blocka7e24c12009-10-30 11:49:00 +00003692}
3693
3694
3695// Turns on access checks by copying the map and setting the check flag.
3696// Because the object gets a new map, existing inline cache caching
3697// the old map of this object will fail.
3698void v8::Object::TurnOnAccessCheck() {
Steve Block44f0eee2011-05-26 01:26:41 +01003699 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3700 ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
3701 ENTER_V8(isolate);
3702 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003703 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3704
Ben Murdochb0fe1622011-05-05 13:52:32 +01003705 // When turning on access checks for a global object deoptimize all functions
3706 // as optimized code does not always handle access checks.
3707 i::Deoptimizer::DeoptimizeGlobalObject(*obj);
3708
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003709 i::Handle<i::Map> new_map = i::Map::Copy(i::Handle<i::Map>(obj->map()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003710 new_map->set_is_access_check_needed(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003711 i::JSObject::MigrateToMap(obj, new_map);
Steve Blocka7e24c12009-10-30 11:49:00 +00003712}
3713
3714
3715bool v8::Object::IsDirty() {
3716 return Utils::OpenHandle(this)->IsDirty();
3717}
3718
3719
3720Local<v8::Object> v8::Object::Clone() {
Steve Block44f0eee2011-05-26 01:26:41 +01003721 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3722 ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
3723 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003724 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003725 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003726 i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00003727 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01003728 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00003729 return Utils::ToLocal(result);
3730}
3731
3732
Ben Murdoch8b112d22011-06-08 16:22:53 +01003733Local<v8::Context> v8::Object::CreationContext() {
3734 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3735 ON_BAILOUT(isolate,
3736 "v8::Object::CreationContext()", return Local<v8::Context>());
3737 ENTER_V8(isolate);
3738 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003739 i::Context* context = self->GetCreationContext();
Ben Murdoch8b112d22011-06-08 16:22:53 +01003740 return Utils::ToLocal(i::Handle<i::Context>(context));
3741}
3742
3743
Steve Blocka7e24c12009-10-30 11:49:00 +00003744int v8::Object::GetIdentityHash() {
Steve Block44f0eee2011-05-26 01:26:41 +01003745 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3746 ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
3747 ENTER_V8(isolate);
3748 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003749 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003750 return i::JSReceiver::GetOrCreateIdentityHash(self)->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00003751}
3752
3753
3754bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
3755 v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01003756 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3757 ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003758 if (value.IsEmpty()) return DeleteHiddenValue(key);
Steve Block44f0eee2011-05-26 01:26:41 +01003759 ENTER_V8(isolate);
3760 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003761 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003762 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003763 i::Handle<i::String> key_string =
3764 isolate->factory()->InternalizeString(key_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00003765 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003766 i::Handle<i::Object> result =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003767 i::JSObject::SetHiddenProperty(self, key_string, value_obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003768 return *result == *self;
Steve Blocka7e24c12009-10-30 11:49:00 +00003769}
3770
3771
3772v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003773 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3774 ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
3775 return Local<v8::Value>());
3776 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003777 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003778 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003779 i::Handle<i::String> key_string =
3780 isolate->factory()->InternalizeString(key_obj);
3781 i::Handle<i::Object> result(self->GetHiddenProperty(key_string), isolate);
3782 if (result->IsTheHole()) return v8::Local<v8::Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +00003783 return Utils::ToLocal(result);
3784}
3785
3786
3787bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01003788 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3789 ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
3790 ENTER_V8(isolate);
3791 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003792 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003793 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003794 i::Handle<i::String> key_string =
3795 isolate->factory()->InternalizeString(key_obj);
3796 i::JSObject::DeleteHiddenProperty(self, key_string);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003797 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00003798}
3799
3800
Steve Block44f0eee2011-05-26 01:26:41 +01003801namespace {
3802
Ben Murdoch589d6972011-11-30 16:04:58 +00003803static i::ElementsKind GetElementsKindFromExternalArrayType(
3804 ExternalArrayType array_type) {
3805 switch (array_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003806#define ARRAY_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \
3807 case kExternal##Type##Array: \
3808 return i::EXTERNAL_##TYPE##_ELEMENTS;
3809
3810 TYPED_ARRAYS(ARRAY_TYPE_TO_ELEMENTS_KIND)
3811#undef ARRAY_TYPE_TO_ELEMENTS_KIND
Ben Murdoch589d6972011-11-30 16:04:58 +00003812 }
3813 UNREACHABLE();
3814 return i::DICTIONARY_ELEMENTS;
3815}
3816
3817
Steve Block44f0eee2011-05-26 01:26:41 +01003818void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
3819 void* data,
3820 ExternalArrayType array_type,
3821 int length) {
3822 i::Isolate* isolate = object->GetIsolate();
3823 i::Handle<i::ExternalArray> array =
3824 isolate->factory()->NewExternalArray(length, array_type, data);
3825
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003826 i::Handle<i::Map> external_array_map =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003827 i::JSObject::GetElementsTransitionMap(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003828 object,
3829 GetElementsKindFromExternalArrayType(array_type));
3830
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003831 i::JSObject::SetMapAndElements(object, external_array_map, array);
Steve Block44f0eee2011-05-26 01:26:41 +01003832}
3833
3834} // namespace
3835
3836
Steve Blocka7e24c12009-10-30 11:49:00 +00003837void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003838 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3839 ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
3840 ENTER_V8(isolate);
3841 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003842 if (!Utils::ApiCheck(length >= 0 &&
3843 length <= i::ExternalUint8ClampedArray::kMaxLength,
3844 "v8::Object::SetIndexedPropertiesToPixelData()",
3845 "length exceeds max acceptable value")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003846 return;
3847 }
3848 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003849 if (!Utils::ApiCheck(!self->IsJSArray(),
3850 "v8::Object::SetIndexedPropertiesToPixelData()",
3851 "JSArray is not supported")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003852 return;
3853 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003854 PrepareExternalArrayElements(self, data, kExternalUint8ClampedArray, length);
Steve Blocka7e24c12009-10-30 11:49:00 +00003855}
3856
3857
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003858bool v8::Object::HasIndexedPropertiesInPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003859 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003860 ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
3861 return false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003862 return self->HasExternalUint8ClampedElements();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003863}
3864
3865
3866uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003867 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003868 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
3869 return NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003870 if (self->HasExternalUint8ClampedElements()) {
3871 return i::ExternalUint8ClampedArray::cast(self->elements())->
3872 external_uint8_clamped_pointer();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003873 } else {
3874 return NULL;
3875 }
3876}
3877
3878
3879int v8::Object::GetIndexedPropertiesPixelDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003880 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003881 ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
3882 return -1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003883 if (self->HasExternalUint8ClampedElements()) {
3884 return i::ExternalUint8ClampedArray::cast(self->elements())->length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003885 } else {
3886 return -1;
3887 }
3888}
3889
Ben Murdoch589d6972011-11-30 16:04:58 +00003890
Steve Block3ce2e202009-11-05 08:53:23 +00003891void v8::Object::SetIndexedPropertiesToExternalArrayData(
3892 void* data,
3893 ExternalArrayType array_type,
3894 int length) {
Steve Block44f0eee2011-05-26 01:26:41 +01003895 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3896 ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
3897 ENTER_V8(isolate);
3898 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003899 if (!Utils::ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
3900 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3901 "length exceeds max acceptable value")) {
Steve Block3ce2e202009-11-05 08:53:23 +00003902 return;
3903 }
3904 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003905 if (!Utils::ApiCheck(!self->IsJSArray(),
3906 "v8::Object::SetIndexedPropertiesToExternalArrayData()",
3907 "JSArray is not supported")) {
Steve Block3ce2e202009-11-05 08:53:23 +00003908 return;
3909 }
Steve Block44f0eee2011-05-26 01:26:41 +01003910 PrepareExternalArrayElements(self, data, array_type, length);
Steve Block3ce2e202009-11-05 08:53:23 +00003911}
3912
3913
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003914bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003915 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003916 ON_BAILOUT(self->GetIsolate(),
3917 "v8::HasIndexedPropertiesInExternalArrayData()",
3918 return false);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003919 return self->HasExternalArrayElements();
3920}
3921
3922
3923void* v8::Object::GetIndexedPropertiesExternalArrayData() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003924 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003925 ON_BAILOUT(self->GetIsolate(),
3926 "v8::GetIndexedPropertiesExternalArrayData()",
3927 return NULL);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003928 if (self->HasExternalArrayElements()) {
3929 return i::ExternalArray::cast(self->elements())->external_pointer();
3930 } else {
3931 return NULL;
3932 }
3933}
3934
3935
3936ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003937 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003938 ON_BAILOUT(self->GetIsolate(),
3939 "v8::GetIndexedPropertiesExternalArrayDataType()",
3940 return static_cast<ExternalArrayType>(-1));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003941 switch (self->elements()->map()->instance_type()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003942#define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \
3943 case i::EXTERNAL_##TYPE##_ARRAY_TYPE: \
3944 return kExternal##Type##Array;
3945 TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
3946#undef INSTANCE_TYPE_TO_ARRAY_TYPE
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003947 default:
3948 return static_cast<ExternalArrayType>(-1);
3949 }
3950}
3951
3952
3953int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003954 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01003955 ON_BAILOUT(self->GetIsolate(),
3956 "v8::GetIndexedPropertiesExternalArrayDataLength()",
3957 return 0);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01003958 if (self->HasExternalArrayElements()) {
3959 return i::ExternalArray::cast(self->elements())->length();
3960 } else {
3961 return -1;
3962 }
3963}
3964
3965
Ben Murdoch257744e2011-11-30 15:57:28 +00003966bool v8::Object::IsCallable() {
3967 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3968 ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
3969 ENTER_V8(isolate);
3970 i::HandleScope scope(isolate);
3971 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003972 return obj->IsCallable();
Ben Murdoch257744e2011-11-30 15:57:28 +00003973}
3974
3975
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003976Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003977 int argc,
Ben Murdoch257744e2011-11-30 15:57:28 +00003978 v8::Handle<v8::Value> argv[]) {
3979 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
3980 ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
3981 return Local<v8::Value>());
3982 LOG_API(isolate, "Object::CallAsFunction");
3983 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003984 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00003985 i::HandleScope scope(isolate);
3986 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
3987 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
3988 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003989 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch257744e2011-11-30 15:57:28 +00003990 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
3991 if (obj->IsJSFunction()) {
3992 fun = i::Handle<i::JSFunction>::cast(obj);
3993 } else {
3994 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003995 i::Handle<i::Object> delegate;
3996 has_pending_exception = !i::Execution::TryGetFunctionDelegate(
3997 isolate, obj).ToHandle(&delegate);
Ben Murdoch257744e2011-11-30 15:57:28 +00003998 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
3999 fun = i::Handle<i::JSFunction>::cast(delegate);
4000 recv_obj = obj;
4001 }
4002 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004003 i::Handle<i::Object> returned;
4004 has_pending_exception = !i::Execution::Call(
4005 isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004006 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
Ben Murdoch257744e2011-11-30 15:57:28 +00004007 return Utils::ToLocal(scope.CloseAndEscape(returned));
4008}
4009
4010
4011Local<v8::Value> Object::CallAsConstructor(int argc,
4012 v8::Handle<v8::Value> argv[]) {
4013 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4014 ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
4015 return Local<v8::Object>());
4016 LOG_API(isolate, "Object::CallAsConstructor");
4017 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004018 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00004019 i::HandleScope scope(isolate);
4020 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4021 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004022 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch257744e2011-11-30 15:57:28 +00004023 if (obj->IsJSFunction()) {
4024 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
4025 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004026 i::Handle<i::Object> returned;
4027 has_pending_exception = !i::Execution::New(
4028 fun, argc, args).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004029 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
Ben Murdoch257744e2011-11-30 15:57:28 +00004030 return Utils::ToLocal(scope.CloseAndEscape(
4031 i::Handle<i::JSObject>::cast(returned)));
4032 }
4033 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004034 i::Handle<i::Object> delegate;
4035 has_pending_exception = !i::Execution::TryGetConstructorDelegate(
4036 isolate, obj).ToHandle(&delegate);
Ben Murdoch257744e2011-11-30 15:57:28 +00004037 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
4038 if (!delegate->IsUndefined()) {
4039 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
4040 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004041 i::Handle<i::Object> returned;
4042 has_pending_exception = !i::Execution::Call(
4043 isolate, fun, obj, argc, args).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004044 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004045 DCHECK(!delegate->IsUndefined());
Ben Murdoch257744e2011-11-30 15:57:28 +00004046 return Utils::ToLocal(scope.CloseAndEscape(returned));
4047 }
4048 return Local<v8::Object>();
4049}
4050
4051
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004052Local<Function> Function::New(Isolate* v8_isolate,
4053 FunctionCallback callback,
4054 Local<Value> data,
4055 int length) {
4056 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
4057 LOG_API(isolate, "Function::New");
4058 ENTER_V8(isolate);
4059 return FunctionTemplateNew(
4060 isolate, callback, data, Local<Signature>(), length, true)->
4061 GetFunction();
4062}
4063
4064
Steve Blocka7e24c12009-10-30 11:49:00 +00004065Local<v8::Object> Function::NewInstance() const {
4066 return NewInstance(0, NULL);
4067}
4068
4069
4070Local<v8::Object> Function::NewInstance(int argc,
4071 v8::Handle<v8::Value> argv[]) const {
Steve Block44f0eee2011-05-26 01:26:41 +01004072 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4073 ON_BAILOUT(isolate, "v8::Function::NewInstance()",
4074 return Local<v8::Object>());
4075 LOG_API(isolate, "Function::NewInstance");
4076 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004077 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4078 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00004079 i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
4080 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004081 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Steve Block44f0eee2011-05-26 01:26:41 +01004082 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004083 i::Handle<i::Object> returned;
4084 has_pending_exception = !i::Execution::New(
4085 function, argc, args).ToHandle(&returned);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004086 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004087 return scope.Escape(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
Steve Blocka7e24c12009-10-30 11:49:00 +00004088}
4089
4090
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004091Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
Steve Blocka7e24c12009-10-30 11:49:00 +00004092 v8::Handle<v8::Value> argv[]) {
Steve Block44f0eee2011-05-26 01:26:41 +01004093 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4094 ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
4095 LOG_API(isolate, "Function::Call");
4096 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004097 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
4098 i::HandleScope scope(isolate);
4099 i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
4100 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
4101 STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
4102 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4103 EXCEPTION_PREAMBLE(isolate);
4104 i::Handle<i::Object> returned;
4105 has_pending_exception = !i::Execution::Call(
4106 isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
4107 EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
4108 return Utils::ToLocal(scope.CloseAndEscape(returned));
Steve Blocka7e24c12009-10-30 11:49:00 +00004109}
4110
4111
4112void Function::SetName(v8::Handle<v8::String> name) {
Steve Block44f0eee2011-05-26 01:26:41 +01004113 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4114 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00004115 USE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00004116 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4117 func->shared()->set_name(*Utils::OpenHandle(*name));
4118}
4119
4120
4121Handle<Value> Function::GetName() const {
4122 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004123 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name(),
4124 func->GetIsolate()));
Steve Blocka7e24c12009-10-30 11:49:00 +00004125}
4126
4127
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004128Handle<Value> Function::GetInferredName() const {
4129 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004130 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4131 func->GetIsolate()));
4132}
4133
4134
4135Handle<Value> Function::GetDisplayName() const {
4136 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4137 ON_BAILOUT(isolate, "v8::Function::GetDisplayName()",
4138 return ToApiHandle<Primitive>(
4139 isolate->factory()->undefined_value()));
4140 ENTER_V8(isolate);
4141 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4142 i::Handle<i::String> property_name =
4143 isolate->factory()->InternalizeOneByteString(
4144 STATIC_CHAR_VECTOR("displayName"));
4145
4146 i::Handle<i::Object> value =
4147 i::JSObject::GetDataProperty(func, property_name);
4148 if (value->IsString()) {
4149 i::Handle<i::String> name = i::Handle<i::String>::cast(value);
4150 if (name->length() > 0) return Utils::ToLocal(name);
4151 }
4152
4153 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004154}
4155
4156
Andrei Popescu402d9372010-02-26 13:31:12 +00004157ScriptOrigin Function::GetScriptOrigin() const {
4158 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4159 if (func->shared()->script()->IsScript()) {
4160 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004161 i::Handle<i::Object> scriptName = i::Script::GetNameOrSourceURL(script);
4162 v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(func->GetIsolate());
Andrei Popescu402d9372010-02-26 13:31:12 +00004163 v8::ScriptOrigin origin(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004164 Utils::ToLocal(scriptName),
4165 v8::Integer::New(isolate, script->line_offset()->value()),
4166 v8::Integer::New(isolate, script->column_offset()->value()));
Andrei Popescu402d9372010-02-26 13:31:12 +00004167 return origin;
4168 }
4169 return v8::ScriptOrigin(Handle<Value>());
4170}
4171
4172
4173const int Function::kLineOffsetNotFound = -1;
4174
4175
4176int Function::GetScriptLineNumber() const {
4177 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4178 if (func->shared()->script()->IsScript()) {
4179 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004180 return i::Script::GetLineNumber(script, func->shared()->start_position());
Andrei Popescu402d9372010-02-26 13:31:12 +00004181 }
4182 return kLineOffsetNotFound;
4183}
4184
4185
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004186int Function::GetScriptColumnNumber() const {
4187 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4188 if (func->shared()->script()->IsScript()) {
4189 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004190 return i::Script::GetColumnNumber(script, func->shared()->start_position());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004191 }
4192 return kLineOffsetNotFound;
4193}
4194
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004195
4196bool Function::IsBuiltin() const {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004197 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004198 return func->IsBuiltin();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004199}
4200
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004201
4202int Function::ScriptId() const {
4203 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4204 if (!func->shared()->script()->IsScript()) {
4205 return v8::UnboundScript::kNoScriptId;
4206 }
4207 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
4208 return script->id()->value();
4209}
4210
4211
4212Local<v8::Value> Function::GetBoundFunction() const {
4213 i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
4214 if (!func->shared()->bound()) {
4215 return v8::Undefined(reinterpret_cast<v8::Isolate*>(func->GetIsolate()));
4216 }
4217 i::Handle<i::FixedArray> bound_args = i::Handle<i::FixedArray>(
4218 i::FixedArray::cast(func->function_bindings()));
4219 i::Handle<i::Object> original(
4220 bound_args->get(i::JSFunction::kBoundFunctionIndex),
4221 func->GetIsolate());
4222 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(original));
4223}
4224
4225
Steve Blocka7e24c12009-10-30 11:49:00 +00004226int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004227 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004228 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00004229}
4230
4231
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004232bool String::IsOneByte() const {
4233 i::Handle<i::String> str = Utils::OpenHandle(this);
4234 return str->HasOnlyOneByteChars();
4235}
4236
4237
4238// Helpers for ContainsOnlyOneByteHelper
4239template<size_t size> struct OneByteMask;
4240template<> struct OneByteMask<4> {
4241 static const uint32_t value = 0xFF00FF00;
4242};
4243template<> struct OneByteMask<8> {
4244 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4245};
4246static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4247static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4248static inline bool Unaligned(const uint16_t* chars) {
4249 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4250}
4251
4252
4253static inline const uint16_t* Align(const uint16_t* chars) {
4254 return reinterpret_cast<uint16_t*>(
4255 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4256}
4257
4258class ContainsOnlyOneByteHelper {
4259 public:
4260 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4261 bool Check(i::String* string) {
4262 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4263 if (cons_string == NULL) return is_one_byte_;
4264 return CheckCons(cons_string);
4265 }
4266 void VisitOneByteString(const uint8_t* chars, int length) {
4267 // Nothing to do.
4268 }
4269 void VisitTwoByteString(const uint16_t* chars, int length) {
4270 // Accumulated bits.
4271 uintptr_t acc = 0;
4272 // Align to uintptr_t.
4273 const uint16_t* end = chars + length;
4274 while (Unaligned(chars) && chars != end) {
4275 acc |= *chars++;
4276 }
4277 // Read word aligned in blocks,
4278 // checking the return value at the end of each block.
4279 const uint16_t* aligned_end = Align(end);
4280 const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4281 const int inner_loops = 16;
4282 while (chars + inner_loops*increment < aligned_end) {
4283 for (int i = 0; i < inner_loops; i++) {
4284 acc |= *reinterpret_cast<const uintptr_t*>(chars);
4285 chars += increment;
4286 }
4287 // Check for early return.
4288 if ((acc & kOneByteMask) != 0) {
4289 is_one_byte_ = false;
4290 return;
4291 }
4292 }
4293 // Read the rest.
4294 while (chars != end) {
4295 acc |= *chars++;
4296 }
4297 // Check result.
4298 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
4299 }
4300
4301 private:
4302 bool CheckCons(i::ConsString* cons_string) {
4303 while (true) {
4304 // Check left side if flat.
4305 i::String* left = cons_string->first();
4306 i::ConsString* left_as_cons =
4307 i::String::VisitFlat(this, left, 0);
4308 if (!is_one_byte_) return false;
4309 // Check right side if flat.
4310 i::String* right = cons_string->second();
4311 i::ConsString* right_as_cons =
4312 i::String::VisitFlat(this, right, 0);
4313 if (!is_one_byte_) return false;
4314 // Standard recurse/iterate trick.
4315 if (left_as_cons != NULL && right_as_cons != NULL) {
4316 if (left->length() < right->length()) {
4317 CheckCons(left_as_cons);
4318 cons_string = right_as_cons;
4319 } else {
4320 CheckCons(right_as_cons);
4321 cons_string = left_as_cons;
4322 }
4323 // Check fast return.
4324 if (!is_one_byte_) return false;
4325 continue;
4326 }
4327 // Descend left in place.
4328 if (left_as_cons != NULL) {
4329 cons_string = left_as_cons;
4330 continue;
4331 }
4332 // Descend right in place.
4333 if (right_as_cons != NULL) {
4334 cons_string = right_as_cons;
4335 continue;
4336 }
4337 // Terminate.
4338 break;
4339 }
4340 return is_one_byte_;
4341 }
4342 bool is_one_byte_;
4343 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4344};
4345
4346
4347bool String::ContainsOnlyOneByte() const {
4348 i::Handle<i::String> str = Utils::OpenHandle(this);
4349 if (str->HasOnlyOneByteChars()) return true;
4350 ContainsOnlyOneByteHelper helper;
4351 return helper.Check(*str);
4352}
4353
4354
4355class Utf8LengthHelper : public i::AllStatic {
4356 public:
4357 enum State {
4358 kEndsWithLeadingSurrogate = 1 << 0,
4359 kStartsWithTrailingSurrogate = 1 << 1,
4360 kLeftmostEdgeIsCalculated = 1 << 2,
4361 kRightmostEdgeIsCalculated = 1 << 3,
4362 kLeftmostEdgeIsSurrogate = 1 << 4,
4363 kRightmostEdgeIsSurrogate = 1 << 5
4364 };
4365
4366 static const uint8_t kInitialState = 0;
4367
4368 static inline bool EndsWithSurrogate(uint8_t state) {
4369 return state & kEndsWithLeadingSurrogate;
4370 }
4371
4372 static inline bool StartsWithSurrogate(uint8_t state) {
4373 return state & kStartsWithTrailingSurrogate;
4374 }
4375
4376 class Visitor {
4377 public:
4378 Visitor() : utf8_length_(0), state_(kInitialState) {}
4379
4380 void VisitOneByteString(const uint8_t* chars, int length) {
4381 int utf8_length = 0;
4382 // Add in length 1 for each non-Latin1 character.
4383 for (int i = 0; i < length; i++) {
4384 utf8_length += *chars++ >> 7;
4385 }
4386 // Add in length 1 for each character.
4387 utf8_length_ = utf8_length + length;
4388 state_ = kInitialState;
4389 }
4390
4391 void VisitTwoByteString(const uint16_t* chars, int length) {
4392 int utf8_length = 0;
4393 int last_character = unibrow::Utf16::kNoPreviousCharacter;
4394 for (int i = 0; i < length; i++) {
4395 uint16_t c = chars[i];
4396 utf8_length += unibrow::Utf8::Length(c, last_character);
4397 last_character = c;
4398 }
4399 utf8_length_ = utf8_length;
4400 uint8_t state = 0;
4401 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4402 state |= kStartsWithTrailingSurrogate;
4403 }
4404 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4405 state |= kEndsWithLeadingSurrogate;
4406 }
4407 state_ = state;
4408 }
4409
4410 static i::ConsString* VisitFlat(i::String* string,
4411 int* length,
4412 uint8_t* state) {
4413 Visitor visitor;
4414 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4415 *length = visitor.utf8_length_;
4416 *state = visitor.state_;
4417 return cons_string;
4418 }
4419
4420 private:
4421 int utf8_length_;
4422 uint8_t state_;
4423 DISALLOW_COPY_AND_ASSIGN(Visitor);
4424 };
4425
4426 static inline void MergeLeafLeft(int* length,
4427 uint8_t* state,
4428 uint8_t leaf_state) {
4429 bool edge_surrogate = StartsWithSurrogate(leaf_state);
4430 if (!(*state & kLeftmostEdgeIsCalculated)) {
4431 DCHECK(!(*state & kLeftmostEdgeIsSurrogate));
4432 *state |= kLeftmostEdgeIsCalculated
4433 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4434 } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4435 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4436 }
4437 if (EndsWithSurrogate(leaf_state)) {
4438 *state |= kEndsWithLeadingSurrogate;
4439 } else {
4440 *state &= ~kEndsWithLeadingSurrogate;
4441 }
4442 }
4443
4444 static inline void MergeLeafRight(int* length,
4445 uint8_t* state,
4446 uint8_t leaf_state) {
4447 bool edge_surrogate = EndsWithSurrogate(leaf_state);
4448 if (!(*state & kRightmostEdgeIsCalculated)) {
4449 DCHECK(!(*state & kRightmostEdgeIsSurrogate));
4450 *state |= (kRightmostEdgeIsCalculated
4451 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4452 } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4453 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4454 }
4455 if (StartsWithSurrogate(leaf_state)) {
4456 *state |= kStartsWithTrailingSurrogate;
4457 } else {
4458 *state &= ~kStartsWithTrailingSurrogate;
4459 }
4460 }
4461
4462 static inline void MergeTerminal(int* length,
4463 uint8_t state,
4464 uint8_t* state_out) {
4465 DCHECK((state & kLeftmostEdgeIsCalculated) &&
4466 (state & kRightmostEdgeIsCalculated));
4467 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4468 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4469 }
4470 *state_out = kInitialState |
4471 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4472 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4473 }
4474
4475 static int Calculate(i::ConsString* current, uint8_t* state_out) {
4476 using namespace internal;
4477 int total_length = 0;
4478 uint8_t state = kInitialState;
4479 while (true) {
4480 i::String* left = current->first();
4481 i::String* right = current->second();
4482 uint8_t right_leaf_state;
4483 uint8_t left_leaf_state;
4484 int leaf_length;
4485 ConsString* left_as_cons =
4486 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4487 if (left_as_cons == NULL) {
4488 total_length += leaf_length;
4489 MergeLeafLeft(&total_length, &state, left_leaf_state);
4490 }
4491 ConsString* right_as_cons =
4492 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4493 if (right_as_cons == NULL) {
4494 total_length += leaf_length;
4495 MergeLeafRight(&total_length, &state, right_leaf_state);
4496 if (left_as_cons != NULL) {
4497 // 1 Leaf node. Descend in place.
4498 current = left_as_cons;
4499 continue;
4500 } else {
4501 // Terminal node.
4502 MergeTerminal(&total_length, state, state_out);
4503 return total_length;
4504 }
4505 } else if (left_as_cons == NULL) {
4506 // 1 Leaf node. Descend in place.
4507 current = right_as_cons;
4508 continue;
4509 }
4510 // Both strings are ConsStrings.
4511 // Recurse on smallest.
4512 if (left->length() < right->length()) {
4513 total_length += Calculate(left_as_cons, &left_leaf_state);
4514 MergeLeafLeft(&total_length, &state, left_leaf_state);
4515 current = right_as_cons;
4516 } else {
4517 total_length += Calculate(right_as_cons, &right_leaf_state);
4518 MergeLeafRight(&total_length, &state, right_leaf_state);
4519 current = left_as_cons;
4520 }
4521 }
4522 UNREACHABLE();
4523 return 0;
4524 }
4525
4526 static inline int Calculate(i::ConsString* current) {
4527 uint8_t state = kInitialState;
4528 return Calculate(current, &state);
4529 }
4530
4531 private:
4532 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
4533};
4534
4535
4536static int Utf8Length(i::String* str, i::Isolate* isolate) {
4537 int length = str->length();
4538 if (length == 0) return 0;
4539 uint8_t state;
4540 i::ConsString* cons_string =
4541 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4542 if (cons_string == NULL) return length;
4543 return Utf8LengthHelper::Calculate(cons_string);
4544}
4545
4546
Steve Blocka7e24c12009-10-30 11:49:00 +00004547int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004548 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004549 i::Isolate* isolate = str->GetIsolate();
4550 return v8::Utf8Length(*str, isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004551}
4552
4553
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004554class Utf8WriterVisitor {
4555 public:
4556 Utf8WriterVisitor(
4557 char* buffer,
4558 int capacity,
4559 bool skip_capacity_check,
4560 bool replace_invalid_utf8)
4561 : early_termination_(false),
4562 last_character_(unibrow::Utf16::kNoPreviousCharacter),
4563 buffer_(buffer),
4564 start_(buffer),
4565 capacity_(capacity),
4566 skip_capacity_check_(capacity == -1 || skip_capacity_check),
4567 replace_invalid_utf8_(replace_invalid_utf8),
4568 utf16_chars_read_(0) {
4569 }
4570
4571 static int WriteEndCharacter(uint16_t character,
4572 int last_character,
4573 int remaining,
4574 char* const buffer,
4575 bool replace_invalid_utf8) {
4576 using namespace unibrow;
4577 DCHECK(remaining > 0);
4578 // We can't use a local buffer here because Encode needs to modify
4579 // previous characters in the stream. We know, however, that
4580 // exactly one character will be advanced.
4581 if (Utf16::IsSurrogatePair(last_character, character)) {
4582 int written = Utf8::Encode(buffer,
4583 character,
4584 last_character,
4585 replace_invalid_utf8);
4586 DCHECK(written == 1);
4587 return written;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004588 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004589 // Use a scratch buffer to check the required characters.
4590 char temp_buffer[Utf8::kMaxEncodedSize];
4591 // Can't encode using last_character as gcc has array bounds issues.
4592 int written = Utf8::Encode(temp_buffer,
4593 character,
4594 Utf16::kNoPreviousCharacter,
4595 replace_invalid_utf8);
4596 // Won't fit.
4597 if (written > remaining) return 0;
4598 // Copy over the character from temp_buffer.
4599 for (int j = 0; j < written; j++) {
4600 buffer[j] = temp_buffer[j];
4601 }
4602 return written;
4603 }
4604
4605 // Visit writes out a group of code units (chars) of a v8::String to the
4606 // internal buffer_. This is done in two phases. The first phase calculates a
4607 // pesimistic estimate (writable_length) on how many code units can be safely
4608 // written without exceeding the buffer capacity and without writing the last
4609 // code unit (it could be a lead surrogate). The estimated number of code
4610 // units is then written out in one go, and the reported byte usage is used
4611 // to correct the estimate. This is repeated until the estimate becomes <= 0
4612 // or all code units have been written out. The second phase writes out code
4613 // units until the buffer capacity is reached, would be exceeded by the next
4614 // unit, or all units have been written out.
4615 template<typename Char>
4616 void Visit(const Char* chars, const int length) {
4617 using namespace unibrow;
4618 DCHECK(!early_termination_);
4619 if (length == 0) return;
4620 // Copy state to stack.
4621 char* buffer = buffer_;
4622 int last_character =
4623 sizeof(Char) == 1 ? Utf16::kNoPreviousCharacter : last_character_;
4624 int i = 0;
4625 // Do a fast loop where there is no exit capacity check.
4626 while (true) {
4627 int fast_length;
4628 if (skip_capacity_check_) {
4629 fast_length = length;
4630 } else {
4631 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4632 // Need enough space to write everything but one character.
4633 STATIC_ASSERT(Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
4634 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
4635 int writable_length =
4636 (remaining_capacity - max_size_per_char)/max_size_per_char;
4637 // Need to drop into slow loop.
4638 if (writable_length <= 0) break;
4639 fast_length = i + writable_length;
4640 if (fast_length > length) fast_length = length;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004641 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004642 // Write the characters to the stream.
4643 if (sizeof(Char) == 1) {
4644 for (; i < fast_length; i++) {
4645 buffer +=
4646 Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
4647 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004648 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004649 } else {
4650 for (; i < fast_length; i++) {
4651 uint16_t character = *chars++;
4652 buffer += Utf8::Encode(buffer,
4653 character,
4654 last_character,
4655 replace_invalid_utf8_);
4656 last_character = character;
4657 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004658 }
4659 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004660 // Array is fully written. Exit.
4661 if (fast_length == length) {
4662 // Write state back out to object.
4663 last_character_ = last_character;
4664 buffer_ = buffer;
4665 utf16_chars_read_ += length;
4666 return;
4667 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004668 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004669 DCHECK(!skip_capacity_check_);
4670 // Slow loop. Must check capacity on each iteration.
4671 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4672 DCHECK(remaining_capacity >= 0);
4673 for (; i < length && remaining_capacity > 0; i++) {
4674 uint16_t character = *chars++;
4675 // remaining_capacity is <= 3 bytes at this point, so we do not write out
4676 // an umatched lead surrogate.
4677 if (replace_invalid_utf8_ && Utf16::IsLeadSurrogate(character)) {
4678 early_termination_ = true;
4679 break;
4680 }
4681 int written = WriteEndCharacter(character,
4682 last_character,
4683 remaining_capacity,
4684 buffer,
4685 replace_invalid_utf8_);
4686 if (written == 0) {
4687 early_termination_ = true;
4688 break;
4689 }
4690 buffer += written;
4691 remaining_capacity -= written;
4692 last_character = character;
4693 }
4694 // Write state back out to object.
4695 last_character_ = last_character;
4696 buffer_ = buffer;
4697 utf16_chars_read_ += i;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004698 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004699
4700 inline bool IsDone() {
4701 return early_termination_;
4702 }
4703
4704 inline void VisitOneByteString(const uint8_t* chars, int length) {
4705 Visit(chars, length);
4706 }
4707
4708 inline void VisitTwoByteString(const uint16_t* chars, int length) {
4709 Visit(chars, length);
4710 }
4711
4712 int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
4713 // Write out number of utf16 characters written to the stream.
4714 if (utf16_chars_read_out != NULL) {
4715 *utf16_chars_read_out = utf16_chars_read_;
4716 }
4717 // Only null terminate if all of the string was written and there's space.
4718 if (write_null &&
4719 !early_termination_ &&
4720 (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
4721 *buffer_++ = '\0';
4722 }
4723 return static_cast<int>(buffer_ - start_);
4724 }
4725
4726 private:
4727 bool early_termination_;
4728 int last_character_;
4729 char* buffer_;
4730 char* const start_;
4731 int capacity_;
4732 bool const skip_capacity_check_;
4733 bool const replace_invalid_utf8_;
4734 int utf16_chars_read_;
4735 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
4736};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004737
4738
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004739static bool RecursivelySerializeToUtf8(i::String* current,
4740 Utf8WriterVisitor* writer,
4741 int recursion_budget) {
4742 while (!writer->IsDone()) {
4743 i::ConsString* cons_string = i::String::VisitFlat(writer, current);
4744 if (cons_string == NULL) return true; // Leaf node.
4745 if (recursion_budget <= 0) return false;
4746 // Must write the left branch first.
4747 i::String* first = cons_string->first();
4748 bool success = RecursivelySerializeToUtf8(first,
4749 writer,
4750 recursion_budget - 1);
4751 if (!success) return false;
4752 // Inline tail recurse for right branch.
4753 current = cons_string->second();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004754 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004755 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00004756}
4757
4758
Steve Block6ded16b2010-05-10 14:33:55 +01004759int String::WriteUtf8(char* buffer,
4760 int capacity,
4761 int* nchars_ref,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004762 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01004763 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004764 LOG_API(isolate, "String::WriteUtf8");
4765 ENTER_V8(isolate);
Ben Murdoch85b71792012-04-11 18:30:58 +01004766 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004767 if (options & HINT_MANY_WRITES_EXPECTED) {
4768 str = i::String::Flatten(str); // Flatten the string for efficiency.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004769 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004770 const int string_length = str->length();
4771 bool write_null = !(options & NO_NULL_TERMINATION);
4772 bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
4773 int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
4774 // First check if we can just write the string without checking capacity.
4775 if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
4776 Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004777 const int kMaxRecursion = 100;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004778 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
4779 if (success) return writer.CompleteWrite(write_null, nchars_ref);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004780 } else if (capacity >= string_length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004781 // First check that the buffer is large enough.
4782 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004783 if (utf8_bytes <= capacity) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004784 // one-byte fast path.
4785 if (utf8_bytes == string_length) {
4786 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
4787 if (nchars_ref != NULL) *nchars_ref = string_length;
4788 if (write_null && (utf8_bytes+1 <= capacity)) {
4789 return string_length + 1;
4790 }
4791 return string_length;
4792 }
4793 if (write_null && (utf8_bytes+1 > capacity)) {
4794 options |= NO_NULL_TERMINATION;
4795 }
4796 // Recurse once without a capacity limit.
4797 // This will get into the first branch above.
4798 // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004799 return WriteUtf8(buffer, -1, nchars_ref, options);
4800 }
4801 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004802 // Recursive slow path can potentially be unreasonable slow. Flatten.
4803 str = i::String::Flatten(str);
4804 Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
4805 i::String::VisitFlat(&writer, *str);
4806 return writer.CompleteWrite(write_null, nchars_ref);
Steve Blocka7e24c12009-10-30 11:49:00 +00004807}
4808
4809
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004810template<typename CharType>
4811static inline int WriteHelper(const String* string,
4812 CharType* buffer,
4813 int start,
4814 int length,
4815 int options) {
4816 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004817 LOG_API(isolate, "String::Write");
4818 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004819 DCHECK(start >= 0 && length >= -1);
4820 i::Handle<i::String> str = Utils::OpenHandle(string);
Steve Block44f0eee2011-05-26 01:26:41 +01004821 isolate->string_tracker()->RecordWrite(str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004822 if (options & String::HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01004823 // Flatten the string for efficiency. This applies whether we are
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004824 // using StringCharacterStream or Get(i) to access the characters.
4825 str = i::String::Flatten(str);
Steve Block6ded16b2010-05-10 14:33:55 +01004826 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01004827 int end = start + length;
4828 if ((length == -1) || (length > str->length() - start) )
4829 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00004830 if (end < 0) return 0;
4831 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004832 if (!(options & String::NO_NULL_TERMINATION) &&
Ben Murdoch69a99ed2011-11-30 16:03:39 +00004833 (length == -1 || end - start < length)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01004834 buffer[end - start] = '\0';
4835 }
4836 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00004837}
4838
4839
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004840int String::WriteOneByte(uint8_t* buffer,
4841 int start,
4842 int length,
4843 int options) const {
4844 return WriteHelper(this, buffer, start, length, options);
4845}
4846
4847
4848int String::Write(uint16_t* buffer,
4849 int start,
4850 int length,
4851 int options) const {
4852 return WriteHelper(this, buffer, start, length, options);
4853}
4854
4855
Steve Blocka7e24c12009-10-30 11:49:00 +00004856bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004857 i::Handle<i::String> str = Utils::OpenHandle(this);
4858 return i::StringShape(*str).IsExternalTwoByte();
4859}
4860
4861
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004862bool v8::String::IsExternalOneByte() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004863 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004864 return i::StringShape(*str).IsExternalOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00004865}
4866
4867
4868void v8::String::VerifyExternalStringResource(
4869 v8::String::ExternalStringResource* value) const {
4870 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004871 const v8::String::ExternalStringResource* expected;
Steve Blocka7e24c12009-10-30 11:49:00 +00004872 if (i::StringShape(*str).IsExternalTwoByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004873 const void* resource =
4874 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4875 expected = reinterpret_cast<const ExternalStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004876 } else {
4877 expected = NULL;
4878 }
4879 CHECK_EQ(expected, value);
4880}
4881
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004882void v8::String::VerifyExternalStringResourceBase(
4883 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004884 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004885 const v8::String::ExternalStringResourceBase* expected;
4886 Encoding expectedEncoding;
4887 if (i::StringShape(*str).IsExternalOneByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004888 const void* resource =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004889 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
4890 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4891 expectedEncoding = ONE_BYTE_ENCODING;
4892 } else if (i::StringShape(*str).IsExternalTwoByte()) {
4893 const void* resource =
4894 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
4895 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
4896 expectedEncoding = TWO_BYTE_ENCODING;
4897 } else {
4898 expected = NULL;
4899 expectedEncoding =
4900 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
4901 }
4902 CHECK_EQ(expected, value);
4903 CHECK_EQ(expectedEncoding, encoding);
4904}
4905
4906const v8::String::ExternalOneByteStringResource*
4907v8::String::GetExternalOneByteStringResource() const {
4908 i::Handle<i::String> str = Utils::OpenHandle(this);
4909 if (i::StringShape(*str).IsExternalOneByte()) {
4910 const void* resource =
4911 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
4912 return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00004913 } else {
4914 return NULL;
4915 }
4916}
4917
4918
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004919Local<Value> Symbol::Name() const {
4920 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
4921 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
4922 return Utils::ToLocal(name);
4923}
4924
4925
4926Local<Value> Private::Name() const {
4927 return reinterpret_cast<const Symbol*>(this)->Name();
4928}
4929
4930
Steve Blocka7e24c12009-10-30 11:49:00 +00004931double Number::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004932 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4933 return obj->Number();
4934}
4935
4936
4937bool Boolean::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004938 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4939 return obj->IsTrue();
4940}
4941
4942
4943int64_t Integer::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004944 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4945 if (obj->IsSmi()) {
4946 return i::Smi::cast(*obj)->value();
4947 } else {
4948 return static_cast<int64_t>(obj->Number());
4949 }
4950}
4951
4952
4953int32_t Int32::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00004954 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4955 if (obj->IsSmi()) {
4956 return i::Smi::cast(*obj)->value();
4957 } else {
4958 return static_cast<int32_t>(obj->Number());
4959 }
4960}
4961
4962
Steve Block6ded16b2010-05-10 14:33:55 +01004963uint32_t Uint32::Value() const {
Steve Block6ded16b2010-05-10 14:33:55 +01004964 i::Handle<i::Object> obj = Utils::OpenHandle(this);
4965 if (obj->IsSmi()) {
4966 return i::Smi::cast(*obj)->value();
4967 } else {
4968 return static_cast<uint32_t>(obj->Number());
4969 }
4970}
4971
4972
Steve Blocka7e24c12009-10-30 11:49:00 +00004973int v8::Object::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00004974 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
4975 return obj->GetInternalFieldCount();
4976}
4977
4978
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004979static bool InternalFieldOK(i::Handle<i::JSObject> obj,
4980 int index,
4981 const char* location) {
4982 return Utils::ApiCheck(index < obj->GetInternalFieldCount(),
4983 location,
4984 "Internal field out of bounds");
4985}
4986
4987
4988Local<Value> v8::Object::SlowGetInternalField(int index) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004989 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004990 const char* location = "v8::Object::GetInternalField()";
4991 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
4992 i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
4993 return Utils::ToLocal(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004994}
4995
4996
4997void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +00004998 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004999 const char* location = "v8::Object::SetInternalField()";
5000 if (!InternalFieldOK(obj, index, location)) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00005001 i::Handle<i::Object> val = Utils::OpenHandle(*value);
5002 obj->SetInternalField(index, *val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005003 DCHECK_EQ(value, GetInternalField(index));
Steve Blocka7e24c12009-10-30 11:49:00 +00005004}
5005
5006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005007void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
5008 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
5009 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5010 if (!InternalFieldOK(obj, index, location)) return NULL;
5011 return DecodeSmiToAligned(obj->GetInternalField(index), location);
Ben Murdochb8e0da22011-05-16 14:20:40 +01005012}
5013
5014
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005015void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
5016 i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
5017 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5018 if (!InternalFieldOK(obj, index, location)) return;
5019 obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
5020 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
Ben Murdochb8e0da22011-05-16 14:20:40 +01005021}
5022
5023
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005024static void* ExternalValue(i::Object* obj) {
5025 // Obscure semantics for undefined, but somehow checked in our unit tests...
5026 if (obj->IsUndefined()) return NULL;
5027 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
5028 return i::Foreign::cast(foreign)->foreign_address();
Steve Blocka7e24c12009-10-30 11:49:00 +00005029}
5030
5031
5032// --- E n v i r o n m e n t ---
5033
Steve Block44f0eee2011-05-26 01:26:41 +01005034
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005035void v8::V8::InitializePlatform(Platform* platform) {
5036 i::V8::InitializePlatform(platform);
Steve Blocka7e24c12009-10-30 11:49:00 +00005037}
5038
5039
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005040void v8::V8::ShutdownPlatform() {
5041 i::V8::ShutdownPlatform();
5042}
5043
5044
5045bool v8::V8::Initialize() {
5046 i::V8::Initialize();
5047 return true;
5048}
5049
5050
5051void v8::V8::SetEntropySource(EntropySource entropy_source) {
5052 base::RandomNumberGenerator::SetEntropySource(entropy_source);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005053}
5054
5055
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005056void v8::V8::SetReturnAddressLocationResolver(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005057 ReturnAddressLocationResolver return_address_resolver) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005058 i::V8::SetReturnAddressLocationResolver(return_address_resolver);
5059}
5060
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005061void v8::V8::SetArrayBufferAllocator(
5062 ArrayBuffer::Allocator* allocator) {
5063 if (!Utils::ApiCheck(i::V8::ArrayBufferAllocator() == NULL,
5064 "v8::V8::SetArrayBufferAllocator",
5065 "ArrayBufferAllocator might only be set once"))
5066 return;
5067 i::V8::SetArrayBufferAllocator(allocator);
5068}
5069
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005070
Steve Blocka7e24c12009-10-30 11:49:00 +00005071bool v8::V8::Dispose() {
5072 i::V8::TearDown();
5073 return true;
5074}
5075
5076
Russell Brenner90bac252010-11-18 13:33:46 -08005077HeapStatistics::HeapStatistics(): total_heap_size_(0),
5078 total_heap_size_executable_(0),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005079 total_physical_size_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01005080 used_heap_size_(0),
5081 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00005082
5083
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005084void v8::V8::VisitExternalResources(ExternalResourceVisitor* visitor) {
5085 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005086 isolate->heap()->VisitExternalResources(visitor);
5087}
5088
5089
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005090class VisitorAdapter : public i::ObjectVisitor {
5091 public:
5092 explicit VisitorAdapter(PersistentHandleVisitor* visitor)
5093 : visitor_(visitor) {}
5094 virtual void VisitPointers(i::Object** start, i::Object** end) {
5095 UNREACHABLE();
5096 }
5097 virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
5098 Value* value = ToApi<Value>(i::Handle<i::Object>(p));
5099 visitor_->VisitPersistentHandle(
5100 reinterpret_cast<Persistent<Value>*>(&value), class_id);
5101 }
5102 private:
5103 PersistentHandleVisitor* visitor_;
5104};
5105
5106
5107void v8::V8::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005108 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005109 i::DisallowHeapAllocation no_allocation;
5110
5111 VisitorAdapter visitor_adapter(visitor);
5112 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
Steve Blocka7e24c12009-10-30 11:49:00 +00005113}
5114
5115
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005116void v8::V8::VisitHandlesForPartialDependence(
5117 Isolate* exported_isolate, PersistentHandleVisitor* visitor) {
5118 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(exported_isolate);
5119 DCHECK(isolate == i::Isolate::Current());
5120 i::DisallowHeapAllocation no_allocation;
5121
5122 VisitorAdapter visitor_adapter(visitor);
5123 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
5124 &visitor_adapter);
Steve Blocka7e24c12009-10-30 11:49:00 +00005125}
5126
5127
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005128bool v8::V8::InitializeICU(const char* icu_data_file) {
5129 return i::InitializeICU(icu_data_file);
Steve Block6ded16b2010-05-10 14:33:55 +01005130}
5131
5132
Steve Blocka7e24c12009-10-30 11:49:00 +00005133const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01005134 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00005135}
5136
5137
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005138static i::Handle<i::Context> CreateEnvironment(
5139 i::Isolate* isolate,
Steve Blocka7e24c12009-10-30 11:49:00 +00005140 v8::ExtensionConfiguration* extensions,
5141 v8::Handle<ObjectTemplate> global_template,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005142 v8::Handle<Value> maybe_global_proxy) {
5143 i::Handle<i::Context> env;
Steve Blocka7e24c12009-10-30 11:49:00 +00005144
5145 // Enter V8 via an ENTER_V8 scope.
Steve Blocka7e24c12009-10-30 11:49:00 +00005146 {
Steve Block44f0eee2011-05-26 01:26:41 +01005147 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005148 v8::Handle<ObjectTemplate> proxy_template = global_template;
5149 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5150 i::Handle<i::FunctionTemplateInfo> global_constructor;
5151
5152 if (!global_template.IsEmpty()) {
5153 // Make sure that the global_template has a constructor.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005154 global_constructor = EnsureConstructor(isolate, *global_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005155
5156 // Create a fresh template for the global proxy object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005157 proxy_template = ObjectTemplate::New(
5158 reinterpret_cast<v8::Isolate*>(isolate));
5159 proxy_constructor = EnsureConstructor(isolate, *proxy_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005160
5161 // Set the global template to be the prototype template of
5162 // global proxy template.
5163 proxy_constructor->set_prototype_template(
5164 *Utils::OpenHandle(*global_template));
5165
5166 // Migrate security handlers from global_template to
5167 // proxy_template. Temporarily removing access check
5168 // information from the global template.
5169 if (!global_constructor->access_check_info()->IsUndefined()) {
5170 proxy_constructor->set_access_check_info(
5171 global_constructor->access_check_info());
5172 proxy_constructor->set_needs_access_check(
5173 global_constructor->needs_access_check());
5174 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01005175 global_constructor->set_access_check_info(
5176 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00005177 }
5178 }
5179
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005180 i::Handle<i::Object> proxy = Utils::OpenHandle(*maybe_global_proxy, true);
5181 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
5182 if (!proxy.is_null()) {
5183 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(proxy);
5184 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005185 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01005186 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005187 maybe_proxy, proxy_template, extensions);
Steve Blocka7e24c12009-10-30 11:49:00 +00005188
5189 // Restore the access check info on the global template.
5190 if (!global_template.IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005191 DCHECK(!global_constructor.is_null());
5192 DCHECK(!proxy_constructor.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00005193 global_constructor->set_access_check_info(
5194 proxy_constructor->access_check_info());
5195 global_constructor->set_needs_access_check(
5196 proxy_constructor->needs_access_check());
5197 }
5198 }
5199 // Leave V8.
5200
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005201 return env;
5202}
5203
5204Local<Context> v8::Context::New(
5205 v8::Isolate* external_isolate,
5206 v8::ExtensionConfiguration* extensions,
5207 v8::Handle<ObjectTemplate> global_template,
5208 v8::Handle<Value> global_object) {
5209 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5210 LOG_API(isolate, "Context::New");
5211 ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
5212 i::HandleScope scope(isolate);
5213 ExtensionConfiguration no_extensions;
5214 if (extensions == NULL) extensions = &no_extensions;
5215 i::Handle<i::Context> env =
5216 CreateEnvironment(isolate, extensions, global_template, global_object);
5217 if (env.is_null()) return Local<Context>();
5218 return Utils::ToLocal(scope.CloseAndEscape(env));
Steve Blocka7e24c12009-10-30 11:49:00 +00005219}
5220
5221
5222void v8::Context::SetSecurityToken(Handle<Value> token) {
Steve Block44f0eee2011-05-26 01:26:41 +01005223 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01005224 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005225 i::Handle<i::Context> env = Utils::OpenHandle(this);
5226 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
5227 env->set_security_token(*token_handle);
5228}
5229
5230
5231void v8::Context::UseDefaultSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01005232 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01005233 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005234 i::Handle<i::Context> env = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005235 env->set_security_token(env->global_object());
Steve Blocka7e24c12009-10-30 11:49:00 +00005236}
5237
5238
5239Handle<Value> v8::Context::GetSecurityToken() {
Steve Block44f0eee2011-05-26 01:26:41 +01005240 i::Isolate* isolate = i::Isolate::Current();
Steve Blocka7e24c12009-10-30 11:49:00 +00005241 i::Handle<i::Context> env = Utils::OpenHandle(this);
5242 i::Object* security_token = env->security_token();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005243 i::Handle<i::Object> token_handle(security_token, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005244 return Utils::ToLocal(token_handle);
5245}
5246
5247
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005248v8::Isolate* Context::GetIsolate() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005249 i::Handle<i::Context> env = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005250 return reinterpret_cast<Isolate*>(env->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00005251}
5252
5253
5254v8::Local<v8::Object> Context::Global() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005255 i::Handle<i::Context> context = Utils::OpenHandle(this);
5256 i::Isolate* isolate = context->GetIsolate();
5257 i::Handle<i::Object> global(context->global_proxy(), isolate);
5258 // TODO(dcarney): This should always return the global proxy
5259 // but can't presently as calls to GetProtoype will return the wrong result.
5260 if (i::Handle<i::JSGlobalProxy>::cast(
5261 global)->IsDetachedFrom(context->global_object())) {
5262 global = i::Handle<i::Object>(context->global_object(), isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005263 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005264 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5265}
5266
5267
5268void Context::DetachGlobal() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005269 i::Handle<i::Context> context = Utils::OpenHandle(this);
5270 i::Isolate* isolate = context->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005271 ENTER_V8(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005272 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00005273}
5274
5275
Ben Murdoch257744e2011-11-30 15:57:28 +00005276void Context::AllowCodeGenerationFromStrings(bool allow) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005277 i::Handle<i::Context> context = Utils::OpenHandle(this);
5278 i::Isolate* isolate = context->GetIsolate();
Ben Murdoch257744e2011-11-30 15:57:28 +00005279 ENTER_V8(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005280 context->set_allow_code_gen_from_strings(
5281 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5282}
5283
5284
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005285bool Context::IsCodeGenerationFromStringsAllowed() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005286 i::Handle<i::Context> context = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005287 return !context->allow_code_gen_from_strings()->IsFalse();
5288}
5289
5290
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005291void Context::SetErrorMessageForCodeGenerationFromStrings(
5292 Handle<String> error) {
5293 i::Handle<i::Context> context = Utils::OpenHandle(this);
5294 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
5295 context->set_error_message_for_code_gen_from_strings(*error_handle);
Andrei Popescu74b3c142010-03-29 12:03:09 +01005296}
5297
5298
Steve Blocka7e24c12009-10-30 11:49:00 +00005299Local<v8::Object> ObjectTemplate::NewInstance() {
Steve Block44f0eee2011-05-26 01:26:41 +01005300 i::Isolate* isolate = i::Isolate::Current();
5301 ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
5302 return Local<v8::Object>());
5303 LOG_API(isolate, "ObjectTemplate::NewInstance");
5304 ENTER_V8(isolate);
5305 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005306 i::Handle<i::Object> obj;
5307 has_pending_exception = !i::Execution::InstantiateObject(
5308 Utils::OpenHandle(this)).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01005309 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005310 return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
5311}
5312
5313
5314Local<v8::Function> FunctionTemplate::GetFunction() {
Steve Block44f0eee2011-05-26 01:26:41 +01005315 i::Isolate* isolate = i::Isolate::Current();
5316 ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
Steve Blocka7e24c12009-10-30 11:49:00 +00005317 return Local<v8::Function>());
Steve Block44f0eee2011-05-26 01:26:41 +01005318 LOG_API(isolate, "FunctionTemplate::GetFunction");
5319 ENTER_V8(isolate);
5320 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005321 i::Handle<i::Object> obj;
5322 has_pending_exception = !i::Execution::InstantiateFunction(
5323 Utils::OpenHandle(this)).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01005324 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005325 return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
5326}
5327
5328
5329bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01005330 ON_BAILOUT(i::Isolate::Current(), "v8::FunctionTemplate::HasInstanceOf()",
5331 return false);
Steve Blocka7e24c12009-10-30 11:49:00 +00005332 i::Object* obj = *Utils::OpenHandle(*value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005333 return Utils::OpenHandle(this)->IsTemplateFor(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005334}
5335
5336
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005337Local<External> v8::External::New(Isolate* isolate, void* value) {
5338 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
5339 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5340 LOG_API(i_isolate, "External::New");
5341 ENTER_V8(i_isolate);
5342 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
5343 return Utils::ExternalToLocal(external);
Steve Blocka7e24c12009-10-30 11:49:00 +00005344}
5345
5346
5347void* External::Value() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005348 return ExternalValue(*Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00005349}
5350
5351
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005352// anonymous namespace for string creation helper functions
5353namespace {
5354
5355inline int StringLength(const char* string) {
5356 return i::StrLength(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005357}
5358
5359
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005360inline int StringLength(const uint8_t* string) {
5361 return i::StrLength(reinterpret_cast<const char*>(string));
5362}
5363
5364
5365inline int StringLength(const uint16_t* string) {
5366 int length = 0;
5367 while (string[length] != '\0')
5368 length++;
5369 return length;
5370}
5371
5372
5373MUST_USE_RESULT
5374inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5375 String::NewStringType type,
5376 i::Vector<const char> string) {
5377 if (type == String::kInternalizedString) {
5378 return factory->InternalizeUtf8String(string);
5379 }
5380 return factory->NewStringFromUtf8(string);
5381}
5382
5383
5384MUST_USE_RESULT
5385inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5386 String::NewStringType type,
5387 i::Vector<const uint8_t> string) {
5388 if (type == String::kInternalizedString) {
5389 return factory->InternalizeOneByteString(string);
5390 }
5391 return factory->NewStringFromOneByte(string);
5392}
5393
5394
5395MUST_USE_RESULT
5396inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
5397 String::NewStringType type,
5398 i::Vector<const uint16_t> string) {
5399 if (type == String::kInternalizedString) {
5400 return factory->InternalizeTwoByteString(string);
5401 }
5402 return factory->NewStringFromTwoByte(string);
5403}
5404
5405
5406template<typename Char>
5407inline Local<String> NewString(Isolate* v8_isolate,
5408 const char* location,
5409 const char* env,
5410 const Char* data,
5411 String::NewStringType type,
5412 int length) {
5413 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
5414 LOG_API(isolate, env);
5415 if (length == 0 && type != String::kUndetectableString) {
5416 return String::Empty(v8_isolate);
5417 }
Steve Block44f0eee2011-05-26 01:26:41 +01005418 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005419 if (length == -1) length = StringLength(data);
5420 // We do not expect this to fail. Change this if it does.
5421 i::Handle<i::String> result = NewString(
5422 isolate->factory(),
5423 type,
5424 i::Vector<const Char>(data, length)).ToHandleChecked();
5425 if (type == String::kUndetectableString) {
5426 result->MarkAsUndetectable();
5427 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005428 return Utils::ToLocal(result);
5429}
5430
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005431} // anonymous namespace
5432
5433
5434Local<String> String::NewFromUtf8(Isolate* isolate,
5435 const char* data,
5436 NewStringType type,
5437 int length) {
5438 return NewString(isolate,
5439 "v8::String::NewFromUtf8()",
5440 "String::NewFromUtf8",
5441 data,
5442 type,
5443 length);
5444}
5445
5446
5447Local<String> String::NewFromOneByte(Isolate* isolate,
5448 const uint8_t* data,
5449 NewStringType type,
5450 int length) {
5451 return NewString(isolate,
5452 "v8::String::NewFromOneByte()",
5453 "String::NewFromOneByte",
5454 data,
5455 type,
5456 length);
5457}
5458
5459
5460Local<String> String::NewFromTwoByte(Isolate* isolate,
5461 const uint16_t* data,
5462 NewStringType type,
5463 int length) {
5464 return NewString(isolate,
5465 "v8::String::NewFromTwoByte()",
5466 "String::NewFromTwoByte",
5467 data,
5468 type,
5469 length);
5470}
5471
Steve Blocka7e24c12009-10-30 11:49:00 +00005472
Steve Block3ce2e202009-11-05 08:53:23 +00005473Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00005474 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01005475 i::Isolate* isolate = left_string->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005476 LOG_API(isolate, "String::New(char)");
5477 ENTER_V8(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00005478 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005479 // We do not expect this to fail. Change this if it does.
5480 i::Handle<i::String> result = isolate->factory()->NewConsString(
5481 left_string, right_string).ToHandleChecked();
Steve Block3ce2e202009-11-05 08:53:23 +00005482 return Utils::ToLocal(result);
5483}
5484
5485
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005486static i::Handle<i::String> NewExternalStringHandle(
5487 i::Isolate* isolate,
5488 v8::String::ExternalStringResource* resource) {
5489 // We do not expect this to fail. Change this if it does.
5490 return isolate->factory()->NewExternalStringFromTwoByte(
5491 resource).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00005492}
5493
5494
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005495static i::Handle<i::String> NewExternalOneByteStringHandle(
5496 i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5497 // We do not expect this to fail. Change this if it does.
5498 return isolate->factory()
5499 ->NewExternalStringFromOneByte(resource)
5500 .ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00005501}
5502
5503
Steve Blocka7e24c12009-10-30 11:49:00 +00005504Local<String> v8::String::NewExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005505 Isolate* isolate,
5506 v8::String::ExternalStringResource* resource) {
5507 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5508 LOG_API(i_isolate, "String::NewExternal");
5509 ENTER_V8(i_isolate);
5510 CHECK(resource && resource->data());
5511 i::Handle<i::String> result = NewExternalStringHandle(i_isolate, resource);
5512 i_isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00005513 return Utils::ToLocal(result);
5514}
5515
5516
5517bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005518 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005519 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005520 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005521 return false; // Already an external string.
5522 }
5523 ENTER_V8(isolate);
5524 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5525 return false;
5526 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005527 if (isolate->heap()->IsInGCPostProcessing()) {
5528 return false;
5529 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005530 CHECK(resource && resource->data());
5531
Steve Blocka7e24c12009-10-30 11:49:00 +00005532 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005533 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5534 DCHECK(!CanMakeExternal() || result);
5535 if (result) {
5536 DCHECK(obj->IsExternalString());
Steve Block44f0eee2011-05-26 01:26:41 +01005537 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005538 }
5539 return result;
5540}
5541
5542
5543Local<String> v8::String::NewExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005544 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5545 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5546 LOG_API(i_isolate, "String::NewExternal");
5547 ENTER_V8(i_isolate);
5548 CHECK(resource && resource->data());
5549 i::Handle<i::String> result =
5550 NewExternalOneByteStringHandle(i_isolate, resource);
5551 i_isolate->heap()->external_string_table()->AddString(*result);
Steve Blocka7e24c12009-10-30 11:49:00 +00005552 return Utils::ToLocal(result);
5553}
5554
5555
5556bool v8::String::MakeExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005557 v8::String::ExternalOneByteStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005558 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005559 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005560 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005561 return false; // Already an external string.
5562 }
5563 ENTER_V8(isolate);
5564 if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
5565 return false;
5566 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005567 if (isolate->heap()->IsInGCPostProcessing()) {
5568 return false;
5569 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005570 CHECK(resource && resource->data());
5571
Steve Blocka7e24c12009-10-30 11:49:00 +00005572 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005573 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5574 DCHECK(!CanMakeExternal() || result);
5575 if (result) {
5576 DCHECK(obj->IsExternalString());
Steve Block44f0eee2011-05-26 01:26:41 +01005577 isolate->heap()->external_string_table()->AddString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005578 }
5579 return result;
5580}
5581
5582
5583bool v8::String::CanMakeExternal() {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005584 if (!internal::FLAG_clever_optimizations) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00005585 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005586 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005587
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005588 if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00005589 int size = obj->Size(); // Byte size of the original string.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005590 if (size < i::ExternalString::kShortSize) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00005591 i::StringShape shape(*obj);
5592 return !shape.IsExternal();
5593}
5594
5595
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005596Local<v8::Object> v8::Object::New(Isolate* isolate) {
5597 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5598 LOG_API(i_isolate, "Object::New");
5599 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005600 i::Handle<i::JSObject> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005601 i_isolate->factory()->NewJSObject(i_isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00005602 return Utils::ToLocal(obj);
5603}
5604
5605
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005606Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
5607 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5608 LOG_API(i_isolate, "NumberObject::New");
5609 ENTER_V8(i_isolate);
5610 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
5611 i::Handle<i::Object> obj =
5612 i::Object::ToObject(i_isolate, number).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005613 return Utils::ToLocal(obj);
5614}
5615
5616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005617double v8::NumberObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005618 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5619 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005620 i::Isolate* isolate = jsvalue->GetIsolate();
5621 LOG_API(isolate, "NumberObject::NumberValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005622 return jsvalue->value()->Number();
5623}
5624
5625
5626Local<v8::Value> v8::BooleanObject::New(bool value) {
5627 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005628 LOG_API(isolate, "BooleanObject::New");
5629 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005630 i::Handle<i::Object> boolean(value
5631 ? isolate->heap()->true_value()
5632 : isolate->heap()->false_value(),
5633 isolate);
5634 i::Handle<i::Object> obj =
5635 i::Object::ToObject(isolate, boolean).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005636 return Utils::ToLocal(obj);
5637}
5638
5639
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005640bool v8::BooleanObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005641 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5642 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005643 i::Isolate* isolate = jsvalue->GetIsolate();
5644 LOG_API(isolate, "BooleanObject::BooleanValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005645 return jsvalue->value()->IsTrue();
5646}
5647
5648
5649Local<v8::Value> v8::StringObject::New(Handle<String> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005650 i::Handle<i::String> string = Utils::OpenHandle(*value);
5651 i::Isolate* isolate = string->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005652 LOG_API(isolate, "StringObject::New");
5653 ENTER_V8(isolate);
5654 i::Handle<i::Object> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005655 i::Object::ToObject(isolate, string).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005656 return Utils::ToLocal(obj);
5657}
5658
5659
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005660Local<v8::String> v8::StringObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005661 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5662 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005663 i::Isolate* isolate = jsvalue->GetIsolate();
5664 LOG_API(isolate, "StringObject::StringValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005665 return Utils::ToLocal(
5666 i::Handle<i::String>(i::String::cast(jsvalue->value())));
5667}
5668
5669
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005670Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
5671 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5672 LOG_API(i_isolate, "SymbolObject::New");
5673 ENTER_V8(i_isolate);
5674 i::Handle<i::Object> obj = i::Object::ToObject(
5675 i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00005676 return Utils::ToLocal(obj);
5677}
5678
5679
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005680Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
5681 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5682 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
5683 i::Isolate* isolate = jsvalue->GetIsolate();
5684 LOG_API(isolate, "SymbolObject::SymbolValue");
5685 return Utils::ToLocal(
5686 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
5687}
5688
5689
5690Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
5691 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5692 LOG_API(i_isolate, "Date::New");
5693 if (std::isnan(time)) {
5694 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
5695 time = base::OS::nan_value();
5696 }
5697 ENTER_V8(i_isolate);
5698 EXCEPTION_PREAMBLE(i_isolate);
5699 i::Handle<i::Object> obj;
5700 has_pending_exception = !i::Execution::NewDate(
5701 i_isolate, time).ToHandle(&obj);
5702 EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::Value>());
5703 return Utils::ToLocal(obj);
5704}
5705
5706
5707double v8::Date::ValueOf() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005708 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005709 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005710 i::Isolate* isolate = jsdate->GetIsolate();
5711 LOG_API(isolate, "Date::NumberValue");
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005712 return jsdate->value()->Number();
Steve Blocka7e24c12009-10-30 11:49:00 +00005713}
5714
5715
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005716void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
5717 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5718 if (!i_isolate->IsInitialized()) return;
5719 ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
Steve Block44f0eee2011-05-26 01:26:41 +01005720 return);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005721 LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
5722 ENTER_V8(i_isolate);
Ben Murdochb0fe1622011-05-05 13:52:32 +01005723
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005724 i_isolate->date_cache()->ResetDateCache();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005725
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005726 if (!i_isolate->eternal_handles()->Exists(
5727 i::EternalHandles::DATE_CACHE_VERSION)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005728 return;
5729 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005730 i::Handle<i::FixedArray> date_cache_version =
5731 i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
5732 i::EternalHandles::DATE_CACHE_VERSION));
5733 DCHECK_EQ(1, date_cache_version->length());
5734 CHECK(date_cache_version->get(0)->IsSmi());
5735 date_cache_version->set(
5736 0,
5737 i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1));
Ben Murdochb0fe1622011-05-05 13:52:32 +01005738}
5739
5740
Ben Murdochf87a2032010-10-22 12:50:53 +01005741static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005742 i::Isolate* isolate = i::Isolate::Current();
5743 uint8_t flags_buf[3];
Ben Murdochf87a2032010-10-22 12:50:53 +01005744 int num_flags = 0;
5745 if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
5746 if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
5747 if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005748 DCHECK(num_flags <= static_cast<int>(arraysize(flags_buf)));
5749 return isolate->factory()->InternalizeOneByteString(
5750 i::Vector<const uint8_t>(flags_buf, num_flags));
Ben Murdochf87a2032010-10-22 12:50:53 +01005751}
5752
5753
5754Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
5755 Flags flags) {
Steve Block44f0eee2011-05-26 01:26:41 +01005756 i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005757 LOG_API(isolate, "RegExp::New");
5758 ENTER_V8(isolate);
5759 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005760 i::Handle<i::JSRegExp> obj;
5761 has_pending_exception = !i::Execution::NewJSRegExp(
Ben Murdochf87a2032010-10-22 12:50:53 +01005762 Utils::OpenHandle(*pattern),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005763 RegExpFlagsToString(flags)).ToHandle(&obj);
Steve Block44f0eee2011-05-26 01:26:41 +01005764 EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
Ben Murdochf87a2032010-10-22 12:50:53 +01005765 return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
5766}
5767
5768
5769Local<v8::String> v8::RegExp::GetSource() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01005770 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5771 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
5772}
5773
5774
5775// Assert that the static flags cast in GetFlags is valid.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005776#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
5777 STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
Ben Murdochf87a2032010-10-22 12:50:53 +01005778 static_cast<int>(i::JSRegExp::internal_flag))
5779REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
5780REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
5781REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
5782REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
5783#undef REGEXP_FLAG_ASSERT_EQ
5784
5785v8::RegExp::Flags v8::RegExp::GetFlags() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01005786 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
5787 return static_cast<RegExp::Flags>(obj->GetFlags().value());
5788}
5789
5790
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005791Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
5792 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5793 LOG_API(i_isolate, "Array::New");
5794 ENTER_V8(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005795 int real_length = length > 0 ? length : 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005796 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01005797 i::Handle<i::Object> length_obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005798 i_isolate->factory()->NewNumberFromInt(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01005799 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005800 return Utils::ToLocal(obj);
5801}
5802
5803
5804uint32_t v8::Array::Length() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005805 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
5806 i::Object* length = obj->length();
5807 if (length->IsSmi()) {
5808 return i::Smi::cast(length)->value();
5809 } else {
5810 return static_cast<uint32_t>(length->Number());
5811 }
5812}
5813
5814
5815Local<Object> Array::CloneElementAt(uint32_t index) {
Steve Block44f0eee2011-05-26 01:26:41 +01005816 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
5817 ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005818 i::Handle<i::JSObject> self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005819 if (!self->HasFastObjectElements()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005820 return Local<Object>();
5821 }
5822 i::FixedArray* elms = i::FixedArray::cast(self->elements());
5823 i::Object* paragon = elms->get(index);
5824 if (!paragon->IsJSObject()) {
5825 return Local<Object>();
5826 }
5827 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Steve Block44f0eee2011-05-26 01:26:41 +01005828 EXCEPTION_PREAMBLE(isolate);
5829 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005830 i::Handle<i::JSObject> result =
5831 isolate->factory()->CopyJSObject(paragon_handle);
Steve Blocka7e24c12009-10-30 11:49:00 +00005832 has_pending_exception = result.is_null();
Steve Block44f0eee2011-05-26 01:26:41 +01005833 EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
Steve Blocka7e24c12009-10-30 11:49:00 +00005834 return Utils::ToLocal(result);
5835}
5836
5837
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005838bool Value::IsPromise() const {
5839 i::Handle<i::Object> val = Utils::OpenHandle(this);
5840 if (!val->IsJSObject()) return false;
5841 i::Handle<i::JSObject> obj = i::Handle<i::JSObject>::cast(val);
5842 i::Isolate* isolate = obj->GetIsolate();
5843 LOG_API(isolate, "IsPromise");
Steve Block44f0eee2011-05-26 01:26:41 +01005844 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005845 EXCEPTION_PREAMBLE(isolate);
5846 i::Handle<i::Object> argv[] = { obj };
5847 i::Handle<i::Object> b;
5848 has_pending_exception = !i::Execution::Call(
5849 isolate,
5850 isolate->is_promise(),
5851 isolate->factory()->undefined_value(),
5852 arraysize(argv), argv,
5853 false).ToHandle(&b);
5854 EXCEPTION_BAILOUT_CHECK(isolate, false);
5855 return b->BooleanValue();
5856}
5857
5858
5859Local<Promise::Resolver> Promise::Resolver::New(Isolate* v8_isolate) {
5860 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
5861 LOG_API(isolate, "Promise::Resolver::New");
5862 ENTER_V8(isolate);
5863 EXCEPTION_PREAMBLE(isolate);
5864 i::Handle<i::Object> result;
5865 has_pending_exception = !i::Execution::Call(
5866 isolate,
5867 isolate->promise_create(),
5868 isolate->factory()->undefined_value(),
5869 0, NULL,
5870 false).ToHandle(&result);
5871 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise::Resolver>());
5872 return Local<Promise::Resolver>::Cast(Utils::ToLocal(result));
5873}
5874
5875
5876Local<Promise> Promise::Resolver::GetPromise() {
5877 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5878 return Local<Promise>::Cast(Utils::ToLocal(promise));
5879}
5880
5881
5882void Promise::Resolver::Resolve(Handle<Value> value) {
5883 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5884 i::Isolate* isolate = promise->GetIsolate();
5885 LOG_API(isolate, "Promise::Resolver::Resolve");
5886 ENTER_V8(isolate);
5887 EXCEPTION_PREAMBLE(isolate);
5888 i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
5889 has_pending_exception = i::Execution::Call(
5890 isolate,
5891 isolate->promise_resolve(),
5892 isolate->factory()->undefined_value(),
5893 arraysize(argv), argv,
5894 false).is_null();
5895 EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
5896}
5897
5898
5899void Promise::Resolver::Reject(Handle<Value> value) {
5900 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5901 i::Isolate* isolate = promise->GetIsolate();
5902 LOG_API(isolate, "Promise::Resolver::Reject");
5903 ENTER_V8(isolate);
5904 EXCEPTION_PREAMBLE(isolate);
5905 i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
5906 has_pending_exception = i::Execution::Call(
5907 isolate,
5908 isolate->promise_reject(),
5909 isolate->factory()->undefined_value(),
5910 arraysize(argv), argv,
5911 false).is_null();
5912 EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
5913}
5914
5915
5916Local<Promise> Promise::Chain(Handle<Function> handler) {
5917 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5918 i::Isolate* isolate = promise->GetIsolate();
5919 LOG_API(isolate, "Promise::Chain");
5920 ENTER_V8(isolate);
5921 EXCEPTION_PREAMBLE(isolate);
5922 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5923 i::Handle<i::Object> result;
5924 has_pending_exception = !i::Execution::Call(
5925 isolate,
5926 isolate->promise_chain(),
5927 promise,
5928 arraysize(argv), argv,
5929 false).ToHandle(&result);
5930 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
5931 return Local<Promise>::Cast(Utils::ToLocal(result));
5932}
5933
5934
5935Local<Promise> Promise::Catch(Handle<Function> handler) {
5936 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5937 i::Isolate* isolate = promise->GetIsolate();
5938 LOG_API(isolate, "Promise::Catch");
5939 ENTER_V8(isolate);
5940 EXCEPTION_PREAMBLE(isolate);
5941 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5942 i::Handle<i::Object> result;
5943 has_pending_exception = !i::Execution::Call(
5944 isolate,
5945 isolate->promise_catch(),
5946 promise,
5947 arraysize(argv), argv,
5948 false).ToHandle(&result);
5949 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
5950 return Local<Promise>::Cast(Utils::ToLocal(result));
5951}
5952
5953
5954Local<Promise> Promise::Then(Handle<Function> handler) {
5955 i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
5956 i::Isolate* isolate = promise->GetIsolate();
5957 LOG_API(isolate, "Promise::Then");
5958 ENTER_V8(isolate);
5959 EXCEPTION_PREAMBLE(isolate);
5960 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
5961 i::Handle<i::Object> result;
5962 has_pending_exception = !i::Execution::Call(
5963 isolate,
5964 isolate->promise_then(),
5965 promise,
5966 arraysize(argv), argv,
5967 false).ToHandle(&result);
5968 EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
5969 return Local<Promise>::Cast(Utils::ToLocal(result));
5970}
5971
5972
5973bool v8::ArrayBuffer::IsExternal() const {
5974 return Utils::OpenHandle(this)->is_external();
5975}
5976
5977
5978v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
5979 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5980 Utils::ApiCheck(!obj->is_external(),
5981 "v8::ArrayBuffer::Externalize",
5982 "ArrayBuffer already externalized");
5983 obj->set_is_external(true);
5984 size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
5985 Contents contents;
5986 contents.data_ = obj->backing_store();
5987 contents.byte_length_ = byte_length;
5988 return contents;
5989}
5990
5991
5992void v8::ArrayBuffer::Neuter() {
5993 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
5994 i::Isolate* isolate = obj->GetIsolate();
5995 Utils::ApiCheck(obj->is_external(),
5996 "v8::ArrayBuffer::Neuter",
5997 "Only externalized ArrayBuffers can be neutered");
5998 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
5999 ENTER_V8(isolate);
6000 i::Runtime::NeuterArrayBuffer(obj);
6001}
6002
6003
6004size_t v8::ArrayBuffer::ByteLength() const {
6005 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6006 return static_cast<size_t>(obj->byte_length()->Number());
6007}
6008
6009
6010Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
6011 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6012 LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
6013 ENTER_V8(i_isolate);
6014 i::Handle<i::JSArrayBuffer> obj =
6015 i_isolate->factory()->NewJSArrayBuffer();
6016 i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length);
6017 return Utils::ToLocal(obj);
6018}
6019
6020
6021Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
6022 size_t byte_length) {
6023 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6024 LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
6025 ENTER_V8(i_isolate);
6026 i::Handle<i::JSArrayBuffer> obj =
6027 i_isolate->factory()->NewJSArrayBuffer();
6028 i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
6029 return Utils::ToLocal(obj);
6030}
6031
6032
6033Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
6034 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6035 i::Handle<i::JSArrayBuffer> buffer;
6036 if (obj->IsJSDataView()) {
6037 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj));
6038 DCHECK(data_view->buffer()->IsJSArrayBuffer());
6039 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()));
6040 } else {
6041 DCHECK(obj->IsJSTypedArray());
6042 buffer = i::JSTypedArray::cast(*obj)->GetBuffer();
6043 }
6044 return Utils::ToLocal(buffer);
6045}
6046
6047
6048size_t v8::ArrayBufferView::ByteOffset() {
6049 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6050 return static_cast<size_t>(obj->byte_offset()->Number());
6051}
6052
6053
6054size_t v8::ArrayBufferView::ByteLength() {
6055 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6056 return static_cast<size_t>(obj->byte_length()->Number());
6057}
6058
6059
6060size_t v8::TypedArray::Length() {
6061 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
6062 return static_cast<size_t>(obj->length()->Number());
6063}
6064
6065
6066static inline void SetupArrayBufferView(
6067 i::Isolate* isolate,
6068 i::Handle<i::JSArrayBufferView> obj,
6069 i::Handle<i::JSArrayBuffer> buffer,
6070 size_t byte_offset,
6071 size_t byte_length) {
6072 DCHECK(byte_offset + byte_length <=
6073 static_cast<size_t>(buffer->byte_length()->Number()));
6074
6075 obj->set_buffer(*buffer);
6076
6077 obj->set_weak_next(buffer->weak_first_view());
6078 buffer->set_weak_first_view(*obj);
6079
6080 i::Handle<i::Object> byte_offset_object =
6081 isolate->factory()->NewNumberFromSize(byte_offset);
6082 obj->set_byte_offset(*byte_offset_object);
6083
6084 i::Handle<i::Object> byte_length_object =
6085 isolate->factory()->NewNumberFromSize(byte_length);
6086 obj->set_byte_length(*byte_length_object);
6087}
6088
6089template<typename ElementType,
6090 ExternalArrayType array_type,
6091 i::ElementsKind elements_kind>
6092i::Handle<i::JSTypedArray> NewTypedArray(
6093 i::Isolate* isolate,
6094 Handle<ArrayBuffer> array_buffer, size_t byte_offset, size_t length) {
6095 i::Handle<i::JSTypedArray> obj =
6096 isolate->factory()->NewJSTypedArray(array_type);
6097 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6098
6099 DCHECK(byte_offset % sizeof(ElementType) == 0);
6100
6101 CHECK(length <= (std::numeric_limits<size_t>::max() / sizeof(ElementType)));
6102 CHECK(length <= static_cast<size_t>(i::Smi::kMaxValue));
6103 size_t byte_length = length * sizeof(ElementType);
6104 SetupArrayBufferView(
6105 isolate, obj, buffer, byte_offset, byte_length);
6106
6107 i::Handle<i::Object> length_object =
6108 isolate->factory()->NewNumberFromSize(length);
6109 obj->set_length(*length_object);
6110
6111 i::Handle<i::ExternalArray> elements =
6112 isolate->factory()->NewExternalArray(
6113 static_cast<int>(length), array_type,
6114 static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
6115 i::Handle<i::Map> map =
6116 i::JSObject::GetElementsTransitionMap(obj, elements_kind);
6117 i::JSObject::SetMapAndElements(obj, map, elements);
6118 return obj;
6119}
6120
6121
6122#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
6123 Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \
6124 size_t byte_offset, size_t length) { \
6125 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
6126 LOG_API(isolate, \
6127 "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
6128 ENTER_V8(isolate); \
6129 if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
6130 "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \
6131 "length exceeds max allowed value")) { \
6132 return Local<Type##Array>(); \
6133 } \
6134 i::Handle<i::JSTypedArray> obj = \
6135 NewTypedArray<ctype, v8::kExternal##Type##Array, \
6136 i::EXTERNAL_##TYPE##_ELEMENTS>( \
6137 isolate, array_buffer, byte_offset, length); \
6138 return Utils::ToLocal##Type##Array(obj); \
6139 }
6140
6141
6142TYPED_ARRAYS(TYPED_ARRAY_NEW)
6143#undef TYPED_ARRAY_NEW
6144
6145Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
6146 size_t byte_offset, size_t byte_length) {
6147 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6148 i::Isolate* isolate = buffer->GetIsolate();
6149 LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
6150 ENTER_V8(isolate);
6151 i::Handle<i::JSDataView> obj = isolate->factory()->NewJSDataView();
6152 SetupArrayBufferView(
6153 isolate, obj, buffer, byte_offset, byte_length);
6154 return Utils::ToLocal(obj);
6155}
6156
6157
6158Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
6159 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6160 LOG_API(i_isolate, "Symbol::New()");
6161 ENTER_V8(i_isolate);
6162 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6163 if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
Steve Blocka7e24c12009-10-30 11:49:00 +00006164 return Utils::ToLocal(result);
6165}
6166
6167
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006168static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
6169 i::Handle<i::String> name,
6170 i::Handle<i::String> part) {
6171 i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
6172 i::Handle<i::JSObject> symbols =
6173 i::Handle<i::JSObject>::cast(
6174 i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6175 i::Handle<i::Object> symbol =
6176 i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
6177 if (!symbol->IsSymbol()) {
6178 DCHECK(symbol->IsUndefined());
6179 symbol = isolate->factory()->NewSymbol();
6180 i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
6181 i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert();
Steve Blockd0582a62009-12-15 09:54:21 +00006182 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006183 return i::Handle<i::Symbol>::cast(symbol);
6184}
6185
6186
6187Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
6188 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6189 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6190 i::Handle<i::String> part = i_isolate->factory()->for_string();
6191 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6192}
6193
6194
6195Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
6196 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6197 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6198 i::Handle<i::String> part = i_isolate->factory()->for_api_string();
6199 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6200}
6201
6202
6203static Local<Symbol> GetWellKnownSymbol(Isolate* isolate, const char* name) {
6204 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6205 i::Handle<i::String> i_name =
6206 Utils::OpenHandle(*String::NewFromUtf8(isolate, name));
6207 i::Handle<i::String> part = i_isolate->factory()->for_intern_string();
6208 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
6209}
6210
6211
6212Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
6213 return GetWellKnownSymbol(isolate, "Symbol.iterator");
6214}
6215
6216
6217Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
6218 return GetWellKnownSymbol(isolate, "Symbol.unscopables");
6219}
6220
6221
6222Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
6223 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6224 LOG_API(i_isolate, "Private::New()");
6225 ENTER_V8(i_isolate);
6226 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
6227 if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
6228 Local<Symbol> result = Utils::ToLocal(symbol);
6229 return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
6230}
6231
6232
6233Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
6234 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6235 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6236 i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
6237 i::Handle<i::String> part = i_isolate->factory()->private_api_string();
6238 i::Handle<i::JSObject> privates =
6239 i::Handle<i::JSObject>::cast(
6240 i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6241 i::Handle<i::Object> symbol =
6242 i::Object::GetPropertyOrElement(privates, i_name).ToHandleChecked();
6243 if (!symbol->IsSymbol()) {
6244 DCHECK(symbol->IsUndefined());
6245 symbol = i_isolate->factory()->NewPrivateSymbol();
6246 i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
6247 i::JSObject::SetProperty(privates, i_name, symbol, i::STRICT).Assert();
6248 }
6249 Local<Symbol> result = Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
6250 return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
6251}
6252
6253
6254Local<Number> v8::Number::New(Isolate* isolate, double value) {
6255 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6256 DCHECK(internal_isolate->IsInitialized());
6257 if (std::isnan(value)) {
6258 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
6259 value = base::OS::nan_value();
6260 }
6261 ENTER_V8(internal_isolate);
6262 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006263 return Utils::NumberToLocal(result);
6264}
6265
6266
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006267Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
6268 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6269 DCHECK(internal_isolate->IsInitialized());
Steve Blocka7e24c12009-10-30 11:49:00 +00006270 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01006271 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006272 internal_isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00006273 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006274 ENTER_V8(internal_isolate);
6275 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006276 return Utils::IntegerToLocal(result);
6277}
6278
6279
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006280Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
6281 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6282 DCHECK(internal_isolate->IsInitialized());
Steve Block3ce2e202009-11-05 08:53:23 +00006283 bool fits_into_int32_t = (value & (1 << 31)) == 0;
6284 if (fits_into_int32_t) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006285 return Integer::New(isolate, static_cast<int32_t>(value));
Steve Block3ce2e202009-11-05 08:53:23 +00006286 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006287 ENTER_V8(internal_isolate);
6288 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00006289 return Utils::IntegerToLocal(result);
6290}
6291
6292
Steve Blocka7e24c12009-10-30 11:49:00 +00006293bool V8::AddMessageListener(MessageCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01006294 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006295 ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
6296 ENTER_V8(isolate);
6297 i::HandleScope scope(isolate);
6298 NeanderArray listeners(isolate->factory()->message_listeners());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006299 NeanderObject obj(isolate, 2);
Ben Murdoch257744e2011-11-30 15:57:28 +00006300 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006301 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
6302 : *Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00006303 listeners.add(obj.value());
6304 return true;
6305}
6306
6307
6308void V8::RemoveMessageListeners(MessageCallback that) {
Steve Block44f0eee2011-05-26 01:26:41 +01006309 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006310 ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
6311 ENTER_V8(isolate);
6312 i::HandleScope scope(isolate);
6313 NeanderArray listeners(isolate->factory()->message_listeners());
Steve Blocka7e24c12009-10-30 11:49:00 +00006314 for (int i = 0; i < listeners.length(); i++) {
6315 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
6316
6317 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
Ben Murdoch257744e2011-11-30 15:57:28 +00006318 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006319 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
Steve Block44f0eee2011-05-26 01:26:41 +01006320 listeners.set(i, isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00006321 }
6322 }
6323}
6324
6325
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006326void V8::SetCaptureStackTraceForUncaughtExceptions(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006327 bool capture,
6328 int frame_limit,
6329 StackTrace::StackTraceOptions options) {
Steve Block44f0eee2011-05-26 01:26:41 +01006330 i::Isolate::Current()->SetCaptureStackTraceForUncaughtExceptions(
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006331 capture,
6332 frame_limit,
6333 options);
6334}
6335
6336
Steve Blocka7e24c12009-10-30 11:49:00 +00006337void V8::SetFailedAccessCheckCallbackFunction(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006338 FailedAccessCheckCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01006339 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006340 isolate->SetFailedAccessCheckCallback(callback);
6341}
6342
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006343
6344void Isolate::CollectAllGarbage(const char* gc_reason) {
6345 reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
6346 i::Heap::kNoGCFlags, gc_reason);
Steve Blocka7e24c12009-10-30 11:49:00 +00006347}
6348
6349
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006350HeapProfiler* Isolate::GetHeapProfiler() {
6351 i::HeapProfiler* heap_profiler =
6352 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
6353 return reinterpret_cast<HeapProfiler*>(heap_profiler);
Steve Blocka7e24c12009-10-30 11:49:00 +00006354}
6355
6356
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006357CpuProfiler* Isolate::GetCpuProfiler() {
6358 i::CpuProfiler* cpu_profiler =
6359 reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
6360 return reinterpret_cast<CpuProfiler*>(cpu_profiler);
6361}
6362
6363
6364bool Isolate::InContext() {
6365 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6366 return isolate->context() != NULL;
6367}
6368
6369
6370v8::Local<v8::Context> Isolate::GetCurrentContext() {
6371 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6372 i::Context* context = isolate->context();
6373 if (context == NULL) return Local<Context>();
6374 i::Context* native_context = context->native_context();
6375 if (native_context == NULL) return Local<Context>();
6376 return Utils::ToLocal(i::Handle<i::Context>(native_context));
6377}
6378
6379
6380v8::Local<v8::Context> Isolate::GetCallingContext() {
6381 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6382 i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
6383 if (calling.is_null()) return Local<Context>();
6384 return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
6385}
6386
6387
6388v8::Local<v8::Context> Isolate::GetEnteredContext() {
6389 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6390 i::Handle<i::Object> last =
6391 isolate->handle_scope_implementer()->LastEnteredContext();
6392 if (last.is_null()) return Local<Context>();
6393 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
6394}
6395
6396
6397v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
6398 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6399 ENTER_V8(isolate);
6400 // If we're passed an empty handle, we throw an undefined exception
6401 // to deal more gracefully with out of memory situations.
6402 if (value.IsEmpty()) {
6403 isolate->ScheduleThrow(isolate->heap()->undefined_value());
6404 } else {
6405 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Block44f0eee2011-05-26 01:26:41 +01006406 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006407 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00006408}
6409
6410
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006411void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
6412 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6413 internal_isolate->global_handles()->SetObjectGroupId(
6414 v8::internal::Handle<v8::internal::Object>(object).location(),
6415 id);
Steve Blocka7e24c12009-10-30 11:49:00 +00006416}
6417
6418
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006419void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
6420 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6421 internal_isolate->global_handles()->SetReferenceFromGroup(
6422 id,
6423 v8::internal::Handle<v8::internal::Object>(object).location());
6424}
6425
6426
6427void Isolate::SetReference(internal::Object** parent,
6428 internal::Object** child) {
6429 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
6430 i::Object** parent_location =
6431 v8::internal::Handle<v8::internal::Object>(parent).location();
6432 internal_isolate->global_handles()->SetReference(
6433 reinterpret_cast<i::HeapObject**>(parent_location),
6434 v8::internal::Handle<v8::internal::Object>(child).location());
6435}
6436
6437
6438void Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
6439 GCType gc_type) {
6440 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6441 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
6442}
6443
6444
6445void Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
6446 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6447 isolate->heap()->RemoveGCPrologueCallback(callback);
6448}
6449
6450
6451void Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
6452 GCType gc_type) {
6453 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6454 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
6455}
6456
6457
6458void Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
6459 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6460 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00006461}
6462
6463
Steve Block6ded16b2010-05-10 14:33:55 +01006464void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01006465 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006466 isolate->heap()->AddGCPrologueCallback(
6467 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
6468 gc_type,
6469 false);
Steve Block6ded16b2010-05-10 14:33:55 +01006470}
6471
6472
6473void V8::RemoveGCPrologueCallback(GCPrologueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01006474 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006475 isolate->heap()->RemoveGCPrologueCallback(
6476 reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback));
Steve Block6ded16b2010-05-10 14:33:55 +01006477}
6478
6479
6480void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01006481 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006482 isolate->heap()->AddGCEpilogueCallback(
6483 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
6484 gc_type,
6485 false);
Steve Block6ded16b2010-05-10 14:33:55 +01006486}
6487
6488
6489void V8::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01006490 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006491 isolate->heap()->RemoveGCEpilogueCallback(
6492 reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback));
Steve Block6ded16b2010-05-10 14:33:55 +01006493}
6494
6495
Iain Merrick9ac36c92010-09-13 15:29:50 +01006496void V8::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
6497 ObjectSpace space,
6498 AllocationAction action) {
Steve Block44f0eee2011-05-26 01:26:41 +01006499 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006500 isolate->memory_allocator()->AddMemoryAllocationCallback(
6501 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01006502}
6503
6504
6505void V8::RemoveMemoryAllocationCallback(MemoryAllocationCallback callback) {
Steve Block44f0eee2011-05-26 01:26:41 +01006506 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006507 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
6508 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01006509}
6510
6511
Steve Block44f0eee2011-05-26 01:26:41 +01006512void V8::TerminateExecution(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006513 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6514 i_isolate->stack_guard()->RequestTerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00006515}
6516
6517
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006518bool V8::IsExecutionTerminating(Isolate* isolate) {
6519 i::Isolate* i_isolate = isolate != NULL ?
6520 reinterpret_cast<i::Isolate*>(isolate) : i::Isolate::Current();
6521 return IsExecutionTerminatingCheck(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01006522}
6523
6524
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006525void V8::CancelTerminateExecution(Isolate* isolate) {
6526 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6527 i_isolate->stack_guard()->ClearTerminateExecution();
6528 i_isolate->CancelTerminateExecution();
6529}
6530
6531
6532void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
6533 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
6534 i_isolate->set_api_interrupt_callback(callback);
6535 i_isolate->set_api_interrupt_callback_data(data);
6536 i_isolate->stack_guard()->RequestApiInterrupt();
6537}
6538
6539
6540void Isolate::ClearInterrupt() {
6541 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
6542 i_isolate->stack_guard()->ClearApiInterrupt();
6543 i_isolate->set_api_interrupt_callback(NULL);
6544 i_isolate->set_api_interrupt_callback_data(NULL);
6545}
6546
6547
6548void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
6549 CHECK(i::FLAG_expose_gc);
6550 if (type == kMinorGarbageCollection) {
6551 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
6552 i::NEW_SPACE, "Isolate::RequestGarbageCollection",
6553 kGCCallbackFlagForced);
6554 } else {
6555 DCHECK_EQ(kFullGarbageCollection, type);
6556 reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
6557 i::Heap::kAbortIncrementalMarkingMask,
6558 "Isolate::RequestGarbageCollection", kGCCallbackFlagForced);
6559 }
6560}
6561
6562
Steve Block44f0eee2011-05-26 01:26:41 +01006563Isolate* Isolate::GetCurrent() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006564 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006565 return reinterpret_cast<Isolate*>(isolate);
6566}
6567
6568
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006569Isolate* Isolate::New(const Isolate::CreateParams& params) {
Steve Block44f0eee2011-05-26 01:26:41 +01006570 i::Isolate* isolate = new i::Isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006571 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
6572 if (params.entry_hook) {
6573 isolate->set_function_entry_hook(params.entry_hook);
6574 }
6575 if (params.code_event_handler) {
6576 isolate->InitializeLoggingAndCounters();
6577 isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
6578 params.code_event_handler);
6579 }
6580 SetResourceConstraints(isolate, params.constraints);
6581 if (params.enable_serializer) {
6582 isolate->enable_serializer();
6583 }
6584 // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
6585 Isolate::Scope isolate_scope(v8_isolate);
6586 if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
6587 // If the isolate has a function entry hook, it needs to re-build all its
6588 // code stubs with entry hooks embedded, so don't deserialize a snapshot.
6589 isolate->Init(NULL);
6590 }
6591 return v8_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +01006592}
6593
6594
6595void Isolate::Dispose() {
6596 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006597 if (!Utils::ApiCheck(!isolate->IsInUse(),
6598 "v8::Isolate::Dispose()",
6599 "Disposing the isolate that is entered by a thread.")) {
Steve Block44f0eee2011-05-26 01:26:41 +01006600 return;
Steve Block6ded16b2010-05-10 14:33:55 +01006601 }
Steve Block44f0eee2011-05-26 01:26:41 +01006602 isolate->TearDown();
6603}
6604
6605
6606void Isolate::Enter() {
6607 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6608 isolate->Enter();
6609}
6610
6611
6612void Isolate::Exit() {
6613 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6614 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01006615}
6616
6617
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006618Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
6619 Isolate* isolate,
6620 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
6621 : on_failure_(on_failure) {
6622 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6623 if (on_failure_ == CRASH_ON_FAILURE) {
6624 internal_ = reinterpret_cast<void*>(
6625 new i::DisallowJavascriptExecution(i_isolate));
6626 } else {
6627 DCHECK_EQ(THROW_ON_FAILURE, on_failure);
6628 internal_ = reinterpret_cast<void*>(
6629 new i::ThrowOnJavascriptExecution(i_isolate));
6630 }
Ben Murdoch257744e2011-11-30 15:57:28 +00006631}
6632
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006633
6634Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
6635 if (on_failure_ == CRASH_ON_FAILURE) {
6636 delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
6637 } else {
6638 delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
6639 }
6640}
6641
6642
6643Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
6644 Isolate* isolate) {
6645 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6646 internal_assert_ = reinterpret_cast<void*>(
6647 new i::AllowJavascriptExecution(i_isolate));
6648 internal_throws_ = reinterpret_cast<void*>(
6649 new i::NoThrowOnJavascriptExecution(i_isolate));
6650}
6651
6652
6653Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
6654 delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
6655 delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
6656}
6657
6658
6659Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
6660 Isolate* isolate)
6661 : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
6662 isolate_->handle_scope_implementer()->IncrementCallDepth();
6663}
6664
6665
6666Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
6667 isolate_->handle_scope_implementer()->DecrementCallDepth();
6668}
6669
6670
6671void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
Ben Murdoch257744e2011-11-30 15:57:28 +00006672 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006673 if (!isolate->IsInitialized()) {
6674 heap_statistics->total_heap_size_ = 0;
6675 heap_statistics->total_heap_size_executable_ = 0;
6676 heap_statistics->total_physical_size_ = 0;
6677 heap_statistics->used_heap_size_ = 0;
6678 heap_statistics->heap_size_limit_ = 0;
6679 return;
6680 }
6681 i::Heap* heap = isolate->heap();
6682 heap_statistics->total_heap_size_ = heap->CommittedMemory();
6683 heap_statistics->total_heap_size_executable_ =
6684 heap->CommittedMemoryExecutable();
6685 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
6686 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
6687 heap_statistics->heap_size_limit_ = heap->MaxReserved();
6688}
6689
6690
6691void Isolate::SetEventLogger(LogEventCallback that) {
6692 // Do not overwrite the event logger if we want to log explicitly.
6693 if (i::FLAG_log_timer_events) return;
6694 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6695 isolate->set_event_logger(that);
6696}
6697
6698
6699void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
6700 if (callback == NULL) return;
6701 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6702 isolate->AddCallCompletedCallback(callback);
6703}
6704
6705
6706void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
6707 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6708 isolate->RemoveCallCompletedCallback(callback);
6709}
6710
6711
6712void Isolate::RunMicrotasks() {
6713 reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
6714}
6715
6716
6717void Isolate::EnqueueMicrotask(Handle<Function> microtask) {
6718 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6719 isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
6720}
6721
6722
6723void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
6724 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6725 i::HandleScope scope(isolate);
6726 i::Handle<i::CallHandlerInfo> callback_info =
6727 i::Handle<i::CallHandlerInfo>::cast(
6728 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE));
6729 SET_FIELD_WRAPPED(callback_info, set_callback, microtask);
6730 SET_FIELD_WRAPPED(callback_info, set_data, data);
6731 isolate->EnqueueMicrotask(callback_info);
6732}
6733
6734
6735void Isolate::SetAutorunMicrotasks(bool autorun) {
6736 reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
6737}
6738
6739
6740bool Isolate::WillAutorunMicrotasks() const {
6741 return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks();
6742}
6743
6744
6745void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
6746 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
6747}
6748
6749
6750void Isolate::SetCounterFunction(CounterLookupCallback callback) {
6751 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6752 isolate->stats_table()->SetCounterFunction(callback);
6753 isolate->InitializeLoggingAndCounters();
6754 isolate->counters()->ResetCounters();
6755}
6756
6757
6758void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
6759 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6760 isolate->stats_table()->SetCreateHistogramFunction(callback);
6761 isolate->InitializeLoggingAndCounters();
6762 isolate->counters()->ResetHistograms();
6763}
6764
6765
6766void Isolate::SetAddHistogramSampleFunction(
6767 AddHistogramSampleCallback callback) {
6768 reinterpret_cast<i::Isolate*>(this)
6769 ->stats_table()
6770 ->SetAddHistogramSampleFunction(callback);
6771}
6772
6773
6774bool v8::Isolate::IdleNotification(int idle_time_in_ms) {
6775 // Returning true tells the caller that it need not
6776 // continue to call IdleNotification.
6777 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6778 if (!i::FLAG_use_idle_notification) return true;
6779 return isolate->heap()->IdleNotification(idle_time_in_ms);
6780}
6781
6782
6783void v8::Isolate::LowMemoryNotification() {
6784 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6785 {
6786 i::HistogramTimerScope idle_notification_scope(
6787 isolate->counters()->gc_low_memory_notification());
6788 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
6789 }
6790}
6791
6792
6793int v8::Isolate::ContextDisposedNotification() {
6794 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6795 return isolate->heap()->NotifyContextDisposed();
6796}
6797
6798
6799void v8::Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
6800 JitCodeEventHandler event_handler) {
6801 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6802 // Ensure that logging is initialized for our isolate.
6803 isolate->InitializeLoggingAndCounters();
6804 isolate->logger()->SetCodeEventHandler(options, event_handler);
6805}
6806
6807
6808void v8::Isolate::SetStackLimit(uintptr_t stack_limit) {
6809 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6810 CHECK(stack_limit);
6811 isolate->stack_guard()->SetStackLimit(stack_limit);
Ben Murdoch257744e2011-11-30 15:57:28 +00006812}
6813
6814
6815String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
6816 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01006817 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00006818 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01006819 ENTER_V8(isolate);
6820 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006821 TryCatch try_catch;
6822 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00006823 if (str.IsEmpty()) return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006824 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006825 length_ = v8::Utf8Length(*i_str, isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00006826 str_ = i::NewArray<char>(length_ + 1);
6827 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00006828}
6829
6830
6831String::Utf8Value::~Utf8Value() {
6832 i::DeleteArray(str_);
6833}
6834
6835
Ben Murdoch257744e2011-11-30 15:57:28 +00006836String::Value::Value(v8::Handle<v8::Value> obj)
6837 : str_(NULL), length_(0) {
Steve Block44f0eee2011-05-26 01:26:41 +01006838 i::Isolate* isolate = i::Isolate::Current();
Ben Murdoch257744e2011-11-30 15:57:28 +00006839 if (obj.IsEmpty()) return;
Steve Block44f0eee2011-05-26 01:26:41 +01006840 ENTER_V8(isolate);
6841 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006842 TryCatch try_catch;
6843 Handle<String> str = obj->ToString();
Ben Murdoch257744e2011-11-30 15:57:28 +00006844 if (str.IsEmpty()) return;
6845 length_ = str->Length();
6846 str_ = i::NewArray<uint16_t>(length_ + 1);
6847 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00006848}
6849
6850
6851String::Value::~Value() {
6852 i::DeleteArray(str_);
6853}
6854
Steve Blocka7e24c12009-10-30 11:49:00 +00006855
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006856#define DEFINE_ERROR(NAME) \
6857 Local<Value> Exception::NAME(v8::Handle<v8::String> raw_message) { \
6858 i::Isolate* isolate = i::Isolate::Current(); \
6859 LOG_API(isolate, #NAME); \
6860 ON_BAILOUT(isolate, "v8::Exception::" #NAME "()", return Local<Value>()); \
6861 ENTER_V8(isolate); \
6862 i::Object* error; \
6863 { \
6864 i::HandleScope scope(isolate); \
6865 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
6866 i::Handle<i::Object> result; \
6867 EXCEPTION_PREAMBLE(isolate); \
6868 i::MaybeHandle<i::Object> maybe_result = \
6869 isolate->factory()->New##NAME(message); \
6870 has_pending_exception = !maybe_result.ToHandle(&result); \
6871 /* TODO(yangguo): crbug/403509. Return empty handle instead. */ \
6872 EXCEPTION_BAILOUT_CHECK( \
6873 isolate, v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate))); \
6874 error = *result; \
6875 } \
6876 i::Handle<i::Object> result(error, isolate); \
6877 return Utils::ToLocal(result); \
Steve Blocka7e24c12009-10-30 11:49:00 +00006878 }
Steve Blocka7e24c12009-10-30 11:49:00 +00006879
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006880DEFINE_ERROR(RangeError)
6881DEFINE_ERROR(ReferenceError)
6882DEFINE_ERROR(SyntaxError)
6883DEFINE_ERROR(TypeError)
6884DEFINE_ERROR(Error)
Steve Blocka7e24c12009-10-30 11:49:00 +00006885
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006886#undef DEFINE_ERROR
Steve Blocka7e24c12009-10-30 11:49:00 +00006887
6888
6889// --- D e b u g S u p p o r t ---
6890
Steve Blocka7e24c12009-10-30 11:49:00 +00006891bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01006892 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006893 ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
6894 ENTER_V8(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01006895 i::HandleScope scope(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00006896 i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00006897 if (that != NULL) {
Ben Murdoch257744e2011-11-30 15:57:28 +00006898 foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00006899 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006900 isolate->debug()->SetEventListener(foreign,
6901 Utils::OpenHandle(*data, true));
Steve Blocka7e24c12009-10-30 11:49:00 +00006902 return true;
6903}
6904
6905
Steve Block44f0eee2011-05-26 01:26:41 +01006906void Debug::DebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006907 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
Steve Blocka7e24c12009-10-30 11:49:00 +00006908}
6909
6910
Steve Block44f0eee2011-05-26 01:26:41 +01006911void Debug::CancelDebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006912 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6913 internal_isolate->stack_guard()->ClearDebugBreak();
Ben Murdochf87a2032010-10-22 12:50:53 +01006914}
6915
6916
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006917bool Debug::CheckDebugBreak(Isolate* isolate) {
6918 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6919 return internal_isolate->stack_guard()->CheckDebugBreak();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01006920}
6921
6922
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006923void Debug::DebugBreakForCommand(Isolate* isolate, ClientData* data) {
6924 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6925 internal_isolate->debug()->EnqueueDebugCommand(data);
6926}
6927
6928
6929void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
Steve Block44f0eee2011-05-26 01:26:41 +01006930 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01006931 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006932 isolate->debug()->SetMessageHandler(handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00006933}
6934
6935
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006936void Debug::SendCommand(Isolate* isolate,
6937 const uint16_t* command,
6938 int length,
6939 ClientData* client_data) {
6940 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
6941 internal_isolate->debug()->EnqueueCommandMessage(
6942 i::Vector<const uint16_t>(command, length), client_data);
Steve Blockd0582a62009-12-15 09:54:21 +00006943}
6944
6945
Steve Blocka7e24c12009-10-30 11:49:00 +00006946Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
6947 v8::Handle<v8::Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01006948 i::Isolate* isolate = i::Isolate::Current();
6949 if (!isolate->IsInitialized()) return Local<Value>();
6950 ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
6951 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006952 i::MaybeHandle<i::Object> maybe_result;
Steve Block44f0eee2011-05-26 01:26:41 +01006953 EXCEPTION_PREAMBLE(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006954 if (data.IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006955 maybe_result = isolate->debug()->Call(
6956 Utils::OpenHandle(*fun), isolate->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00006957 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006958 maybe_result = isolate->debug()->Call(
6959 Utils::OpenHandle(*fun), Utils::OpenHandle(*data));
Steve Blocka7e24c12009-10-30 11:49:00 +00006960 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006961 i::Handle<i::Object> result;
6962 has_pending_exception = !maybe_result.ToHandle(&result);
Steve Block44f0eee2011-05-26 01:26:41 +01006963 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Steve Blocka7e24c12009-10-30 11:49:00 +00006964 return Utils::ToLocal(result);
6965}
6966
6967
6968Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
Steve Block44f0eee2011-05-26 01:26:41 +01006969 i::Isolate* isolate = i::Isolate::Current();
6970 if (!isolate->IsInitialized()) return Local<Value>();
6971 ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
6972 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006973 v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Block44f0eee2011-05-26 01:26:41 +01006974 i::Debug* isolate_debug = isolate->debug();
Steve Block44f0eee2011-05-26 01:26:41 +01006975 EXCEPTION_PREAMBLE(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006976 has_pending_exception = !isolate_debug->Load();
6977 v8::Local<v8::Value> result;
6978 if (!has_pending_exception) {
6979 i::Handle<i::JSObject> debug(
6980 isolate_debug->debug_context()->global_object());
6981 i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
6982 STATIC_CHAR_VECTOR("MakeMirror"));
6983 i::Handle<i::Object> fun_obj =
6984 i::Object::GetProperty(debug, name).ToHandleChecked();
6985 i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
6986 v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
6987 const int kArgc = 1;
6988 v8::Handle<v8::Value> argv[kArgc] = { obj };
6989 result = v8_fun->Call(Utils::ToLocal(debug), kArgc, argv);
6990 has_pending_exception = result.IsEmpty();
6991 }
Steve Block44f0eee2011-05-26 01:26:41 +01006992 EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006993 return scope.Escape(result);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006994}
6995
6996
Leon Clarkee46be812010-01-19 14:06:41 +00006997void Debug::ProcessDebugMessages() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006998 i::Isolate::Current()->debug()->ProcessDebugMessages(true);
Leon Clarkee46be812010-01-19 14:06:41 +00006999}
7000
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007001
Steve Block6ded16b2010-05-10 14:33:55 +01007002Local<Context> Debug::GetDebugContext() {
Steve Block44f0eee2011-05-26 01:26:41 +01007003 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01007004 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007005 return Utils::ToLocal(i::Isolate::Current()->debug()->GetDebugContext());
Steve Block6ded16b2010-05-10 14:33:55 +01007006}
7007
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007008
7009void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
7010 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7011 internal_isolate->debug()->set_live_edit_enabled(enable);
7012}
Steve Blocka7e24c12009-10-30 11:49:00 +00007013
Steve Block6ded16b2010-05-10 14:33:55 +01007014
Steve Block6ded16b2010-05-10 14:33:55 +01007015Handle<String> CpuProfileNode::GetFunctionName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007016 i::Isolate* isolate = i::Isolate::Current();
Steve Block6ded16b2010-05-10 14:33:55 +01007017 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7018 const i::CodeEntry* entry = node->entry();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007019 i::Handle<i::String> name =
7020 isolate->factory()->InternalizeUtf8String(entry->name());
Steve Block6ded16b2010-05-10 14:33:55 +01007021 if (!entry->has_name_prefix()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007022 return ToApiHandle<String>(name);
Steve Block6ded16b2010-05-10 14:33:55 +01007023 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007024 // We do not expect this to fail. Change this if it does.
7025 i::Handle<i::String> cons = isolate->factory()->NewConsString(
7026 isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
7027 name).ToHandleChecked();
7028 return ToApiHandle<String>(cons);
Steve Block6ded16b2010-05-10 14:33:55 +01007029 }
7030}
7031
7032
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007033int CpuProfileNode::GetScriptId() const {
7034 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7035 const i::CodeEntry* entry = node->entry();
7036 return entry->script_id();
7037}
7038
7039
Steve Block6ded16b2010-05-10 14:33:55 +01007040Handle<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007041 i::Isolate* isolate = i::Isolate::Current();
Steve Block6ded16b2010-05-10 14:33:55 +01007042 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007043 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
7044 node->entry()->resource_name()));
Steve Block6ded16b2010-05-10 14:33:55 +01007045}
7046
7047
7048int CpuProfileNode::GetLineNumber() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007049 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
7050}
7051
7052
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007053int CpuProfileNode::GetColumnNumber() const {
7054 return reinterpret_cast<const i::ProfileNode*>(this)->
7055 entry()->column_number();
Steve Block6ded16b2010-05-10 14:33:55 +01007056}
7057
7058
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007059const char* CpuProfileNode::GetBailoutReason() const {
7060 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7061 return node->entry()->bailout_reason();
Steve Block6ded16b2010-05-10 14:33:55 +01007062}
7063
7064
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007065unsigned CpuProfileNode::GetHitCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007066 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
7067}
7068
7069
7070unsigned CpuProfileNode::GetCallUid() const {
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007071 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
Steve Block6ded16b2010-05-10 14:33:55 +01007072}
7073
7074
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007075unsigned CpuProfileNode::GetNodeId() const {
7076 return reinterpret_cast<const i::ProfileNode*>(this)->id();
7077}
7078
7079
Steve Block6ded16b2010-05-10 14:33:55 +01007080int CpuProfileNode::GetChildrenCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007081 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
7082}
7083
7084
7085const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block6ded16b2010-05-10 14:33:55 +01007086 const i::ProfileNode* child =
7087 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
7088 return reinterpret_cast<const CpuProfileNode*>(child);
7089}
7090
7091
Steve Block44f0eee2011-05-26 01:26:41 +01007092void CpuProfile::Delete() {
7093 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007094 i::CpuProfiler* profiler = isolate->cpu_profiler();
7095 DCHECK(profiler != NULL);
7096 profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
Steve Block6ded16b2010-05-10 14:33:55 +01007097}
7098
7099
7100Handle<String> CpuProfile::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007101 i::Isolate* isolate = i::Isolate::Current();
Steve Block6ded16b2010-05-10 14:33:55 +01007102 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007103 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
7104 profile->title()));
Steve Block6ded16b2010-05-10 14:33:55 +01007105}
7106
7107
7108const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007109 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7110 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
7111}
7112
7113
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007114const CpuProfileNode* CpuProfile::GetSample(int index) const {
7115 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7116 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
Steve Block6ded16b2010-05-10 14:33:55 +01007117}
7118
7119
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007120int64_t CpuProfile::GetSampleTimestamp(int index) const {
7121 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7122 return (profile->sample_timestamp(index) - base::TimeTicks())
7123 .InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01007124}
7125
7126
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007127int64_t CpuProfile::GetStartTime() const {
7128 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7129 return (profile->start_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01007130}
7131
7132
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007133int64_t CpuProfile::GetEndTime() const {
7134 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
7135 return (profile->end_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01007136}
7137
7138
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007139int CpuProfile::GetSamplesCount() const {
7140 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
7141}
7142
7143
7144void CpuProfiler::SetSamplingInterval(int us) {
7145 DCHECK(us >= 0);
7146 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
7147 base::TimeDelta::FromMicroseconds(us));
7148}
7149
7150
7151void CpuProfiler::StartProfiling(Handle<String> title, bool record_samples) {
7152 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
7153 *Utils::OpenHandle(*title), record_samples);
7154}
7155
7156
7157void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
7158 StartProfiling(title, record_samples);
7159}
7160
7161
7162CpuProfile* CpuProfiler::StopProfiling(Handle<String> title) {
7163 return reinterpret_cast<CpuProfile*>(
7164 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
Leon Clarkef7060e22010-06-03 12:02:55 +01007165 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01007166}
7167
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007168
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007169const CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title) {
7170 return StopProfiling(title);
7171}
7172
7173
7174void CpuProfiler::SetIdle(bool is_idle) {
7175 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
7176 i::StateTag state = isolate->current_vm_state();
7177 DCHECK(state == i::EXTERNAL || state == i::IDLE);
7178 if (isolate->js_entry_sp() != NULL) return;
7179 if (is_idle) {
7180 isolate->set_current_vm_state(i::IDLE);
7181 } else if (state == i::IDLE) {
7182 isolate->set_current_vm_state(i::EXTERNAL);
7183 }
Steve Block44f0eee2011-05-26 01:26:41 +01007184}
7185
7186
Iain Merrick75681382010-08-19 15:07:18 +01007187static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
7188 return const_cast<i::HeapGraphEdge*>(
7189 reinterpret_cast<const i::HeapGraphEdge*>(edge));
7190}
7191
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007192
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007193HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01007194 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007195}
7196
7197
7198Handle<Value> HeapGraphEdge::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007199 i::Isolate* isolate = i::Isolate::Current();
Iain Merrick75681382010-08-19 15:07:18 +01007200 i::HeapGraphEdge* edge = ToInternal(this);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007201 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01007202 case i::HeapGraphEdge::kContextVariable:
7203 case i::HeapGraphEdge::kInternal:
7204 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08007205 case i::HeapGraphEdge::kShortcut:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007206 case i::HeapGraphEdge::kWeak:
7207 return ToApiHandle<String>(
7208 isolate->factory()->InternalizeUtf8String(edge->name()));
Iain Merrick75681382010-08-19 15:07:18 +01007209 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08007210 case i::HeapGraphEdge::kHidden:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007211 return ToApiHandle<Number>(
7212 isolate->factory()->NewNumberFromInt(edge->index()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007213 default: UNREACHABLE();
7214 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007215 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007216}
7217
7218
7219const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007220 const i::HeapEntry* from = ToInternal(this)->from();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007221 return reinterpret_cast<const HeapGraphNode*>(from);
7222}
7223
7224
7225const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Iain Merrick75681382010-08-19 15:07:18 +01007226 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007227 return reinterpret_cast<const HeapGraphNode*>(to);
7228}
7229
7230
Iain Merrick75681382010-08-19 15:07:18 +01007231static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
7232 return const_cast<i::HeapEntry*>(
7233 reinterpret_cast<const i::HeapEntry*>(entry));
7234}
7235
7236
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007237HeapGraphNode::Type HeapGraphNode::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01007238 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007239}
7240
7241
7242Handle<String> HeapGraphNode::GetName() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007243 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007244 return ToApiHandle<String>(
7245 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007246}
7247
7248
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007249SnapshotObjectId HeapGraphNode::GetId() const {
Iain Merrick75681382010-08-19 15:07:18 +01007250 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007251}
7252
7253
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007254int HeapGraphNode::GetSelfSize() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007255 size_t size = ToInternal(this)->self_size();
7256 CHECK(size <= static_cast<size_t>(internal::kMaxInt));
7257 return static_cast<int>(size);
7258}
7259
7260
7261size_t HeapGraphNode::GetShallowSize() const {
Iain Merrick75681382010-08-19 15:07:18 +01007262 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007263}
7264
7265
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007266int HeapGraphNode::GetChildrenCount() const {
Iain Merrick75681382010-08-19 15:07:18 +01007267 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007268}
7269
7270
7271const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007272 return reinterpret_cast<const HeapGraphEdge*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007273 ToInternal(this)->children()[index]);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00007274}
7275
7276
Iain Merrick75681382010-08-19 15:07:18 +01007277static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
7278 return const_cast<i::HeapSnapshot*>(
7279 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
7280}
7281
7282
Steve Block44f0eee2011-05-26 01:26:41 +01007283void HeapSnapshot::Delete() {
7284 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007285 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
Steve Block44f0eee2011-05-26 01:26:41 +01007286 ToInternal(this)->Delete();
7287 } else {
7288 // If this is the last snapshot, clean up all accessory data as well.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007289 isolate->heap_profiler()->DeleteAllSnapshots();
Steve Block44f0eee2011-05-26 01:26:41 +01007290 }
7291}
7292
7293
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007294unsigned HeapSnapshot::GetUid() const {
Iain Merrick75681382010-08-19 15:07:18 +01007295 return ToInternal(this)->uid();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007296}
7297
7298
7299Handle<String> HeapSnapshot::GetTitle() const {
Steve Block44f0eee2011-05-26 01:26:41 +01007300 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007301 return ToApiHandle<String>(
7302 isolate->factory()->InternalizeUtf8String(ToInternal(this)->title()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007303}
7304
7305
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007306const HeapGraphNode* HeapSnapshot::GetRoot() const {
Iain Merrick75681382010-08-19 15:07:18 +01007307 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007308}
7309
7310
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007311const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
Ben Murdochb0fe1622011-05-05 13:52:32 +01007312 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007313 ToInternal(this)->GetEntryById(id));
Ben Murdochb0fe1622011-05-05 13:52:32 +01007314}
7315
7316
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007317int HeapSnapshot::GetNodesCount() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007318 return ToInternal(this)->entries().length();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007319}
7320
7321
7322const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007323 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007324 &ToInternal(this)->entries().at(index));
7325}
7326
7327
7328SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
7329 return ToInternal(this)->max_snapshot_js_object_id();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00007330}
7331
7332
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007333void HeapSnapshot::Serialize(OutputStream* stream,
7334 HeapSnapshot::SerializationFormat format) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007335 Utils::ApiCheck(format == kJSON,
7336 "v8::HeapSnapshot::Serialize",
7337 "Unknown serialization format");
7338 Utils::ApiCheck(stream->GetChunkSize() > 0,
7339 "v8::HeapSnapshot::Serialize",
7340 "Invalid stream chunk size");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01007341 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
7342 serializer.Serialize(stream);
7343}
7344
7345
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007346int HeapProfiler::GetSnapshotCount() {
7347 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007348}
7349
7350
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007351const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007352 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007353 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007354}
7355
7356
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007357SnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
7358 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
7359 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
7360}
7361
7362
7363Handle<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
7364 i::Handle<i::Object> obj =
7365 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
7366 if (obj.is_null()) return Local<Value>();
7367 return Utils::ToLocal(obj);
7368}
7369
7370
7371void HeapProfiler::ClearObjectIds() {
7372 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
7373}
7374
7375
7376const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
7377 Handle<String> title,
7378 ActivityControl* control,
7379 ObjectNameResolver* resolver) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007380 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007381 reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
7382 *Utils::OpenHandle(*title), control, resolver));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007383}
7384
7385
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007386void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
7387 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
7388 track_allocations);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01007389}
7390
Steve Block44f0eee2011-05-26 01:26:41 +01007391
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007392void HeapProfiler::StopTrackingHeapObjects() {
7393 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
Steve Block44f0eee2011-05-26 01:26:41 +01007394}
7395
7396
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007397SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
7398 return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
Steve Block44f0eee2011-05-26 01:26:41 +01007399}
7400
Steve Block6ded16b2010-05-10 14:33:55 +01007401
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007402void HeapProfiler::DeleteAllHeapSnapshots() {
7403 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
7404}
7405
7406
7407void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
7408 WrapperInfoCallback callback) {
7409 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
7410 callback);
7411}
7412
7413
7414size_t HeapProfiler::GetProfilerMemorySize() {
7415 return reinterpret_cast<i::HeapProfiler*>(this)->
7416 GetMemorySizeUsedByProfiler();
7417}
7418
7419
7420void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
7421 RetainedObjectInfo* info) {
7422 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007423}
7424
Steve Block6ded16b2010-05-10 14:33:55 +01007425
Ben Murdochb0fe1622011-05-05 13:52:32 +01007426v8::Testing::StressType internal::Testing::stress_type_ =
7427 v8::Testing::kStressTypeOpt;
7428
7429
7430void Testing::SetStressRunType(Testing::StressType type) {
7431 internal::Testing::set_stress_type(type);
7432}
7433
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007434
Ben Murdochb0fe1622011-05-05 13:52:32 +01007435int Testing::GetStressRuns() {
7436 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
7437#ifdef DEBUG
7438 // In debug mode the code runs much slower so stressing will only make two
7439 // runs.
7440 return 2;
7441#else
7442 return 5;
7443#endif
7444}
7445
7446
7447static void SetFlagsFromString(const char* flags) {
7448 V8::SetFlagsFromString(flags, i::StrLength(flags));
7449}
7450
7451
7452void Testing::PrepareStressRun(int run) {
7453 static const char* kLazyOptimizations =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007454 "--prepare-always-opt "
7455 "--max-inlined-source-size=999999 "
7456 "--max-inlined-nodes=999999 "
7457 "--max-inlined-nodes-cumulative=999999 "
7458 "--noalways-opt";
Ben Murdochb0fe1622011-05-05 13:52:32 +01007459 static const char* kForcedOptimizations = "--always-opt";
7460
7461 // If deoptimization stressed turn on frequent deoptimization. If no value
7462 // is spefified through --deopt-every-n-times use a default default value.
7463 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
7464 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
7465 internal::FLAG_deopt_every_n_times == 0) {
7466 SetFlagsFromString(kDeoptEvery13Times);
7467 }
7468
7469#ifdef DEBUG
7470 // As stressing in debug mode only make two runs skip the deopt stressing
7471 // here.
7472 if (run == GetStressRuns() - 1) {
7473 SetFlagsFromString(kForcedOptimizations);
7474 } else {
Ben Murdochb0fe1622011-05-05 13:52:32 +01007475 SetFlagsFromString(kLazyOptimizations);
7476 }
7477#else
7478 if (run == GetStressRuns() - 1) {
7479 SetFlagsFromString(kForcedOptimizations);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007480 } else if (run != GetStressRuns() - 2) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01007481 SetFlagsFromString(kLazyOptimizations);
7482 }
7483#endif
7484}
7485
7486
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007487// TODO(svenpanne) Deprecate this.
Steve Block44f0eee2011-05-26 01:26:41 +01007488void Testing::DeoptimizeAll() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007489 i::Isolate* isolate = i::Isolate::Current();
7490 i::HandleScope scope(isolate);
7491 internal::Deoptimizer::DeoptimizeAll(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00007492}
7493
7494
Steve Block44f0eee2011-05-26 01:26:41 +01007495namespace internal {
7496
7497
Steve Blocka7e24c12009-10-30 11:49:00 +00007498void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01007499 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00007500}
7501
7502
7503char* HandleScopeImplementer::ArchiveThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007504 HandleScopeData* current = isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00007505 handle_scope_data_ = *current;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007506 MemCopy(storage, this, sizeof(*this));
Steve Blocka7e24c12009-10-30 11:49:00 +00007507
7508 ResetAfterArchive();
7509 current->Initialize();
7510
7511 return storage + ArchiveSpacePerThread();
7512}
7513
7514
7515int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01007516 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00007517}
7518
7519
7520char* HandleScopeImplementer::RestoreThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007521 MemCopy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00007522 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00007523 return storage + ArchiveSpacePerThread();
7524}
7525
7526
7527void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007528#ifdef DEBUG
7529 bool found_block_before_deferred = false;
7530#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00007531 // Iterate over all handles in the blocks except for the last.
7532 for (int i = blocks()->length() - 2; i >= 0; --i) {
7533 Object** block = blocks()->at(i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007534 if (last_handle_before_deferred_block_ != NULL &&
7535 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
7536 (last_handle_before_deferred_block_ >= block)) {
7537 v->VisitPointers(block, last_handle_before_deferred_block_);
7538 DCHECK(!found_block_before_deferred);
7539#ifdef DEBUG
7540 found_block_before_deferred = true;
7541#endif
7542 } else {
7543 v->VisitPointers(block, &block[kHandleBlockSize]);
7544 }
Steve Blocka7e24c12009-10-30 11:49:00 +00007545 }
7546
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007547 DCHECK(last_handle_before_deferred_block_ == NULL ||
7548 found_block_before_deferred);
7549
Steve Blocka7e24c12009-10-30 11:49:00 +00007550 // Iterate over live handles in the last block (if any).
7551 if (!blocks()->is_empty()) {
7552 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
7553 }
7554
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007555 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
7556 for (unsigned i = 0; i < arraysize(context_lists); i++) {
7557 if (context_lists[i]->is_empty()) continue;
7558 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
7559 v->VisitPointers(start, start + context_lists[i]->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00007560 }
7561}
7562
7563
7564void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007565 HandleScopeData* current = isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01007566 handle_scope_data_ = *current;
7567 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00007568}
7569
7570
7571char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01007572 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00007573 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01007574 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00007575 return storage + ArchiveSpacePerThread();
7576}
7577
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007578
7579DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
7580 DeferredHandles* deferred =
7581 new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
7582
7583 while (!blocks_.is_empty()) {
7584 Object** block_start = blocks_.last();
7585 Object** block_limit = &block_start[kHandleBlockSize];
7586 // We should not need to check for SealHandleScope here. Assert this.
7587 DCHECK(prev_limit == block_limit ||
7588 !(block_start <= prev_limit && prev_limit <= block_limit));
7589 if (prev_limit == block_limit) break;
7590 deferred->blocks_.Add(blocks_.last());
7591 blocks_.RemoveLast();
7592 }
7593
7594 // deferred->blocks_ now contains the blocks installed on the
7595 // HandleScope stack since BeginDeferredScope was called, but in
7596 // reverse order.
7597
7598 DCHECK(prev_limit == NULL || !blocks_.is_empty());
7599
7600 DCHECK(!blocks_.is_empty() && prev_limit != NULL);
7601 DCHECK(last_handle_before_deferred_block_ != NULL);
7602 last_handle_before_deferred_block_ = NULL;
7603 return deferred;
7604}
7605
7606
7607void HandleScopeImplementer::BeginDeferredScope() {
7608 DCHECK(last_handle_before_deferred_block_ == NULL);
7609 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
7610}
7611
7612
7613DeferredHandles::~DeferredHandles() {
7614 isolate_->UnlinkDeferredHandles(this);
7615
7616 for (int i = 0; i < blocks_.length(); i++) {
7617#ifdef ENABLE_HANDLE_ZAPPING
7618 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
7619#endif
7620 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
7621 }
7622}
7623
7624
7625void DeferredHandles::Iterate(ObjectVisitor* v) {
7626 DCHECK(!blocks_.is_empty());
7627
7628 DCHECK((first_block_limit_ >= blocks_.first()) &&
7629 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
7630
7631 v->VisitPointers(blocks_.first(), first_block_limit_);
7632
7633 for (int i = 1; i < blocks_.length(); i++) {
7634 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
7635 }
7636}
7637
7638
7639void InvokeAccessorGetterCallback(
7640 v8::Local<v8::Name> property,
7641 const v8::PropertyCallbackInfo<v8::Value>& info,
7642 v8::AccessorNameGetterCallback getter) {
7643 // Leaving JavaScript.
7644 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7645 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
7646 getter));
7647 VMState<EXTERNAL> state(isolate);
7648 ExternalCallbackScope call_scope(isolate, getter_address);
7649 getter(property, info);
7650}
7651
7652
7653void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
7654 v8::FunctionCallback callback) {
7655 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
7656 Address callback_address =
7657 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
7658 VMState<EXTERNAL> state(isolate);
7659 ExternalCallbackScope call_scope(isolate, callback_address);
7660 callback(info);
7661}
7662
7663
Steve Blocka7e24c12009-10-30 11:49:00 +00007664} } // namespace v8::internal