blob: a71dcfaec31a7725760646d1263013c3811f8d4d [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.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include <limits>
13#include <vector>
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014#include "include/v8-debug.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015#include "include/v8-experimental.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "include/v8-profiler.h"
17#include "include/v8-testing.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010018#include "src/accessors.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019#include "src/api-experimental.h"
20#include "src/api-natives.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000021#include "src/assert-scope.h"
22#include "src/background-parsing-task.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040023#include "src/base/functional.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024#include "src/base/platform/platform.h"
25#include "src/base/platform/time.h"
26#include "src/base/utils/random-number-generator.h"
27#include "src/bootstrapper.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000028#include "src/char-predicates-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029#include "src/code-stubs.h"
30#include "src/compiler.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000031#include "src/context-measure.h"
32#include "src/contexts.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033#include "src/conversions-inl.h"
34#include "src/counters.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000035#include "src/debug/debug.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036#include "src/deoptimizer.h"
37#include "src/execution.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010038#include "src/gdb-jit.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039#include "src/global-handles.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040#include "src/icu_util.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000041#include "src/isolate-inl.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010042#include "src/json-parser.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043#include "src/messages.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044#include "src/parsing/parser.h"
45#include "src/parsing/scanner-character-streams.h"
46#include "src/pending-compilation-error-handler.h"
47#include "src/profiler/cpu-profiler.h"
48#include "src/profiler/heap-profiler.h"
49#include "src/profiler/heap-snapshot-generator-inl.h"
50#include "src/profiler/profile-generator-inl.h"
51#include "src/profiler/sampler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052#include "src/property.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053#include "src/property-descriptor.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054#include "src/property-details.h"
55#include "src/prototype.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040056#include "src/runtime/runtime.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057#include "src/runtime-profiler.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058#include "src/simulator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059#include "src/snapshot/natives.h"
60#include "src/snapshot/snapshot.h"
61#include "src/startup-data-util.h"
Ben Murdoch097c5b22016-05-18 11:27:45 +010062#include "src/tracing/trace-event.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000063#include "src/unicode-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064#include "src/v8.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065#include "src/v8threads.h"
66#include "src/version.h"
67#include "src/vm-state-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000068
69
Steve Blocka7e24c12009-10-30 11:49:00 +000070namespace v8 {
71
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000072#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
Steve Blocka7e24c12009-10-30 11:49:00 +000073
74
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000075#define ENTER_V8(isolate) i::VMState<v8::OTHER> __state__((isolate))
76
77
78#define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
79 bailout_value, HandleScopeClass, \
80 do_callback) \
81 if (IsExecutionTerminatingCheck(isolate)) { \
82 return bailout_value; \
83 } \
84 HandleScopeClass handle_scope(isolate); \
85 CallDepthScope call_depth_scope(isolate, context, do_callback); \
86 LOG_API(isolate, function_name); \
87 ENTER_V8(isolate); \
Steve Blocka7e24c12009-10-30 11:49:00 +000088 bool has_pending_exception = false
89
90
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000091#define PREPARE_FOR_EXECUTION_WITH_CONTEXT( \
92 context, function_name, bailout_value, HandleScopeClass, do_callback) \
93 auto isolate = context.IsEmpty() \
94 ? i::Isolate::Current() \
95 : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \
96 PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
97 bailout_value, HandleScopeClass, do_callback);
98
99
100#define PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, function_name, T) \
101 PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), function_name, \
102 MaybeLocal<T>(), InternalEscapableScope, \
103 false);
104
105
106#define PREPARE_FOR_EXECUTION(context, function_name, T) \
107 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \
108 InternalEscapableScope, false)
109
110
111#define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, function_name, T) \
112 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \
113 InternalEscapableScope, true)
114
115
116#define PREPARE_FOR_EXECUTION_PRIMITIVE(context, function_name, T) \
117 PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, Nothing<T>(), \
118 i::HandleScope, false)
119
120
121#define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value) \
122 do { \
123 if (has_pending_exception) { \
124 call_depth_scope.Escape(); \
125 return value; \
126 } \
Steve Blocka7e24c12009-10-30 11:49:00 +0000127 } while (false)
128
129
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130#define RETURN_ON_FAILED_EXECUTION(T) \
131 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, MaybeLocal<T>())
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100132
133
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134#define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \
135 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, Nothing<T>())
136
137
138#define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \
139 return maybe_local.FromMaybe(Local<T>());
140
141
142#define RETURN_ESCAPED(value) return handle_scope.Escape(value);
143
144
145namespace {
146
147Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) {
148 return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate())
149 ->GetCurrentContext();
150}
151
152class InternalEscapableScope : public v8::EscapableHandleScope {
153 public:
154 explicit inline InternalEscapableScope(i::Isolate* isolate)
155 : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {}
156};
157
158
159class CallDepthScope {
160 public:
161 explicit CallDepthScope(i::Isolate* isolate, Local<Context> context,
162 bool do_callback)
163 : isolate_(isolate),
164 context_(context),
165 escaped_(false),
166 do_callback_(do_callback) {
167 // TODO(dcarney): remove this when blink stops crashing.
168 DCHECK(!isolate_->external_caught_exception());
169 isolate_->IncrementJsCallsFromApiCounter();
170 isolate_->handle_scope_implementer()->IncrementCallDepth();
171 if (!context_.IsEmpty()) context_->Enter();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100172 if (do_callback_) isolate_->FireBeforeCallEnteredCallback();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000173 }
174 ~CallDepthScope() {
175 if (!context_.IsEmpty()) context_->Exit();
176 if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
177 if (do_callback_) isolate_->FireCallCompletedCallback();
178 }
179
180 void Escape() {
181 DCHECK(!escaped_);
182 escaped_ = true;
183 auto handle_scope_implementer = isolate_->handle_scope_implementer();
184 handle_scope_implementer->DecrementCallDepth();
185 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();
186 isolate_->OptionalRescheduleException(call_depth_is_zero);
187 }
188
189 private:
190 i::Isolate* const isolate_;
191 Local<Context> context_;
192 bool escaped_;
193 bool do_callback_;
194};
195
196} // namespace
197
198
199static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
200 i::Handle<i::Script> script) {
201 i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
202 i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
203 v8::Isolate* v8_isolate =
204 reinterpret_cast<v8::Isolate*>(script->GetIsolate());
205 ScriptOriginOptions options(script->origin_options());
206 v8::ScriptOrigin origin(
207 Utils::ToLocal(scriptName),
208 v8::Integer::New(v8_isolate, script->line_offset()),
209 v8::Integer::New(v8_isolate, script->column_offset()),
210 v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()),
211 v8::Integer::New(v8_isolate, script->id()),
212 v8::Boolean::New(v8_isolate, options.IsEmbedderDebugScript()),
213 Utils::ToLocal(source_map_url),
214 v8::Boolean::New(v8_isolate, options.IsOpaque()));
215 return origin;
216}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100217
218
Steve Blocka7e24c12009-10-30 11:49:00 +0000219// --- E x c e p t i o n B e h a v i o r ---
220
221
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800222void i::FatalProcessOutOfMemory(const char* location) {
223 i::V8::FatalProcessOutOfMemory(location, false);
224}
225
Steve Blocka7e24c12009-10-30 11:49:00 +0000226
227// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
228// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100229void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230 i::Isolate* isolate = i::Isolate::Current();
231 char last_few_messages[Heap::kTraceRingBufferSize + 1];
232 char js_stacktrace[Heap::kStacktraceBufferSize + 1];
233 memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
234 memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
235
Steve Blockd0582a62009-12-15 09:54:21 +0000236 i::HeapStats heap_stats;
237 int start_marker;
238 heap_stats.start_marker = &start_marker;
239 int new_space_size;
240 heap_stats.new_space_size = &new_space_size;
241 int new_space_capacity;
242 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243 intptr_t old_space_size;
244 heap_stats.old_space_size = &old_space_size;
245 intptr_t old_space_capacity;
246 heap_stats.old_space_capacity = &old_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100247 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000248 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100249 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000250 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100251 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000252 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100253 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000254 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100255 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000256 heap_stats.lo_space_size = &lo_space_size;
257 int global_handle_count;
258 heap_stats.global_handle_count = &global_handle_count;
259 int weak_global_handle_count;
260 heap_stats.weak_global_handle_count = &weak_global_handle_count;
261 int pending_global_handle_count;
262 heap_stats.pending_global_handle_count = &pending_global_handle_count;
263 int near_death_global_handle_count;
264 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000265 int free_global_handle_count;
266 heap_stats.free_global_handle_count = &free_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100267 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100268 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100269 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100270 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
271 int objects_per_type[LAST_TYPE + 1] = {0};
272 heap_stats.objects_per_type = objects_per_type;
273 int size_per_type[LAST_TYPE + 1] = {0};
274 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100275 int os_error;
276 heap_stats.os_error = &os_error;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000277 heap_stats.last_few_messages = last_few_messages;
278 heap_stats.js_stacktrace = js_stacktrace;
Steve Blockd0582a62009-12-15 09:54:21 +0000279 int end_marker;
280 heap_stats.end_marker = &end_marker;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000281 if (isolate->heap()->HasBeenSetUp()) {
282 // BUG(1718): Don't use the take_snapshot since we don't support
283 // HeapIterator here without doing a special GC.
284 isolate->heap()->RecordStats(&heap_stats, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000285 char* first_newline = strchr(last_few_messages, '\n');
286 if (first_newline == NULL || first_newline[1] == '\0')
287 first_newline = last_few_messages;
288 PrintF("\n<--- Last few GCs --->\n%s\n", first_newline);
289 PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
Steve Blocka7e24c12009-10-30 11:49:00 +0000290 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000291 Utils::ApiCheck(false, location, "Allocation failed - process out of memory");
292 // If the fatal error handler returns, we stop execution.
293 FATAL("API fatal error handler returned after process out of memory");
Steve Blocka7e24c12009-10-30 11:49:00 +0000294}
295
296
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000297void Utils::ReportApiFailure(const char* location, const char* message) {
298 i::Isolate* isolate = i::Isolate::Current();
299 FatalErrorCallback callback = isolate->exception_behavior();
300 if (callback == NULL) {
301 base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
302 message);
303 base::OS::Abort();
304 } else {
305 callback(location, message);
306 }
307 isolate->SignalFatalError();
Steve Blocka7e24c12009-10-30 11:49:00 +0000308}
309
310
Steve Block44f0eee2011-05-26 01:26:41 +0100311static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100312 if (isolate->has_scheduled_exception()) {
313 return isolate->scheduled_exception() ==
314 isolate->heap()->termination_exception();
315 }
316 return false;
317}
318
319
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000320void V8::SetNativesDataBlob(StartupData* natives_blob) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400321 i::V8::SetNativesBlob(natives_blob);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000322}
323
324
325void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400326 i::V8::SetSnapshotBlob(snapshot_blob);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000327}
328
329
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330bool RunExtraCode(Isolate* isolate, Local<Context> context,
331 const char* utf8_source) {
332 // Run custom script if provided.
333 base::ElapsedTimer timer;
334 timer.Start();
335 TryCatch try_catch(isolate);
336 Local<String> source_string;
337 if (!String::NewFromUtf8(isolate, utf8_source, NewStringType::kNormal)
338 .ToLocal(&source_string)) {
339 return false;
340 }
341 Local<String> resource_name =
342 String::NewFromUtf8(isolate, "<embedded script>", NewStringType::kNormal)
343 .ToLocalChecked();
344 ScriptOrigin origin(resource_name);
345 ScriptCompiler::Source source(source_string, origin);
346 Local<Script> script;
347 if (!ScriptCompiler::Compile(context, &source).ToLocal(&script)) return false;
348 if (script->Run(context).IsEmpty()) return false;
349 if (i::FLAG_profile_deserialization) {
350 i::PrintF("Executing custom snapshot script took %0.3f ms\n",
351 timer.Elapsed().InMillisecondsF());
352 }
353 timer.Stop();
354 CHECK(!try_catch.HasCaught());
355 return true;
356}
357
358
359namespace {
360
361class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
362 public:
363 virtual void* Allocate(size_t length) {
364 void* data = AllocateUninitialized(length);
365 return data == NULL ? data : memset(data, 0, length);
366 }
367 virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
368 virtual void Free(void* data, size_t) { free(data); }
369};
370
371} // namespace
372
373
374StartupData V8::CreateSnapshotDataBlob(const char* custom_source) {
375 i::Isolate* internal_isolate = new i::Isolate(true);
376 ArrayBufferAllocator allocator;
377 internal_isolate->set_array_buffer_allocator(&allocator);
378 Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400379 StartupData result = {NULL, 0};
380 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000381 base::ElapsedTimer timer;
382 timer.Start();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400383 Isolate::Scope isolate_scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000384 internal_isolate->Init(NULL);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400385 Persistent<Context> context;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000386 i::Snapshot::Metadata metadata;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400387 {
388 HandleScope handle_scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 Local<Context> new_context = Context::New(isolate);
390 context.Reset(isolate, new_context);
391 if (custom_source != NULL) {
392 metadata.set_embeds_script(true);
393 Context::Scope context_scope(new_context);
394 if (!RunExtraCode(isolate, new_context, custom_source)) context.Reset();
395 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400396 }
397 if (!context.IsEmpty()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400398 // If we don't do this then we end up with a stray root pointing at the
399 // context even after we have disposed of the context.
400 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000401
402 // GC may have cleared weak cells, so compact any WeakFixedArrays
403 // found on the heap.
404 i::HeapIterator iterator(internal_isolate->heap(),
405 i::HeapIterator::kFilterUnreachable);
406 for (i::HeapObject* o = iterator.next(); o != NULL; o = iterator.next()) {
407 if (o->IsPrototypeInfo()) {
408 i::Object* prototype_users =
409 i::PrototypeInfo::cast(o)->prototype_users();
410 if (prototype_users->IsWeakFixedArray()) {
411 i::WeakFixedArray* array = i::WeakFixedArray::cast(prototype_users);
412 array->Compact<i::JSObject::PrototypeRegistryCompactionCallback>();
413 }
414 } else if (o->IsScript()) {
415 i::Object* shared_list = i::Script::cast(o)->shared_function_infos();
416 if (shared_list->IsWeakFixedArray()) {
417 i::WeakFixedArray* array = i::WeakFixedArray::cast(shared_list);
418 array->Compact<i::WeakFixedArray::NullCallback>();
419 }
420 }
421 }
422
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400423 i::Object* raw_context = *v8::Utils::OpenPersistent(context);
424 context.Reset();
Steve Blocka7e24c12009-10-30 11:49:00 +0000425
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400426 i::SnapshotByteSink snapshot_sink;
427 i::StartupSerializer ser(internal_isolate, &snapshot_sink);
428 ser.SerializeStrongReferences();
Steve Blocka7e24c12009-10-30 11:49:00 +0000429
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400430 i::SnapshotByteSink context_sink;
431 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
432 context_ser.Serialize(&raw_context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000433 ser.SerializeWeakReferencesAndDeferred();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400434
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 result = i::Snapshot::CreateSnapshotBlob(ser, context_ser, metadata);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400436 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 if (i::FLAG_profile_deserialization) {
438 i::PrintF("Creating snapshot took %0.3f ms\n",
439 timer.Elapsed().InMillisecondsF());
440 }
441 timer.Stop();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400442 }
443 isolate->Dispose();
444 return result;
Ben Murdoch257744e2011-11-30 15:57:28 +0000445}
446
447
Steve Blocka7e24c12009-10-30 11:49:00 +0000448void V8::SetFlagsFromString(const char* str, int length) {
449 i::FlagList::SetFlagsFromString(str, length);
450}
451
452
453void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
454 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
455}
456
457
Steve Blocka7e24c12009-10-30 11:49:00 +0000458RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
459
460
461RegisteredExtension::RegisteredExtension(Extension* extension)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100462 : extension_(extension) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000463
464
465void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100466 that->next_ = first_extension_;
467 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000468}
469
470
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000471void RegisteredExtension::UnregisterAll() {
472 RegisteredExtension* re = first_extension_;
473 while (re != NULL) {
474 RegisteredExtension* next = re->next();
475 delete re;
476 re = next;
477 }
478 first_extension_ = NULL;
479}
480
481
Steve Blocka7e24c12009-10-30 11:49:00 +0000482void RegisterExtension(Extension* that) {
483 RegisteredExtension* extension = new RegisteredExtension(that);
484 RegisteredExtension::Register(extension);
485}
486
487
488Extension::Extension(const char* name,
489 const char* source,
490 int dep_count,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100491 const char** deps,
492 int source_length)
Steve Blocka7e24c12009-10-30 11:49:00 +0000493 : name_(name),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100494 source_length_(source_length >= 0 ?
495 source_length :
496 (source ? static_cast<int>(strlen(source)) : 0)),
497 source_(source, source_length_),
Steve Blocka7e24c12009-10-30 11:49:00 +0000498 dep_count_(dep_count),
499 deps_(deps),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000500 auto_enable_(false) {
501 CHECK(source != NULL || source_length_ == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000502}
503
504
505ResourceConstraints::ResourceConstraints()
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000506 : max_semi_space_size_(0),
507 max_old_space_size_(0),
508 max_executable_size_(0),
509 stack_limit_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000510 code_range_size_(0) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000511
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000512void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000513 uint64_t virtual_memory_limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514#if V8_OS_ANDROID
515 // Android has higher physical memory requirements before raising the maximum
516 // heap size limits since it has no swap space.
517 const uint64_t low_limit = 512ul * i::MB;
518 const uint64_t medium_limit = 1ul * i::GB;
519 const uint64_t high_limit = 2ul * i::GB;
520#else
521 const uint64_t low_limit = 512ul * i::MB;
522 const uint64_t medium_limit = 768ul * i::MB;
523 const uint64_t high_limit = 1ul * i::GB;
524#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000525
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 if (physical_memory <= low_limit) {
527 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice);
528 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
529 set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
530 } else if (physical_memory <= medium_limit) {
531 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice);
532 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
533 set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
534 } else if (physical_memory <= high_limit) {
535 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice);
536 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
537 set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
538 } else {
539 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice);
540 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
541 set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
Steve Blocka7e24c12009-10-30 11:49:00 +0000542 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000543
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000544 if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
545 // Reserve no more than 1/8 of the memory for the code range, but at most
546 // kMaximalCodeRangeSize.
547 set_code_range_size(
548 i::Min(i::kMaximalCodeRangeSize / i::MB,
549 static_cast<size_t>((virtual_memory_limit >> 3) / i::MB)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000550 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000551}
552
553
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000554void SetResourceConstraints(i::Isolate* isolate,
555 const ResourceConstraints& constraints) {
556 int semi_space_size = constraints.max_semi_space_size();
557 int old_space_size = constraints.max_old_space_size();
558 int max_executable_size = constraints.max_executable_size();
559 size_t code_range_size = constraints.code_range_size();
560 if (semi_space_size != 0 || old_space_size != 0 ||
561 max_executable_size != 0 || code_range_size != 0) {
562 isolate->heap()->ConfigureHeap(semi_space_size, old_space_size,
563 max_executable_size, code_range_size);
564 }
565 if (constraints.stack_limit() != NULL) {
566 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
567 isolate->stack_guard()->SetStackLimit(limit);
568 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000569}
570
571
572i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100573 LOG_API(isolate, "Persistent::New");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000574 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400575#ifdef VERIFY_HEAP
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000576 if (i::FLAG_verify_heap) {
577 (*obj)->ObjectVerify();
578 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400579#endif // VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +0000580 return result.location();
581}
582
583
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000584i::Object** V8::CopyPersistent(i::Object** obj) {
585 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400586#ifdef VERIFY_HEAP
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000587 if (i::FLAG_verify_heap) {
588 (*obj)->ObjectVerify();
589 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400590#endif // VERIFY_HEAP
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000591 return result.location();
Steve Blocka7e24c12009-10-30 11:49:00 +0000592}
593
594
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400595void V8::MakeWeak(i::Object** object, void* parameter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000596 WeakCallback weak_callback) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400597 i::GlobalHandles::MakeWeak(object, parameter, weak_callback);
598}
599
600
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000601void V8::MakeWeak(i::Object** object, void* parameter,
602 int internal_field_index1, int internal_field_index2,
603 WeakCallbackInfo<void>::Callback weak_callback) {
604 WeakCallbackType type = WeakCallbackType::kParameter;
605 if (internal_field_index1 == 0) {
606 if (internal_field_index2 == 1) {
607 type = WeakCallbackType::kInternalFields;
608 } else {
609 DCHECK_EQ(internal_field_index2, -1);
610 type = WeakCallbackType::kInternalFields;
611 }
612 } else {
613 DCHECK_EQ(internal_field_index1, -1);
614 DCHECK_EQ(internal_field_index2, -1);
615 }
616 i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400617}
618
619
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000620void V8::MakeWeak(i::Object** object, void* parameter,
621 WeakCallbackInfo<void>::Callback weak_callback,
622 WeakCallbackType type) {
623 i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000624}
625
626
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000627void* V8::ClearWeak(i::Object** obj) {
628 return i::GlobalHandles::ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000629}
630
631
632void V8::DisposeGlobal(i::Object** obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000633 i::GlobalHandles::Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000634}
635
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000636
637void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
638 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
639 i::Object* object = *Utils::OpenHandle(value);
640 isolate->eternal_handles()->Create(isolate, object, index);
641}
642
643
644Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
645 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
646 return Utils::ToLocal(isolate->eternal_handles()->Get(index));
647}
648
649
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000650void V8::FromJustIsNothing() {
651 Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
652}
653
654
655void V8::ToLocalEmpty() {
656 Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
657}
658
659
660void V8::InternalFieldOutOfBounds(int index) {
661 Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
662 "WeakCallbackInfo::GetInternalField",
663 "Internal field out of bounds.");
664}
665
666
Steve Blocka7e24c12009-10-30 11:49:00 +0000667// --- H a n d l e s ---
668
669
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000670HandleScope::HandleScope(Isolate* isolate) {
671 Initialize(isolate);
672}
673
674
675void HandleScope::Initialize(Isolate* isolate) {
676 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
677 // We do not want to check the correct usage of the Locker class all over the
678 // place, so we do it only here: Without a HandleScope, an embedder can do
679 // almost nothing, so it is enough to check in this central place.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 // We make an exception if the serializer is enabled, which means that the
681 // Isolate is exclusively used to create a snapshot.
682 Utils::ApiCheck(
683 !v8::Locker::IsActive() ||
684 internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
685 internal_isolate->serializer_enabled(),
686 "HandleScope::HandleScope",
687 "Entering the V8 API without proper locking in place");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000688 i::HandleScopeData* current = internal_isolate->handle_scope_data();
689 isolate_ = internal_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +0100690 prev_next_ = current->next;
691 prev_limit_ = current->limit;
Steve Block44f0eee2011-05-26 01:26:41 +0100692 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000693}
694
695
696HandleScope::~HandleScope() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000697 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
698}
699
700
701int HandleScope::NumberOfHandles(Isolate* isolate) {
702 return i::HandleScope::NumberOfHandles(
703 reinterpret_cast<i::Isolate*>(isolate));
704}
705
706
707i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
708 return i::HandleScope::CreateHandle(isolate, value);
709}
710
711
712i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
713 i::Object* value) {
714 DCHECK(heap_object->IsHeapObject());
715 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
716}
717
718
719EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
720 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
721 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
722 Initialize(v8_isolate);
723}
724
725
726i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
727 i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
728 Utils::ApiCheck(*escape_slot_ == heap->the_hole_value(),
729 "EscapeableHandleScope::Escape",
730 "Escape value set twice");
731 if (escape_value == NULL) {
732 *escape_slot_ = heap->undefined_value();
733 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000734 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735 *escape_slot_ = *escape_value;
736 return escape_slot_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000737}
738
739
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000740SealHandleScope::SealHandleScope(Isolate* isolate) {
741 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
742
743 isolate_ = internal_isolate;
744 i::HandleScopeData* current = internal_isolate->handle_scope_data();
745 prev_limit_ = current->limit;
746 current->limit = current->next;
747 prev_sealed_level_ = current->sealed_level;
748 current->sealed_level = current->level;
749}
750
751
752SealHandleScope::~SealHandleScope() {
753 i::HandleScopeData* current = isolate_->handle_scope_data();
754 DCHECK_EQ(current->next, current->limit);
755 current->limit = prev_limit_;
756 DCHECK_EQ(current->level, current->sealed_level);
757 current->sealed_level = prev_sealed_level_;
758}
759
760
Steve Blocka7e24c12009-10-30 11:49:00 +0000761void Context::Enter() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000762 i::Handle<i::Context> env = Utils::OpenHandle(this);
763 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100764 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000765 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
766 impl->EnterContext(env);
767 impl->SaveContext(isolate->context());
Steve Block44f0eee2011-05-26 01:26:41 +0100768 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000769}
770
771
772void Context::Exit() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000773 i::Handle<i::Context> env = Utils::OpenHandle(this);
774 i::Isolate* isolate = env->GetIsolate();
775 ENTER_V8(isolate);
776 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
777 if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
778 "v8::Context::Exit()",
779 "Cannot exit non-entered context")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000780 return;
781 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000782 impl->LeaveContext();
783 isolate->set_context(impl->RestoreContext());
Steve Blocka7e24c12009-10-30 11:49:00 +0000784}
785
786
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000787static void* DecodeSmiToAligned(i::Object* value, const char* location) {
788 Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
789 return reinterpret_cast<void*>(value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000790}
791
792
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000793static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
794 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
795 Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
796 return smi;
797}
798
799
800static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
801 int index,
802 bool can_grow,
803 const char* location) {
804 i::Handle<i::Context> env = Utils::OpenHandle(context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805 i::Isolate* isolate = env->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000806 bool ok =
807 Utils::ApiCheck(env->IsNativeContext(),
808 location,
809 "Not a native context") &&
810 Utils::ApiCheck(index >= 0, location, "Negative index");
811 if (!ok) return i::Handle<i::FixedArray>();
812 i::Handle<i::FixedArray> data(env->embedder_data());
813 if (index < data->length()) return data;
814 if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
815 return i::Handle<i::FixedArray>();
Steve Block44f0eee2011-05-26 01:26:41 +0100816 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000817 int new_size = i::Max(index, data->length() << 1) + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818 int grow_by = new_size - data->length();
819 data = isolate->factory()->CopyFixedArrayAndGrow(data, grow_by);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000820 env->set_embedder_data(*data);
821 return data;
822}
823
824
825v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
826 const char* location = "v8::Context::GetEmbedderData()";
827 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
828 if (data.is_null()) return Local<Value>();
829 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000830 return Utils::ToLocal(result);
831}
832
833
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000834void Context::SetEmbedderData(int index, v8::Local<Value> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000835 const char* location = "v8::Context::SetEmbedderData()";
836 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
837 if (data.is_null()) return;
838 i::Handle<i::Object> val = Utils::OpenHandle(*value);
839 data->set(index, *val);
840 DCHECK_EQ(*Utils::OpenHandle(*value),
841 *Utils::OpenHandle(*GetEmbedderData(index)));
842}
Steve Blocka7e24c12009-10-30 11:49:00 +0000843
Steve Blocka7e24c12009-10-30 11:49:00 +0000844
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000845void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
846 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
847 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
848 if (data.is_null()) return NULL;
849 return DecodeSmiToAligned(data->get(index), location);
850}
Steve Block6ded16b2010-05-10 14:33:55 +0100851
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000852
853void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
854 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
855 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
856 data->set(index, EncodeAlignedAsSmi(value, location));
857 DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
Steve Blocka7e24c12009-10-30 11:49:00 +0000858}
859
860
861// --- N e a n d e r ---
862
863
864// A constructor cannot easily return an error value, therefore it is necessary
865// to check for a dead VM with ON_BAILOUT before constructing any Neander
866// objects. To remind you about this there is no HandleScope in the
867// NeanderObject constructor. When you add one to the site calling the
868// constructor you should check that you ensured the VM was not dead first.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000869NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100870 ENTER_V8(isolate);
871 value_ = isolate->factory()->NewNeanderObject();
872 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000873 value_->set_elements(*elements);
874}
875
876
877int NeanderObject::size() {
878 return i::FixedArray::cast(value_->elements())->length();
879}
880
881
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000882NeanderArray::NeanderArray(v8::internal::Isolate* isolate) : obj_(isolate, 2) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000883 obj_.set(0, i::Smi::FromInt(0));
884}
885
886
887int NeanderArray::length() {
888 return i::Smi::cast(obj_.get(0))->value();
889}
890
891
892i::Object* NeanderArray::get(int offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000893 DCHECK_LE(0, offset);
894 DCHECK_LT(offset, length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000895 return obj_.get(offset + 1);
896}
897
898
899// This method cannot easily return an error value, therefore it is necessary
900// to check for a dead VM with ON_BAILOUT before calling it. To remind you
901// about this there is no HandleScope in this method. When you add one to the
902// site calling this method you should check that you ensured the VM was not
903// dead first.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400904void NeanderArray::add(i::Isolate* isolate, i::Handle<i::Object> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000905 int length = this->length();
906 int size = obj_.size();
907 if (length == size - 1) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400908 i::Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000909 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000910 for (int i = 0; i < length; i++)
911 new_elms->set(i + 1, get(i));
912 obj_.value()->set_elements(*new_elms);
913 }
914 obj_.set(length + 1, *value);
915 obj_.set(0, i::Smi::FromInt(length + 1));
916}
917
918
919void NeanderArray::set(int index, i::Object* value) {
920 if (index < 0 || index >= this->length()) return;
921 obj_.set(index + 1, value);
922}
923
924
925// --- T e m p l a t e ---
926
927
928static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000929 that->set_number_of_properties(0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000930 that->set_tag(i::Smi::FromInt(type));
931}
932
933
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000934void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000935 v8::PropertyAttribute attribute) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000936 auto templ = Utils::OpenHandle(this);
937 i::Isolate* isolate = templ->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000938 ENTER_V8(isolate);
939 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000940 // TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo.
941 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
942 Utils::OpenHandle(*value),
943 static_cast<i::PropertyAttributes>(attribute));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000944}
945
946
947void Template::SetAccessorProperty(
948 v8::Local<v8::Name> name,
949 v8::Local<FunctionTemplate> getter,
950 v8::Local<FunctionTemplate> setter,
951 v8::PropertyAttribute attribute,
952 v8::AccessControl access_control) {
953 // TODO(verwaest): Remove |access_control|.
954 DCHECK_EQ(v8::DEFAULT, access_control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000955 auto templ = Utils::OpenHandle(this);
956 auto isolate = templ->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000957 ENTER_V8(isolate);
958 DCHECK(!name.IsEmpty());
959 DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
960 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000961 i::ApiNatives::AddAccessorProperty(
962 isolate, templ, Utils::OpenHandle(*name),
963 Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
964 static_cast<i::PropertyAttributes>(attribute));
Steve Blocka7e24c12009-10-30 11:49:00 +0000965}
966
967
968// --- F u n c t i o n T e m p l a t e ---
969static void InitializeFunctionTemplate(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000970 i::Handle<i::FunctionTemplateInfo> info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000971 InitializeTemplate(info, Consts::FUNCTION_TEMPLATE);
Steve Blocka7e24c12009-10-30 11:49:00 +0000972 info->set_flag(0);
973}
974
Ben Murdoch097c5b22016-05-18 11:27:45 +0100975static Local<ObjectTemplate> ObjectTemplateNew(
976 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
977 bool do_not_cache);
Steve Blocka7e24c12009-10-30 11:49:00 +0000978
979Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000980 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
981 ENTER_V8(i_isolate);
982 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
983 i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000984 if (result->IsUndefined()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100985 // Do not cache prototype objects.
986 result = Utils::OpenHandle(
987 *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
Steve Blocka7e24c12009-10-30 11:49:00 +0000988 Utils::OpenHandle(this)->set_prototype_template(*result);
989 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000990 return ToApiHandle<ObjectTemplate>(result);
Steve Blocka7e24c12009-10-30 11:49:00 +0000991}
992
993
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000994static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,
995 const char* func) {
996 Utils::ApiCheck(!info->instantiated(), func,
997 "FunctionTemplate already instantiated");
998}
999
1000
1001void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1002 auto info = Utils::OpenHandle(this);
1003 EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit");
1004 i::Isolate* isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001005 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001006 info->set_parent_template(*Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001007}
1008
1009
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001010static Local<FunctionTemplate> FunctionTemplateNew(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001011 i::Isolate* isolate, FunctionCallback callback,
1012 experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
1013 v8::Local<Signature> signature, int length, bool do_not_cache) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001014 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001015 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001016 i::Handle<i::FunctionTemplateInfo> obj =
1017 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1018 InitializeFunctionTemplate(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001019 obj->set_do_not_cache(do_not_cache);
1020 int next_serial_number = 0;
1021 if (!do_not_cache) {
1022 next_serial_number = isolate->next_serial_number() + 1;
1023 isolate->set_next_serial_number(next_serial_number);
1024 }
Steve Block44f0eee2011-05-26 01:26:41 +01001025 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00001026 if (callback != 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001027 if (data.IsEmpty()) {
1028 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1029 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001030 Utils::ToLocal(obj)->SetCallHandler(callback, data, fast_handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00001031 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001032 obj->set_length(length);
Steve Blocka7e24c12009-10-30 11:49:00 +00001033 obj->set_undetectable(false);
1034 obj->set_needs_access_check(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001035 obj->set_accept_any_receiver(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001036 if (!signature.IsEmpty())
1037 obj->set_signature(*Utils::OpenHandle(*signature));
1038 return Utils::ToLocal(obj);
1039}
1040
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001041
1042Local<FunctionTemplate> FunctionTemplate::New(Isolate* isolate,
1043 FunctionCallback callback,
1044 v8::Local<Value> data,
1045 v8::Local<Signature> signature,
1046 int length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001047 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001048 // Changes to the environment cannot be captured in the snapshot. Expect no
1049 // function templates when the isolate is created for serialization.
1050 DCHECK(!i_isolate->serializer_enabled());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001051 LOG_API(i_isolate, "FunctionTemplate::New");
1052 ENTER_V8(i_isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001053 return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature,
1054 length, false);
1055}
1056
1057
1058Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
1059 Isolate* isolate, FunctionCallback callback,
1060 experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
1061 v8::Local<Signature> signature, int length) {
1062 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1063 DCHECK(!i_isolate->serializer_enabled());
1064 LOG_API(i_isolate, "FunctionTemplate::NewWithFastHandler");
1065 ENTER_V8(i_isolate);
1066 return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature,
1067 length, false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001068}
Steve Blocka7e24c12009-10-30 11:49:00 +00001069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001070
1071Local<Signature> Signature::New(Isolate* isolate,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001072 Local<FunctionTemplate> receiver) {
1073 return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
Steve Blocka7e24c12009-10-30 11:49:00 +00001074}
1075
1076
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001077Local<AccessorSignature> AccessorSignature::New(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001078 Isolate* isolate, Local<FunctionTemplate> receiver) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1080}
1081
1082
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001083#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
1084 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
1085 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001086 } while (false)
1087
1088
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001089void FunctionTemplate::SetCallHandler(
1090 FunctionCallback callback, v8::Local<Value> data,
1091 experimental::FastAccessorBuilder* fast_handler) {
1092 auto info = Utils::OpenHandle(this);
1093 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler");
1094 i::Isolate* isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001095 ENTER_V8(isolate);
1096 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001097 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001098 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001099 i::Handle<i::CallHandlerInfo> obj =
1100 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001101 SET_FIELD_WRAPPED(obj, set_callback, callback);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001102 i::MaybeHandle<i::Code> code =
1103 i::experimental::BuildCodeFromFastAccessorBuilder(fast_handler);
1104 if (!code.is_null()) {
1105 obj->set_fast_handler(*code.ToHandleChecked());
1106 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107 if (data.IsEmpty()) {
1108 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1109 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001110 obj->set_data(*Utils::OpenHandle(*data));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001111 info->set_call_code(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001112}
1113
1114
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001115static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001116 i::Handle<i::AccessorInfo> obj, v8::Local<Name> name,
1117 v8::AccessControl settings, v8::PropertyAttribute attributes,
1118 v8::Local<AccessorSignature> signature) {
Leon Clarkef7060e22010-06-03 12:02:55 +01001119 obj->set_name(*Utils::OpenHandle(*name));
1120 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1121 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001122 obj->set_property_attributes(static_cast<i::PropertyAttributes>(attributes));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001123 if (!signature.IsEmpty()) {
1124 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1125 }
Leon Clarkef7060e22010-06-03 12:02:55 +01001126 return obj;
1127}
1128
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001129template <typename Getter, typename Setter>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001130static i::Handle<i::AccessorInfo> MakeAccessorInfo(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001131 v8::Local<Name> name, Getter getter, Setter setter, v8::Local<Value> data,
1132 v8::AccessControl settings, v8::PropertyAttribute attributes,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001133 v8::Local<AccessorSignature> signature, bool is_special_data_property) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001134 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001135 i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001136 SET_FIELD_WRAPPED(obj, set_getter, getter);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001137 if (is_special_data_property && setter == nullptr) {
1138 setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1139 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001140 SET_FIELD_WRAPPED(obj, set_setter, setter);
1141 if (data.IsEmpty()) {
1142 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00001143 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001144 obj->set_data(*Utils::OpenHandle(*data));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001145 obj->set_is_special_data_property(is_special_data_property);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001146 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1147}
Steve Blocka7e24c12009-10-30 11:49:00 +00001148
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001149
Steve Blocka7e24c12009-10-30 11:49:00 +00001150Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001151 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1152 if (!Utils::ApiCheck(!handle.is_null(),
1153 "v8::FunctionTemplate::InstanceTemplate()",
1154 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001155 return Local<ObjectTemplate>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001156 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001157 i::Isolate* isolate = handle->GetIsolate();
1158 ENTER_V8(isolate);
1159 if (handle->instance_template()->IsUndefined()) {
1160 Local<ObjectTemplate> templ =
1161 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1162 handle->set_instance_template(*Utils::OpenHandle(*templ));
1163 }
1164 i::Handle<i::ObjectTemplateInfo> result(
1165 i::ObjectTemplateInfo::cast(handle->instance_template()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001166 return Utils::ToLocal(result);
1167}
1168
1169
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170void FunctionTemplate::SetLength(int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001171 auto info = Utils::OpenHandle(this);
1172 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetLength");
1173 auto isolate = info->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001174 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001175 info->set_length(length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001176}
1177
1178
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001179void FunctionTemplate::SetClassName(Local<String> name) {
1180 auto info = Utils::OpenHandle(this);
1181 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetClassName");
1182 auto isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001183 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001184 info->set_class_name(*Utils::OpenHandle(*name));
1185}
1186
1187
1188void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1189 auto info = Utils::OpenHandle(this);
1190 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1191 auto isolate = info->GetIsolate();
1192 ENTER_V8(isolate);
1193 info->set_accept_any_receiver(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001194}
1195
1196
1197void FunctionTemplate::SetHiddenPrototype(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001198 auto info = Utils::OpenHandle(this);
1199 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetHiddenPrototype");
1200 auto isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001201 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001202 info->set_hidden_prototype(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001203}
1204
1205
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001206void FunctionTemplate::ReadOnlyPrototype() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001207 auto info = Utils::OpenHandle(this);
1208 EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1209 auto isolate = info->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001210 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001211 info->set_read_only_prototype(true);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001212}
1213
1214
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001215void FunctionTemplate::RemovePrototype() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001216 auto info = Utils::OpenHandle(this);
1217 EnsureNotInstantiated(info, "v8::FunctionTemplate::RemovePrototype");
1218 auto isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001219 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001220 info->set_remove_prototype(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001221}
1222
1223
1224// --- O b j e c t T e m p l a t e ---
1225
1226
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001227Local<ObjectTemplate> ObjectTemplate::New(
1228 Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1229 return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001230}
1231
1232
Steve Blocka7e24c12009-10-30 11:49:00 +00001233Local<ObjectTemplate> ObjectTemplate::New() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001234 return New(i::Isolate::Current(), Local<FunctionTemplate>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001235}
1236
Ben Murdoch097c5b22016-05-18 11:27:45 +01001237static Local<ObjectTemplate> ObjectTemplateNew(
1238 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1239 bool do_not_cache) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001240 // Changes to the environment cannot be captured in the snapshot. Expect no
1241 // object templates when the isolate is created for serialization.
1242 DCHECK(!isolate->serializer_enabled());
Steve Block44f0eee2011-05-26 01:26:41 +01001243 LOG_API(isolate, "ObjectTemplate::New");
1244 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001245 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001246 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001247 i::Handle<i::ObjectTemplateInfo> obj =
1248 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1249 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001250 int next_serial_number = 0;
1251 if (!do_not_cache) {
1252 next_serial_number = isolate->next_serial_number() + 1;
1253 isolate->set_next_serial_number(next_serial_number);
1254 }
1255 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00001256 if (!constructor.IsEmpty())
1257 obj->set_constructor(*Utils::OpenHandle(*constructor));
1258 obj->set_internal_field_count(i::Smi::FromInt(0));
1259 return Utils::ToLocal(obj);
1260}
1261
Ben Murdoch097c5b22016-05-18 11:27:45 +01001262Local<ObjectTemplate> ObjectTemplate::New(
1263 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1264 return ObjectTemplateNew(isolate, constructor, false);
1265}
Steve Blocka7e24c12009-10-30 11:49:00 +00001266
1267// Ensure that the object template has a constructor. If no
1268// constructor is available we create one.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001269static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1270 i::Isolate* isolate,
1271 ObjectTemplate* object_template) {
1272 i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1273 if (!obj ->IsUndefined()) {
1274 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1275 return i::Handle<i::FunctionTemplateInfo>(info, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001276 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001277 Local<FunctionTemplate> templ =
1278 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1279 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1280 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1281 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1282 return constructor;
1283}
1284
1285
Ben Murdoch097c5b22016-05-18 11:27:45 +01001286template <typename Getter, typename Setter, typename Data, typename Template>
1287static bool TemplateSetAccessor(Template* template_obj, v8::Local<Name> name,
1288 Getter getter, Setter setter, Data data,
1289 AccessControl settings,
1290 PropertyAttribute attribute,
1291 v8::Local<AccessorSignature> signature,
1292 bool is_special_data_property) {
1293 auto info = Utils::OpenHandle(template_obj);
1294 auto isolate = info->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001295 ENTER_V8(isolate);
1296 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001297 auto obj = MakeAccessorInfo(name, getter, setter, data, settings, attribute,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001298 signature, is_special_data_property);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001299 if (obj.is_null()) return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001300 i::ApiNatives::AddNativeDataProperty(isolate, info, obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001301 return true;
1302}
1303
1304
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001305void Template::SetNativeDataProperty(v8::Local<String> name,
1306 AccessorGetterCallback getter,
1307 AccessorSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001308 v8::Local<Value> data,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001309 PropertyAttribute attribute,
1310 v8::Local<AccessorSignature> signature,
1311 AccessControl settings) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001312 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1313 signature, true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001314}
1315
1316
1317void Template::SetNativeDataProperty(v8::Local<Name> name,
1318 AccessorNameGetterCallback getter,
1319 AccessorNameSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001320 v8::Local<Value> data,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001321 PropertyAttribute attribute,
1322 v8::Local<AccessorSignature> signature,
1323 AccessControl settings) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001324 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1325 signature, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001326}
1327
1328
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001329void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1330 PropertyAttribute attribute) {
1331 auto templ = Utils::OpenHandle(this);
1332 i::Isolate* isolate = templ->GetIsolate();
1333 ENTER_V8(isolate);
1334 i::HandleScope scope(isolate);
1335 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1336 intrinsic,
1337 static_cast<i::PropertyAttributes>(attribute));
1338}
1339
1340
1341void ObjectTemplate::SetAccessor(v8::Local<String> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001342 AccessorGetterCallback getter,
1343 AccessorSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001344 v8::Local<Value> data, AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001345 PropertyAttribute attribute,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001346 v8::Local<AccessorSignature> signature) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001347 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1348 signature, i::FLAG_disable_old_api_accessors);
Steve Blocka7e24c12009-10-30 11:49:00 +00001349}
1350
1351
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001352void ObjectTemplate::SetAccessor(v8::Local<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001353 AccessorNameGetterCallback getter,
1354 AccessorNameSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001355 v8::Local<Value> data, AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001356 PropertyAttribute attribute,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001357 v8::Local<AccessorSignature> signature) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001358 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1359 signature, i::FLAG_disable_old_api_accessors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001360}
1361
1362
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001363template <typename Getter, typename Setter, typename Query, typename Deleter,
1364 typename Enumerator>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001365static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
1366 Getter getter, Setter setter,
1367 Query query, Deleter remover,
1368 Enumerator enumerator,
1369 Local<Value> data,
1370 PropertyHandlerFlags flags) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001371 i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001372 ENTER_V8(isolate);
1373 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001374 auto cons = EnsureConstructor(isolate, templ);
1375 EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001376 auto obj = i::Handle<i::InterceptorInfo>::cast(
1377 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001378 obj->set_flags(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001379
1380 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1381 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1382 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1383 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1384 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001385 obj->set_can_intercept_symbols(
1386 !(static_cast<int>(flags) &
1387 static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001388 obj->set_all_can_read(static_cast<int>(flags) &
1389 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001390 obj->set_non_masking(static_cast<int>(flags) &
1391 static_cast<int>(PropertyHandlerFlags::kNonMasking));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001392
1393 if (data.IsEmpty()) {
1394 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1395 }
1396 obj->set_data(*Utils::OpenHandle(*data));
1397 cons->set_named_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001398}
1399
1400
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001401void ObjectTemplate::SetNamedPropertyHandler(
1402 NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
1403 NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001404 NamedPropertyEnumeratorCallback enumerator, Local<Value> data) {
1405 ObjectTemplateSetNamedPropertyHandler(
1406 this, getter, setter, query, remover, enumerator, data,
1407 PropertyHandlerFlags::kOnlyInterceptStrings);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001408}
1409
1410
1411void ObjectTemplate::SetHandler(
1412 const NamedPropertyHandlerConfiguration& config) {
1413 ObjectTemplateSetNamedPropertyHandler(
1414 this, config.getter, config.setter, config.query, config.deleter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001415 config.enumerator, config.data, config.flags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001416}
1417
1418
Steve Blocka7e24c12009-10-30 11:49:00 +00001419void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001420 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001421 ENTER_V8(isolate);
1422 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001423 auto cons = EnsureConstructor(isolate, this);
1424 EnsureNotInstantiated(cons, "v8::ObjectTemplate::MarkAsUndetectable");
Steve Blocka7e24c12009-10-30 11:49:00 +00001425 cons->set_undetectable(true);
1426}
1427
1428
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001429void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1430 Local<Value> data) {
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 Murdoch4a90d5f2016-03-22 12:00:34 +00001434 auto cons = EnsureConstructor(isolate, this);
1435 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
Steve Blocka7e24c12009-10-30 11:49:00 +00001436
1437 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001438 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001439 i::Handle<i::AccessCheckInfo> info =
1440 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001441
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001442 SET_FIELD_WRAPPED(info, set_callback, callback);
1443 SET_FIELD_WRAPPED(info, set_named_callback, nullptr);
1444 SET_FIELD_WRAPPED(info, set_indexed_callback, nullptr);
1445
1446 if (data.IsEmpty()) {
1447 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1448 }
1449 info->set_data(*Utils::OpenHandle(*data));
1450
1451 cons->set_access_check_info(*info);
1452 cons->set_needs_access_check(true);
1453}
1454
Ben Murdoch097c5b22016-05-18 11:27:45 +01001455void ObjectTemplate::SetAccessCheckCallback(
1456 DeprecatedAccessCheckCallback callback, Local<Value> data) {
1457 SetAccessCheckCallback(reinterpret_cast<AccessCheckCallback>(callback), data);
1458}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001459
1460void ObjectTemplate::SetAccessCheckCallbacks(
1461 NamedSecurityCallback named_callback,
1462 IndexedSecurityCallback indexed_callback, Local<Value> data) {
1463 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1464 ENTER_V8(isolate);
1465 i::HandleScope scope(isolate);
1466 auto cons = EnsureConstructor(isolate, this);
1467 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallbacks");
1468
1469 i::Handle<i::Struct> struct_info =
1470 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
1471 i::Handle<i::AccessCheckInfo> info =
1472 i::Handle<i::AccessCheckInfo>::cast(struct_info);
1473
1474 SET_FIELD_WRAPPED(info, set_callback, nullptr);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001475 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1476 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1477
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001478 if (data.IsEmpty()) {
1479 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1480 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001481 info->set_data(*Utils::OpenHandle(*data));
1482
Steve Blocka7e24c12009-10-30 11:49:00 +00001483 cons->set_access_check_info(*info);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001484 cons->set_needs_access_check(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001485}
1486
1487
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001488void ObjectTemplate::SetHandler(
1489 const IndexedPropertyHandlerConfiguration& config) {
Steve Block44f0eee2011-05-26 01:26:41 +01001490 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001491 ENTER_V8(isolate);
1492 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001493 auto cons = EnsureConstructor(isolate, this);
1494 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001495 auto obj = i::Handle<i::InterceptorInfo>::cast(
1496 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001497 obj->set_flags(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001498
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001499 if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
1500 if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
1501 if (config.query != 0) SET_FIELD_WRAPPED(obj, set_query, config.query);
1502 if (config.deleter != 0) SET_FIELD_WRAPPED(obj, set_deleter, config.deleter);
1503 if (config.enumerator != 0) {
1504 SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
1505 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001506 obj->set_all_can_read(static_cast<int>(config.flags) &
1507 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001508
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001509 v8::Local<v8::Value> data = config.data;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001510 if (data.IsEmpty()) {
1511 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1512 }
1513 obj->set_data(*Utils::OpenHandle(*data));
1514 cons->set_indexed_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001515}
1516
1517
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001518void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001519 Local<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001520 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001521 ENTER_V8(isolate);
1522 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001523 auto cons = EnsureConstructor(isolate, this);
1524 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001525 i::Handle<i::Struct> struct_obj =
1526 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1527 i::Handle<i::CallHandlerInfo> obj =
1528 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1529 SET_FIELD_WRAPPED(obj, set_callback, callback);
1530 if (data.IsEmpty()) {
1531 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1532 }
1533 obj->set_data(*Utils::OpenHandle(*data));
1534 cons->set_instance_call_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001535}
1536
1537
1538int ObjectTemplate::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00001539 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1540}
1541
1542
1543void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001544 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001545 if (!Utils::ApiCheck(i::Smi::IsValid(value),
1546 "v8::ObjectTemplate::SetInternalFieldCount()",
1547 "Invalid internal field count")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001548 return;
1549 }
Steve Block44f0eee2011-05-26 01:26:41 +01001550 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001551 if (value > 0) {
1552 // The internal field count is set by the constructor function's
1553 // construct code, so we ensure that there is a constructor
1554 // function to do the setting.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001555 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001556 }
1557 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1558}
1559
1560
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001561// --- S c r i p t s ---
Steve Blocka7e24c12009-10-30 11:49:00 +00001562
1563
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001564// Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1565// JSFunction.
1566
1567ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1568 BufferPolicy buffer_policy_)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001569 : data(data_),
1570 length(length_),
1571 rejected(false),
1572 buffer_policy(buffer_policy_) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001573
1574
1575ScriptCompiler::CachedData::~CachedData() {
1576 if (buffer_policy == BufferOwned) {
1577 delete[] data;
1578 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001579}
1580
1581
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001582bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; }
1583
1584
1585void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); }
1586
1587
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001588ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
1589 Encoding encoding)
1590 : impl_(new i::StreamedSource(stream, encoding)) {}
1591
1592
1593ScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; }
1594
1595
1596const ScriptCompiler::CachedData*
1597ScriptCompiler::StreamedSource::GetCachedData() const {
1598 return impl_->cached_data.get();
1599}
1600
1601
1602Local<Script> UnboundScript::BindToCurrentContext() {
1603 i::Handle<i::HeapObject> obj =
1604 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1605 i::Handle<i::SharedFunctionInfo>
1606 function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001607 i::Isolate* isolate = obj->GetIsolate();
1608
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001609 i::Handle<i::JSReceiver> global(isolate->native_context()->global_object());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001610 i::Handle<i::JSFunction> function =
1611 obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001612 function_info, isolate->native_context());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001613 return ToApiHandle<Script>(function);
1614}
1615
1616
1617int UnboundScript::GetId() {
1618 i::Handle<i::HeapObject> obj =
1619 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1620 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001621 LOG_API(isolate, "v8::UnboundScript::GetId");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001622 i::HandleScope scope(isolate);
1623 i::Handle<i::SharedFunctionInfo> function_info(
1624 i::SharedFunctionInfo::cast(*obj));
1625 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1626 return script->id();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001627}
1628
1629
1630int UnboundScript::GetLineNumber(int code_pos) {
1631 i::Handle<i::SharedFunctionInfo> obj =
1632 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1633 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001634 LOG_API(isolate, "UnboundScript::GetLineNumber");
1635 if (obj->script()->IsScript()) {
1636 i::Handle<i::Script> script(i::Script::cast(obj->script()));
1637 return i::Script::GetLineNumber(script, code_pos);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001638 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001639 return -1;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001640 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001641}
1642
1643
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001644Local<Value> UnboundScript::GetScriptName() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001645 i::Handle<i::SharedFunctionInfo> obj =
1646 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1647 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001648 LOG_API(isolate, "UnboundScript::GetName");
1649 if (obj->script()->IsScript()) {
1650 i::Object* name = i::Script::cast(obj->script())->name();
1651 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1652 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001653 return Local<String>();
Leon Clarkef7060e22010-06-03 12:02:55 +01001654 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001655}
Leon Clarkef7060e22010-06-03 12:02:55 +01001656
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001657
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001658Local<Value> UnboundScript::GetSourceURL() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001659 i::Handle<i::SharedFunctionInfo> obj =
1660 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1661 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001662 LOG_API(isolate, "UnboundScript::GetSourceURL");
1663 if (obj->script()->IsScript()) {
1664 i::Object* url = i::Script::cast(obj->script())->source_url();
1665 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1666 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001667 return Local<String>();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001668 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001669}
1670
1671
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001672Local<Value> UnboundScript::GetSourceMappingURL() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001673 i::Handle<i::SharedFunctionInfo> obj =
1674 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1675 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001676 LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
1677 if (obj->script()->IsScript()) {
1678 i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
1679 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1680 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001681 return Local<String>();
Ben Murdoch692be652012-01-10 18:47:50 +00001682 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001683}
1684
1685
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001686MaybeLocal<Value> Script::Run(Local<Context> context) {
1687 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Script::Run()", Value)
1688 i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
1689 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001690 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001691 auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
1692 i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
1693 Local<Value> result;
1694 has_pending_exception =
1695 !ToLocal<Value>(i::Execution::Call(isolate, fun, receiver, 0, NULL),
1696 &result);
1697 RETURN_ON_FAILED_EXECUTION(Value);
1698 RETURN_ESCAPED(result);
1699}
1700
1701
Steve Blocka7e24c12009-10-30 11:49:00 +00001702Local<Value> Script::Run() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001703 auto self = Utils::OpenHandle(this, true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001704 // If execution is terminating, Compile(..)->Run() requires this
1705 // check.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001706 if (self.is_null()) return Local<Value>();
1707 auto context = ContextFromHeapObject(self);
1708 RETURN_TO_LOCAL_UNCHECKED(Run(context), Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001709}
1710
1711
1712Local<UnboundScript> Script::GetUnboundScript() {
1713 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1714 return ToApiHandle<UnboundScript>(
1715 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
1716}
1717
1718
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001719MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
1720 Isolate* v8_isolate, Source* source, CompileOptions options,
1721 bool is_module) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001722 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001723 PREPARE_FOR_EXECUTION_WITH_ISOLATE(
1724 isolate, "v8::ScriptCompiler::CompileUnbound()", UnboundScript);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001725
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001726 // Don't try to produce any kind of cache when the debugger is loaded.
1727 if (isolate->debug()->is_loaded() &&
1728 (options == kProduceParserCache || options == kProduceCodeCache)) {
1729 options = kNoCompileOptions;
1730 }
1731
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001732 i::ScriptData* script_data = NULL;
1733 if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1734 DCHECK(source->cached_data);
1735 // ScriptData takes care of pointer-aligning the data.
1736 script_data = new i::ScriptData(source->cached_data->data,
1737 source->cached_data->length);
1738 }
1739
1740 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001741 i::Handle<i::SharedFunctionInfo> result;
1742 {
1743 i::HistogramTimerScope total(isolate->counters()->compile_script(), true);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001744 TRACE_EVENT0("v8", "V8.CompileScript");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001745 i::Handle<i::Object> name_obj;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001746 i::Handle<i::Object> source_map_url;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001747 int line_offset = 0;
1748 int column_offset = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001749 if (!source->resource_name.IsEmpty()) {
1750 name_obj = Utils::OpenHandle(*(source->resource_name));
1751 }
1752 if (!source->resource_line_offset.IsEmpty()) {
1753 line_offset = static_cast<int>(source->resource_line_offset->Value());
1754 }
1755 if (!source->resource_column_offset.IsEmpty()) {
1756 column_offset =
1757 static_cast<int>(source->resource_column_offset->Value());
1758 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001759 if (!source->source_map_url.IsEmpty()) {
1760 source_map_url = Utils::OpenHandle(*(source->source_map_url));
Steve Blocka7e24c12009-10-30 11:49:00 +00001761 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001762 result = i::Compiler::CompileScript(
1763 str, name_obj, line_offset, column_offset, source->resource_options,
1764 source_map_url, isolate->native_context(), NULL, &script_data, options,
1765 i::NOT_NATIVES_CODE, is_module);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001766 has_pending_exception = result.is_null();
1767 if (has_pending_exception && script_data != NULL) {
1768 // This case won't happen during normal operation; we have compiled
1769 // successfully and produced cached data, and but the second compilation
1770 // of the same source code fails.
1771 delete script_data;
1772 script_data = NULL;
1773 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001774 RETURN_ON_FAILED_EXECUTION(UnboundScript);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001775
1776 if ((options == kProduceParserCache || options == kProduceCodeCache) &&
1777 script_data != NULL) {
1778 // script_data now contains the data that was generated. source will
1779 // take the ownership.
1780 source->cached_data = new CachedData(
1781 script_data->data(), script_data->length(), CachedData::BufferOwned);
1782 script_data->ReleaseDataOwnership();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001783 } else if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1784 source->cached_data->rejected = script_data->rejected();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001785 }
1786 delete script_data;
Steve Blocka7e24c12009-10-30 11:49:00 +00001787 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001788 RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
1789}
1790
1791
1792MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
1793 Isolate* v8_isolate, Source* source, CompileOptions options) {
1794 return CompileUnboundInternal(v8_isolate, source, options, false);
1795}
1796
1797
1798Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate,
1799 Source* source,
1800 CompileOptions options) {
1801 RETURN_TO_LOCAL_UNCHECKED(
1802 CompileUnboundInternal(v8_isolate, source, options, false),
1803 UnboundScript);
1804}
1805
1806
1807MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
1808 Source* source,
1809 CompileOptions options) {
1810 auto isolate = context->GetIsolate();
1811 auto maybe = CompileUnboundInternal(isolate, source, options, false);
1812 Local<UnboundScript> result;
1813 if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
1814 v8::Context::Scope scope(context);
1815 return result->BindToCurrentContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00001816}
1817
1818
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001819Local<Script> ScriptCompiler::Compile(
1820 Isolate* v8_isolate,
1821 Source* source,
1822 CompileOptions options) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001823 auto context = v8_isolate->GetCurrentContext();
1824 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, options), Script);
1825}
1826
1827
1828MaybeLocal<Script> ScriptCompiler::CompileModule(Local<Context> context,
1829 Source* source,
1830 CompileOptions options) {
1831 CHECK(i::FLAG_harmony_modules);
1832 auto isolate = context->GetIsolate();
1833 auto maybe = CompileUnboundInternal(isolate, source, options, true);
1834 Local<UnboundScript> generic;
1835 if (!maybe.ToLocal(&generic)) return MaybeLocal<Script>();
1836 v8::Context::Scope scope(context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001837 return generic->BindToCurrentContext();
Steve Block6ded16b2010-05-10 14:33:55 +01001838}
1839
1840
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001841class IsIdentifierHelper {
1842 public:
1843 IsIdentifierHelper() : is_identifier_(false), first_char_(true) {}
1844
1845 bool Check(i::String* string) {
1846 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
1847 if (cons_string == NULL) return is_identifier_;
1848 // We don't support cons strings here.
1849 return false;
1850 }
1851 void VisitOneByteString(const uint8_t* chars, int length) {
1852 for (int i = 0; i < length; ++i) {
1853 if (first_char_) {
1854 first_char_ = false;
1855 is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
1856 } else {
1857 is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
1858 }
1859 }
1860 }
1861 void VisitTwoByteString(const uint16_t* chars, int length) {
1862 for (int i = 0; i < length; ++i) {
1863 if (first_char_) {
1864 first_char_ = false;
1865 is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
1866 } else {
1867 is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
1868 }
1869 }
1870 }
1871
1872 private:
1873 bool is_identifier_;
1874 bool first_char_;
1875 i::UnicodeCache unicode_cache_;
1876 DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper);
1877};
1878
1879
1880MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
1881 Local<Context> v8_context, Source* source, size_t arguments_count,
1882 Local<String> arguments[], size_t context_extension_count,
1883 Local<Object> context_extensions[]) {
1884 PREPARE_FOR_EXECUTION(
1885 v8_context, "v8::ScriptCompiler::CompileFunctionInContext()", Function);
1886 i::Handle<i::String> source_string;
1887 auto factory = isolate->factory();
1888 if (arguments_count) {
1889 source_string = factory->NewStringFromStaticChars("(function(");
1890 for (size_t i = 0; i < arguments_count; ++i) {
1891 IsIdentifierHelper helper;
1892 if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) {
1893 return Local<Function>();
1894 }
1895 has_pending_exception =
1896 !factory->NewConsString(source_string,
1897 Utils::OpenHandle(*arguments[i]))
1898 .ToHandle(&source_string);
1899 RETURN_ON_FAILED_EXECUTION(Function);
1900 if (i + 1 == arguments_count) continue;
1901 has_pending_exception =
1902 !factory->NewConsString(source_string,
1903 factory->LookupSingleCharacterStringFromCode(
1904 ',')).ToHandle(&source_string);
1905 RETURN_ON_FAILED_EXECUTION(Function);
1906 }
1907 auto brackets = factory->NewStringFromStaticChars("){");
1908 has_pending_exception = !factory->NewConsString(source_string, brackets)
1909 .ToHandle(&source_string);
1910 RETURN_ON_FAILED_EXECUTION(Function);
1911 } else {
1912 source_string = factory->NewStringFromStaticChars("(function(){");
1913 }
1914
1915 int scope_position = source_string->length();
1916 has_pending_exception =
1917 !factory->NewConsString(source_string,
1918 Utils::OpenHandle(*source->source_string))
1919 .ToHandle(&source_string);
1920 RETURN_ON_FAILED_EXECUTION(Function);
1921 // Include \n in case the source contains a line end comment.
1922 auto brackets = factory->NewStringFromStaticChars("\n})");
1923 has_pending_exception =
1924 !factory->NewConsString(source_string, brackets).ToHandle(&source_string);
1925 RETURN_ON_FAILED_EXECUTION(Function);
1926
1927 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
1928 i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(),
1929 isolate);
1930 for (size_t i = 0; i < context_extension_count; ++i) {
1931 i::Handle<i::JSReceiver> extension =
1932 Utils::OpenHandle(*context_extensions[i]);
1933 if (!extension->IsJSObject()) return Local<Function>();
1934 i::Handle<i::JSFunction> closure(context->closure(), isolate);
1935 context = factory->NewWithContext(closure, context, extension);
1936 }
1937
1938 i::Handle<i::Object> name_obj;
1939 int line_offset = 0;
1940 int column_offset = 0;
1941 if (!source->resource_name.IsEmpty()) {
1942 name_obj = Utils::OpenHandle(*(source->resource_name));
1943 }
1944 if (!source->resource_line_offset.IsEmpty()) {
1945 line_offset = static_cast<int>(source->resource_line_offset->Value());
1946 }
1947 if (!source->resource_column_offset.IsEmpty()) {
1948 column_offset = static_cast<int>(source->resource_column_offset->Value());
1949 }
1950 i::Handle<i::JSFunction> fun;
1951 has_pending_exception = !i::Compiler::GetFunctionFromEval(
1952 source_string, outer_info, context, i::SLOPPY,
1953 i::ONLY_SINGLE_FUNCTION_LITERAL, line_offset,
1954 column_offset - scope_position, name_obj,
1955 source->resource_options).ToHandle(&fun);
1956 if (has_pending_exception) {
1957 isolate->ReportPendingMessages();
1958 }
1959 RETURN_ON_FAILED_EXECUTION(Function);
1960
1961 i::Handle<i::Object> result;
1962 has_pending_exception =
1963 !i::Execution::Call(isolate, fun,
1964 Utils::OpenHandle(*v8_context->Global()), 0,
1965 nullptr).ToHandle(&result);
1966 RETURN_ON_FAILED_EXECUTION(Function);
1967 RETURN_ESCAPED(
1968 Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(result)));
1969}
1970
1971
1972Local<Function> ScriptCompiler::CompileFunctionInContext(
1973 Isolate* v8_isolate, Source* source, Local<Context> v8_context,
1974 size_t arguments_count, Local<String> arguments[],
1975 size_t context_extension_count, Local<Object> context_extensions[]) {
1976 RETURN_TO_LOCAL_UNCHECKED(
1977 CompileFunctionInContext(v8_context, source, arguments_count, arguments,
1978 context_extension_count, context_extensions),
1979 Function);
1980}
1981
1982
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001983ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
1984 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
1985 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001986 return new i::BackgroundParsingTask(source->impl(), options,
1987 i::FLAG_stack_size, isolate);
1988}
1989
1990
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001991MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
1992 StreamedSource* v8_source,
1993 Local<String> full_source_string,
1994 const ScriptOrigin& origin) {
1995 PREPARE_FOR_EXECUTION(context, "v8::ScriptCompiler::Compile()", Script);
1996 i::StreamedSource* source = v8_source->impl();
1997 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
1998 i::Handle<i::Script> script = isolate->factory()->NewScript(str);
1999 if (!origin.ResourceName().IsEmpty()) {
2000 script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
2001 }
2002 if (!origin.ResourceLineOffset().IsEmpty()) {
2003 script->set_line_offset(
2004 static_cast<int>(origin.ResourceLineOffset()->Value()));
2005 }
2006 if (!origin.ResourceColumnOffset().IsEmpty()) {
2007 script->set_column_offset(
2008 static_cast<int>(origin.ResourceColumnOffset()->Value()));
2009 }
2010 script->set_origin_options(origin.Options());
2011 if (!origin.SourceMapUrl().IsEmpty()) {
2012 script->set_source_mapping_url(
2013 *Utils::OpenHandle(*(origin.SourceMapUrl())));
2014 }
2015
2016 source->info->set_script(script);
2017 source->info->set_context(isolate->native_context());
2018
2019 // Do the parsing tasks which need to be done on the main thread. This will
2020 // also handle parse errors.
2021 source->parser->Internalize(isolate, script,
2022 source->info->literal() == nullptr);
2023 source->parser->HandleSourceURLComments(isolate, script);
2024
2025 i::Handle<i::SharedFunctionInfo> result;
2026 if (source->info->literal() != nullptr) {
2027 // Parsing has succeeded.
2028 result = i::Compiler::CompileStreamedScript(script, source->info.get(),
2029 str->length());
2030 }
2031 has_pending_exception = result.is_null();
2032 if (has_pending_exception) isolate->ReportPendingMessages();
2033 RETURN_ON_FAILED_EXECUTION(Script);
2034
2035 source->info->clear_script(); // because script goes out of scope.
2036
2037 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
2038 if (generic.IsEmpty()) return Local<Script>();
2039 Local<Script> bound = generic->BindToCurrentContext();
2040 if (bound.IsEmpty()) return Local<Script>();
2041 RETURN_ESCAPED(bound);
2042}
2043
2044
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002045Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
2046 StreamedSource* v8_source,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002047 Local<String> full_source_string,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002048 const ScriptOrigin& origin) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002049 auto context = v8_isolate->GetCurrentContext();
2050 RETURN_TO_LOCAL_UNCHECKED(
2051 Compile(context, v8_source, full_source_string, origin), Script);
Steve Blocka7e24c12009-10-30 11:49:00 +00002052}
2053
2054
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002055uint32_t ScriptCompiler::CachedDataVersionTag() {
2056 return static_cast<uint32_t>(base::hash_combine(
2057 internal::Version::Hash(), internal::FlagList::Hash(),
2058 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2059}
2060
2061
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002062MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2063 ScriptOrigin* origin) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002064 if (origin) {
2065 ScriptCompiler::Source script_source(source, *origin);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002066 return ScriptCompiler::Compile(context, &script_source);
Steve Blocka7e24c12009-10-30 11:49:00 +00002067 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002068 ScriptCompiler::Source script_source(source);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002069 return ScriptCompiler::Compile(context, &script_source);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002070}
2071
2072
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002073Local<Script> Script::Compile(v8::Local<String> source,
2074 v8::ScriptOrigin* origin) {
2075 auto str = Utils::OpenHandle(*source);
2076 auto context = ContextFromHeapObject(str);
2077 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script);
2078}
2079
2080
2081Local<Script> Script::Compile(v8::Local<String> source,
2082 v8::Local<String> file_name) {
2083 auto str = Utils::OpenHandle(*source);
2084 auto context = ContextFromHeapObject(str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002085 ScriptOrigin origin(file_name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002086 return Compile(context, source, &origin).FromMaybe(Local<Script>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002087}
2088
2089
2090// --- E x c e p t i o n s ---
2091
2092
2093v8::TryCatch::TryCatch()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002094 : isolate_(i::Isolate::Current()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002095 next_(isolate_->try_catch_handler()),
Steve Blocka7e24c12009-10-30 11:49:00 +00002096 is_verbose_(false),
2097 can_continue_(true),
2098 capture_message_(true),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002099 rethrow_(false),
2100 has_terminated_(false) {
2101 ResetInternal();
2102 // Special handling for simulators which have a separate JS stack.
2103 js_stack_comparable_address_ =
2104 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002105 isolate_, v8::internal::GetCurrentStackPosition()));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002106 isolate_->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002107}
2108
2109
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002110v8::TryCatch::TryCatch(v8::Isolate* isolate)
2111 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2112 next_(isolate_->try_catch_handler()),
2113 is_verbose_(false),
2114 can_continue_(true),
2115 capture_message_(true),
2116 rethrow_(false),
2117 has_terminated_(false) {
2118 ResetInternal();
2119 // Special handling for simulators which have a separate JS stack.
2120 js_stack_comparable_address_ =
2121 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002122 isolate_, v8::internal::GetCurrentStackPosition()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002123 isolate_->RegisterTryCatchHandler(this);
2124}
2125
2126
Steve Blocka7e24c12009-10-30 11:49:00 +00002127v8::TryCatch::~TryCatch() {
Steve Blockd0582a62009-12-15 09:54:21 +00002128 if (rethrow_) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002129 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2130 v8::HandleScope scope(isolate);
2131 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2132 if (HasCaught() && capture_message_) {
2133 // If an exception was caught and rethrow_ is indicated, the saved
2134 // message, script, and location need to be restored to Isolate TLS
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002135 // for reuse. capture_message_ needs to be disabled so that Throw()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002136 // does not create a new message.
2137 isolate_->thread_local_top()->rethrowing_message_ = true;
2138 isolate_->RestorePendingMessageFromTryCatch(this);
2139 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002140 isolate_->UnregisterTryCatchHandler(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002141 v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002142 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2143 DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
Steve Blockd0582a62009-12-15 09:54:21 +00002144 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002145 if (HasCaught() && isolate_->has_scheduled_exception()) {
2146 // If an exception was caught but is still scheduled because no API call
2147 // promoted it, then it is canceled to prevent it from being propagated.
2148 // Note that this will not cancel termination exceptions.
2149 isolate_->CancelScheduledExceptionFromTryCatch(this);
2150 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002151 isolate_->UnregisterTryCatchHandler(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002152 v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_);
Steve Blockd0582a62009-12-15 09:54:21 +00002153 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002154}
2155
2156
2157bool v8::TryCatch::HasCaught() const {
2158 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
2159}
2160
2161
2162bool v8::TryCatch::CanContinue() const {
2163 return can_continue_;
2164}
2165
2166
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002167bool v8::TryCatch::HasTerminated() const {
2168 return has_terminated_;
2169}
2170
2171
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002172v8::Local<v8::Value> v8::TryCatch::ReThrow() {
Steve Blockd0582a62009-12-15 09:54:21 +00002173 if (!HasCaught()) return v8::Local<v8::Value>();
2174 rethrow_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002175 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
Steve Blockd0582a62009-12-15 09:54:21 +00002176}
2177
2178
Steve Blocka7e24c12009-10-30 11:49:00 +00002179v8::Local<Value> v8::TryCatch::Exception() const {
2180 if (HasCaught()) {
2181 // Check for out of memory exception.
2182 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002183 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00002184 } else {
2185 return v8::Local<Value>();
2186 }
2187}
2188
2189
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002190MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2191 if (!HasCaught()) return v8::Local<Value>();
2192 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
2193 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
2194 PREPARE_FOR_EXECUTION(context, "v8::TryCatch::StackTrace", Value);
2195 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
2196 i::Handle<i::String> name = isolate->factory()->stack_string();
2197 Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
2198 has_pending_exception = !maybe.IsJust();
2199 RETURN_ON_FAILED_EXECUTION(Value);
2200 if (!maybe.FromJust()) return v8::Local<Value>();
2201 Local<Value> result;
2202 has_pending_exception =
2203 !ToLocal<Value>(i::Object::GetProperty(obj, name), &result);
2204 RETURN_ON_FAILED_EXECUTION(Value);
2205 RETURN_ESCAPED(result);
2206}
2207
2208
Steve Blocka7e24c12009-10-30 11:49:00 +00002209v8::Local<Value> v8::TryCatch::StackTrace() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002210 auto context = reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext();
2211 RETURN_TO_LOCAL_UNCHECKED(StackTrace(context), Value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002212}
2213
2214
2215v8::Local<v8::Message> v8::TryCatch::Message() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002216 i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2217 DCHECK(message->IsJSMessageObject() || message->IsTheHole());
2218 if (HasCaught() && !message->IsTheHole()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002219 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00002220 } else {
2221 return v8::Local<v8::Message>();
2222 }
2223}
2224
2225
2226void v8::TryCatch::Reset() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002227 if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2228 // If an exception was caught but is still scheduled because no API call
2229 // promoted it, then it is canceled to prevent it from being propagated.
2230 // Note that this will not cancel termination exceptions.
2231 isolate_->CancelScheduledExceptionFromTryCatch(this);
2232 }
2233 ResetInternal();
2234}
2235
2236
2237void v8::TryCatch::ResetInternal() {
2238 i::Object* the_hole = isolate_->heap()->the_hole_value();
2239 exception_ = the_hole;
2240 message_obj_ = the_hole;
Steve Blocka7e24c12009-10-30 11:49:00 +00002241}
2242
2243
2244void v8::TryCatch::SetVerbose(bool value) {
2245 is_verbose_ = value;
2246}
2247
2248
2249void v8::TryCatch::SetCaptureMessage(bool value) {
2250 capture_message_ = value;
2251}
2252
2253
2254// --- M e s s a g e ---
2255
2256
2257Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002258 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002259 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002260 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00002261 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002262 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00002263 Local<String> result = Utils::ToLocal(raw_result);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002264 return scope.Escape(result);
2265}
2266
2267
2268ScriptOrigin Message::GetScriptOrigin() const {
2269 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002270 auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2271 auto script_wraper = i::Handle<i::Object>(message->script(), isolate);
2272 auto script_value = i::Handle<i::JSValue>::cast(script_wraper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002273 i::Handle<i::Script> script(i::Script::cast(script_value->value()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002274 return GetScriptOriginForScript(isolate, script);
Steve Blocka7e24c12009-10-30 11:49:00 +00002275}
2276
2277
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002278v8::Local<Value> Message::GetScriptResourceName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002279 return GetScriptOrigin().ResourceName();
Steve Blocka7e24c12009-10-30 11:49:00 +00002280}
2281
2282
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002283v8::Local<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002284 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002285 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002286 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002287 auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002288 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002289 if (!stackFramesObj->IsJSArray()) return v8::Local<v8::StackTrace>();
2290 auto stackTrace = i::Handle<i::JSArray>::cast(stackFramesObj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002291 return scope.Escape(Utils::StackTraceToLocal(stackTrace));
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002292}
2293
2294
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002295Maybe<int> Message::GetLineNumber(Local<Context> context) const {
2296 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetLineNumber()", int);
2297 i::Handle<i::JSFunction> fun = isolate->message_get_line_number();
2298 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2299 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
2300 i::Handle<i::Object> result;
2301 has_pending_exception =
2302 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2303 .ToHandle(&result);
2304 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
2305 return Just(static_cast<int>(result->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002306}
2307
2308
2309int Message::GetLineNumber() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002310 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2311 return GetLineNumber(context).FromMaybe(0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002312}
2313
2314
2315int Message::GetStartPosition() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002316 auto self = Utils::OpenHandle(this);
2317 return self->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002318}
2319
2320
2321int Message::GetEndPosition() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002322 auto self = Utils::OpenHandle(this);
2323 return self->end_position();
2324}
2325
2326
2327Maybe<int> Message::GetStartColumn(Local<Context> context) const {
2328 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetStartColumn()",
2329 int);
2330 i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
2331 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2332 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
2333 i::Handle<i::Object> result;
2334 has_pending_exception =
2335 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2336 .ToHandle(&result);
2337 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
2338 return Just(static_cast<int>(result->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002339}
2340
2341
2342int Message::GetStartColumn() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002343 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2344 const int default_value = kNoColumnInfo;
2345 return GetStartColumn(context).FromMaybe(default_value);
2346}
2347
2348
2349Maybe<int> Message::GetEndColumn(Local<Context> context) const {
2350 auto self = Utils::OpenHandle(this);
2351 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetEndColumn()", int);
2352 i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
2353 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2354 i::Handle<i::Object> args[] = {self};
2355 i::Handle<i::Object> result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002356 has_pending_exception =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002357 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2358 .ToHandle(&result);
2359 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
2360 int start = self->start_position();
2361 int end = self->end_position();
2362 return Just(static_cast<int>(result->Number()) + (end - start));
Steve Blocka7e24c12009-10-30 11:49:00 +00002363}
2364
2365
2366int Message::GetEndColumn() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002367 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2368 const int default_value = kNoColumnInfo;
2369 return GetEndColumn(context).FromMaybe(default_value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002370}
2371
2372
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002373bool Message::IsSharedCrossOrigin() const {
2374 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2375 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002376 auto self = Utils::OpenHandle(this);
2377 auto script = i::Handle<i::JSValue>::cast(
2378 i::Handle<i::Object>(self->script(), isolate));
2379 return i::Script::cast(script->value())
2380 ->origin_options()
2381 .IsSharedCrossOrigin();
2382}
2383
2384bool Message::IsOpaque() const {
2385 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2386 ENTER_V8(isolate);
2387 auto self = Utils::OpenHandle(this);
2388 auto script = i::Handle<i::JSValue>::cast(
2389 i::Handle<i::Object>(self->script(), isolate));
2390 return i::Script::cast(script->value())->origin_options().IsOpaque();
2391}
2392
2393
2394MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
2395 PREPARE_FOR_EXECUTION(context, "v8::Message::GetSourceLine()", String);
2396 i::Handle<i::JSFunction> fun = isolate->message_get_source_line();
2397 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2398 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
2399 i::Handle<i::Object> result;
2400 has_pending_exception =
2401 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2402 .ToHandle(&result);
2403 RETURN_ON_FAILED_EXECUTION(String);
2404 Local<String> str;
2405 if (result->IsString()) {
2406 str = Utils::ToLocal(i::Handle<i::String>::cast(result));
2407 }
2408 RETURN_ESCAPED(str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002409}
2410
2411
Steve Blocka7e24c12009-10-30 11:49:00 +00002412Local<String> Message::GetSourceLine() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002413 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2414 RETURN_TO_LOCAL_UNCHECKED(GetSourceLine(context), String)
Steve Blocka7e24c12009-10-30 11:49:00 +00002415}
2416
2417
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002418void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
2419 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2420 ENTER_V8(i_isolate);
2421 i_isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00002422}
2423
2424
Kristian Monsen25f61362010-05-21 11:50:48 +01002425// --- S t a c k T r a c e ---
2426
2427Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002428 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002429 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002430 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002431 auto self = Utils::OpenHandle(this);
2432 auto obj = i::Object::GetElement(isolate, self, index).ToHandleChecked();
2433 auto jsobj = i::Handle<i::JSObject>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002434 return scope.Escape(Utils::StackFrameToLocal(jsobj));
Kristian Monsen25f61362010-05-21 11:50:48 +01002435}
2436
2437
2438int StackTrace::GetFrameCount() const {
Kristian Monsen25f61362010-05-21 11:50:48 +01002439 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2440}
2441
2442
2443Local<Array> StackTrace::AsArray() {
Kristian Monsen25f61362010-05-21 11:50:48 +01002444 return Utils::ToLocal(Utils::OpenHandle(this));
2445}
2446
2447
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002448Local<StackTrace> StackTrace::CurrentStackTrace(
2449 Isolate* isolate,
2450 int frame_limit,
Kristian Monsen25f61362010-05-21 11:50:48 +01002451 StackTraceOptions options) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002452 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2453 ENTER_V8(i_isolate);
2454 // TODO(dcarney): remove when ScriptDebugServer is fixed.
2455 options = static_cast<StackTraceOptions>(
2456 static_cast<int>(options) | kExposeFramesAcrossSecurityOrigins);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002457 i::Handle<i::JSArray> stackTrace =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002458 i_isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002459 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01002460}
2461
2462
2463// --- S t a c k F r a m e ---
2464
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002465static int getIntProperty(const StackFrame* f, const char* propertyName,
2466 int defaultValue) {
2467 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002468 ENTER_V8(isolate);
2469 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002470 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2471 i::Handle<i::Object> obj =
2472 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2473 return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue;
2474}
2475
2476
2477int StackFrame::GetLineNumber() const {
2478 return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo);
Kristian Monsen25f61362010-05-21 11:50:48 +01002479}
2480
2481
2482int StackFrame::GetColumn() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002483 return getIntProperty(this, "column", Message::kNoColumnInfo);
2484}
2485
2486
2487int StackFrame::GetScriptId() const {
2488 return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo);
2489}
2490
2491
2492static Local<String> getStringProperty(const StackFrame* f,
2493 const char* propertyName) {
2494 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002495 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002496 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2497 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2498 i::Handle<i::Object> obj =
2499 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2500 return obj->IsString()
2501 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
2502 : Local<String>();
Kristian Monsen25f61362010-05-21 11:50:48 +01002503}
2504
2505
2506Local<String> StackFrame::GetScriptName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002507 return getStringProperty(this, "scriptName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002508}
2509
2510
Ben Murdochf87a2032010-10-22 12:50:53 +01002511Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002512 return getStringProperty(this, "scriptNameOrSourceURL");
Ben Murdochf87a2032010-10-22 12:50:53 +01002513}
2514
2515
Kristian Monsen25f61362010-05-21 11:50:48 +01002516Local<String> StackFrame::GetFunctionName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002517 return getStringProperty(this, "functionName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002518}
2519
2520
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002521static bool getBoolProperty(const StackFrame* f, const char* propertyName) {
2522 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002523 ENTER_V8(isolate);
2524 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002525 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2526 i::Handle<i::Object> obj =
2527 i::Object::GetProperty(isolate, self, propertyName).ToHandleChecked();
2528 return obj->IsTrue();
Kristian Monsen25f61362010-05-21 11:50:48 +01002529}
2530
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002531bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
2532
Kristian Monsen25f61362010-05-21 11:50:48 +01002533
2534bool StackFrame::IsConstructor() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002535 return getBoolProperty(this, "isConstructor");
2536}
2537
2538
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002539// --- N a t i v e W e a k M a p ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002540
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002541Local<NativeWeakMap> NativeWeakMap::New(Isolate* v8_isolate) {
2542 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2543 ENTER_V8(isolate);
2544 i::Handle<i::JSWeakMap> weakmap = isolate->factory()->NewJSWeakMap();
2545 i::JSWeakCollection::Initialize(weakmap, isolate);
2546 return Utils::NativeWeakMapToLocal(weakmap);
2547}
2548
2549
2550void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) {
2551 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2552 i::Isolate* isolate = weak_collection->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002553 ENTER_V8(isolate);
2554 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002555 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2556 i::Handle<i::Object> value = Utils::OpenHandle(*v8_value);
2557 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2558 DCHECK(false);
2559 return;
2560 }
2561 i::Handle<i::ObjectHashTable> table(
2562 i::ObjectHashTable::cast(weak_collection->table()));
2563 if (!table->IsKey(*key)) {
2564 DCHECK(false);
2565 return;
2566 }
2567 int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
2568 i::JSWeakCollection::Set(weak_collection, key, value, hash);
2569}
2570
2571
2572Local<Value> NativeWeakMap::Get(Local<Value> v8_key) {
2573 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2574 i::Isolate* isolate = weak_collection->GetIsolate();
2575 ENTER_V8(isolate);
2576 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2577 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2578 DCHECK(false);
2579 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
2580 }
2581 i::Handle<i::ObjectHashTable> table(
2582 i::ObjectHashTable::cast(weak_collection->table()));
2583 if (!table->IsKey(*key)) {
2584 DCHECK(false);
2585 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
2586 }
2587 i::Handle<i::Object> lookup(table->Lookup(key), isolate);
2588 if (lookup->IsTheHole())
2589 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
2590 return Utils::ToLocal(lookup);
2591}
2592
2593
2594bool NativeWeakMap::Has(Local<Value> v8_key) {
2595 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2596 i::Isolate* isolate = weak_collection->GetIsolate();
2597 ENTER_V8(isolate);
2598 i::HandleScope scope(isolate);
2599 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2600 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2601 DCHECK(false);
2602 return false;
2603 }
2604 i::Handle<i::ObjectHashTable> table(
2605 i::ObjectHashTable::cast(weak_collection->table()));
2606 if (!table->IsKey(*key)) {
2607 DCHECK(false);
2608 return false;
2609 }
2610 i::Handle<i::Object> lookup(table->Lookup(key), isolate);
2611 return !lookup->IsTheHole();
2612}
2613
2614
2615bool NativeWeakMap::Delete(Local<Value> v8_key) {
2616 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2617 i::Isolate* isolate = weak_collection->GetIsolate();
2618 ENTER_V8(isolate);
2619 i::HandleScope scope(isolate);
2620 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2621 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2622 DCHECK(false);
2623 return false;
2624 }
2625 i::Handle<i::ObjectHashTable> table(
2626 i::ObjectHashTable::cast(weak_collection->table()));
2627 if (!table->IsKey(*key)) {
2628 DCHECK(false);
2629 return false;
2630 }
2631 int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
2632 return i::JSWeakCollection::Delete(weak_collection, key, hash);
2633}
2634
2635
2636// --- J S O N ---
2637
2638MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
2639 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2640 PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, "JSON::Parse", Value);
2641 i::Handle<i::String> string = Utils::OpenHandle(*json_string);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002642 i::Handle<i::String> source = i::String::Flatten(string);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002643 auto maybe = source->IsSeqOneByteString()
2644 ? i::JsonParser<true>::Parse(source)
2645 : i::JsonParser<false>::Parse(source);
2646 Local<Value> result;
2647 has_pending_exception = !ToLocal<Value>(maybe, &result);
2648 RETURN_ON_FAILED_EXECUTION(Value);
2649 RETURN_ESCAPED(result);
2650}
2651
2652
2653Local<Value> JSON::Parse(Local<String> json_string) {
2654 auto isolate = reinterpret_cast<v8::Isolate*>(
2655 Utils::OpenHandle(*json_string)->GetIsolate());
2656 RETURN_TO_LOCAL_UNCHECKED(Parse(isolate, json_string), Value);
Kristian Monsen25f61362010-05-21 11:50:48 +01002657}
2658
2659
Steve Blocka7e24c12009-10-30 11:49:00 +00002660// --- D a t a ---
2661
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002662bool Value::FullIsUndefined() const {
2663 bool result = Utils::OpenHandle(this)->IsUndefined();
2664 DCHECK_EQ(result, QuickIsUndefined());
2665 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002666}
2667
2668
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002669bool Value::FullIsNull() const {
2670 bool result = Utils::OpenHandle(this)->IsNull();
2671 DCHECK_EQ(result, QuickIsNull());
2672 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002673}
2674
2675
2676bool Value::IsTrue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002677 return Utils::OpenHandle(this)->IsTrue();
2678}
2679
2680
2681bool Value::IsFalse() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002682 return Utils::OpenHandle(this)->IsFalse();
2683}
2684
2685
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002686bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002687
2688
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002689bool Value::IsName() const {
2690 return Utils::OpenHandle(this)->IsName();
2691}
2692
2693
Steve Blocka7e24c12009-10-30 11:49:00 +00002694bool Value::FullIsString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002695 bool result = Utils::OpenHandle(this)->IsString();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002696 DCHECK_EQ(result, QuickIsString());
Steve Blocka7e24c12009-10-30 11:49:00 +00002697 return result;
2698}
2699
2700
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002701bool Value::IsSymbol() const {
2702 return Utils::OpenHandle(this)->IsSymbol();
2703}
2704
2705
Steve Blocka7e24c12009-10-30 11:49:00 +00002706bool Value::IsArray() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002707 return Utils::OpenHandle(this)->IsJSArray();
2708}
2709
2710
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002711bool Value::IsArrayBuffer() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002712 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2713 return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002714}
2715
2716
2717bool Value::IsArrayBufferView() const {
2718 return Utils::OpenHandle(this)->IsJSArrayBufferView();
2719}
2720
2721
2722bool Value::IsTypedArray() const {
2723 return Utils::OpenHandle(this)->IsJSTypedArray();
2724}
2725
2726
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002727#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
2728 bool Value::Is##Type##Array() const { \
2729 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2730 return obj->IsJSTypedArray() && \
2731 i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002732 }
2733
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002734
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002735TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
2736
2737#undef VALUE_IS_TYPED_ARRAY
2738
2739
2740bool Value::IsDataView() const {
2741 return Utils::OpenHandle(this)->IsJSDataView();
2742}
2743
2744
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002745bool Value::IsSharedArrayBuffer() const {
2746 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2747 return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared();
Steve Blocka7e24c12009-10-30 11:49:00 +00002748}
2749
2750
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002751bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
2752
2753
Steve Blocka7e24c12009-10-30 11:49:00 +00002754bool Value::IsNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002755 return Utils::OpenHandle(this)->IsNumber();
2756}
2757
2758
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002759bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
2760
2761
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002762#define VALUE_IS_SPECIFIC_TYPE(Type, Class) \
2763 bool Value::Is##Type() const { \
2764 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2765 if (!obj->IsHeapObject()) return false; \
2766 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); \
2767 return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
Steve Block44f0eee2011-05-26 01:26:41 +01002768 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002769
2770VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
2771VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
2772VALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
2773VALUE_IS_SPECIFIC_TYPE(StringObject, String)
2774VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
2775VALUE_IS_SPECIFIC_TYPE(Date, Date)
2776VALUE_IS_SPECIFIC_TYPE(Map, Map)
2777VALUE_IS_SPECIFIC_TYPE(Set, Set)
2778VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
2779VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
2780
2781#undef VALUE_IS_SPECIFIC_TYPE
2782
2783
2784bool Value::IsBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002785 return Utils::OpenHandle(this)->IsBoolean();
2786}
2787
2788
2789bool Value::IsExternal() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002790 return Utils::OpenHandle(this)->IsExternal();
Steve Blocka7e24c12009-10-30 11:49:00 +00002791}
2792
2793
2794bool Value::IsInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002795 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2796 if (obj->IsSmi()) return true;
2797 if (obj->IsNumber()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002798 return i::IsInt32Double(obj->Number());
Steve Blocka7e24c12009-10-30 11:49:00 +00002799 }
2800 return false;
2801}
2802
2803
Steve Block6ded16b2010-05-10 14:33:55 +01002804bool Value::IsUint32() const {
Steve Block6ded16b2010-05-10 14:33:55 +01002805 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2806 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2807 if (obj->IsNumber()) {
2808 double value = obj->Number();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002809 return !i::IsMinusZero(value) &&
2810 value >= 0 &&
2811 value <= i::kMaxUInt32 &&
2812 value == i::FastUI2D(i::FastD2UI(value));
Steve Block6ded16b2010-05-10 14:33:55 +01002813 }
2814 return false;
2815}
2816
2817
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002818bool Value::IsNativeError() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002819 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002820 if (!obj->IsJSObject()) return false;
2821 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
2822 i::Isolate* isolate = js_obj->GetIsolate();
2823 i::Handle<i::Object> constructor(js_obj->map()->GetConstructor(), isolate);
2824 if (!constructor->IsJSFunction()) return false;
2825 i::Handle<i::JSFunction> function =
2826 i::Handle<i::JSFunction>::cast(constructor);
2827 if (!function->shared()->native()) return false;
2828 return function.is_identical_to(isolate->error_function()) ||
2829 function.is_identical_to(isolate->eval_error_function()) ||
2830 function.is_identical_to(isolate->range_error_function()) ||
2831 function.is_identical_to(isolate->reference_error_function()) ||
2832 function.is_identical_to(isolate->syntax_error_function()) ||
2833 function.is_identical_to(isolate->type_error_function()) ||
2834 function.is_identical_to(isolate->uri_error_function());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002835}
2836
2837
Iain Merrick75681382010-08-19 15:07:18 +01002838bool Value::IsRegExp() const {
Iain Merrick75681382010-08-19 15:07:18 +01002839 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2840 return obj->IsJSRegExp();
2841}
2842
2843
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002844bool Value::IsGeneratorFunction() const {
2845 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2846 if (!obj->IsJSFunction()) return false;
2847 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
2848 return func->shared()->is_generator();
2849}
2850
2851
2852bool Value::IsGeneratorObject() const {
2853 return Utils::OpenHandle(this)->IsJSGeneratorObject();
2854}
2855
2856
2857bool Value::IsMapIterator() const {
2858 return Utils::OpenHandle(this)->IsJSMapIterator();
2859}
2860
2861
2862bool Value::IsSetIterator() const {
2863 return Utils::OpenHandle(this)->IsJSSetIterator();
2864}
2865
2866
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002867bool Value::IsPromise() const {
2868 auto self = Utils::OpenHandle(this);
2869 return i::Object::IsPromise(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00002870}
2871
2872
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002873MaybeLocal<String> Value::ToString(Local<Context> context) const {
2874 auto obj = Utils::OpenHandle(this);
2875 if (obj->IsString()) return ToApiHandle<String>(obj);
2876 PREPARE_FOR_EXECUTION(context, "ToString", String);
2877 Local<String> result;
2878 has_pending_exception =
2879 !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
2880 RETURN_ON_FAILED_EXECUTION(String);
2881 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002882}
2883
2884
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002885Local<String> Value::ToString(Isolate* isolate) const {
2886 RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String);
2887}
2888
2889
2890MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002891 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002892 if (obj->IsString()) return ToApiHandle<String>(obj);
2893 PREPARE_FOR_EXECUTION(context, "ToDetailString", String);
2894 Local<String> result;
2895 i::Handle<i::Object> args[] = {obj};
2896 has_pending_exception = !ToLocal<String>(
2897 i::Execution::TryCall(isolate, isolate->no_side_effects_to_string_fun(),
2898 isolate->factory()->undefined_value(),
2899 arraysize(args), args),
2900 &result);
2901 RETURN_ON_FAILED_EXECUTION(String);
2902 RETURN_ESCAPED(result);
2903}
2904
2905
2906Local<String> Value::ToDetailString(Isolate* isolate) const {
2907 RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()),
2908 String);
2909}
2910
2911
2912MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
2913 auto obj = Utils::OpenHandle(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002914 if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002915 PREPARE_FOR_EXECUTION(context, "ToObject", Object);
2916 Local<Object> result;
2917 has_pending_exception =
Ben Murdoch097c5b22016-05-18 11:27:45 +01002918 !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002919 RETURN_ON_FAILED_EXECUTION(Object);
2920 RETURN_ESCAPED(result);
2921}
2922
2923
2924Local<v8::Object> Value::ToObject(Isolate* isolate) const {
2925 RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object);
2926}
2927
2928
2929MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const {
2930 auto obj = Utils::OpenHandle(this);
2931 if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj);
2932 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
2933 auto val = isolate->factory()->ToBoolean(obj->BooleanValue());
2934 return ToApiHandle<Boolean>(val);
Steve Blocka7e24c12009-10-30 11:49:00 +00002935}
2936
2937
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002938Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002939 return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00002940}
2941
2942
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002943MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
2944 auto obj = Utils::OpenHandle(this);
2945 if (obj->IsNumber()) return ToApiHandle<Number>(obj);
2946 PREPARE_FOR_EXECUTION(context, "ToNumber", Number);
2947 Local<Number> result;
2948 has_pending_exception = !ToLocal<Number>(i::Object::ToNumber(obj), &result);
2949 RETURN_ON_FAILED_EXECUTION(Number);
2950 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002951}
2952
2953
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002954Local<Number> Value::ToNumber(Isolate* isolate) const {
2955 RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number);
2956}
2957
2958
2959MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
2960 auto obj = Utils::OpenHandle(this);
2961 if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
2962 PREPARE_FOR_EXECUTION(context, "ToInteger", Integer);
2963 Local<Integer> result;
2964 has_pending_exception =
2965 !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
2966 RETURN_ON_FAILED_EXECUTION(Integer);
2967 RETURN_ESCAPED(result);
2968}
2969
2970
2971Local<Integer> Value::ToInteger(Isolate* isolate) const {
2972 RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer);
2973}
2974
2975
2976MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
2977 auto obj = Utils::OpenHandle(this);
2978 if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
2979 Local<Int32> result;
2980 PREPARE_FOR_EXECUTION(context, "ToInt32", Int32);
2981 has_pending_exception =
2982 !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
2983 RETURN_ON_FAILED_EXECUTION(Int32);
2984 RETURN_ESCAPED(result);
2985}
2986
2987
2988Local<Int32> Value::ToInt32(Isolate* isolate) const {
2989 RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32);
2990}
2991
2992
2993MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
2994 auto obj = Utils::OpenHandle(this);
2995 if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
2996 Local<Uint32> result;
2997 PREPARE_FOR_EXECUTION(context, "ToUint32", Uint32);
2998 has_pending_exception =
2999 !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3000 RETURN_ON_FAILED_EXECUTION(Uint32);
3001 RETURN_ESCAPED(result);
3002}
3003
3004
3005Local<Uint32> Value::ToUint32(Isolate* isolate) const {
3006 RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003007}
3008
3009
3010void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3011 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3012 Utils::ApiCheck(isolate != NULL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003013 !isolate->IsDead(),
3014 "v8::internal::Internals::CheckInitialized()",
3015 "Isolate is not initialized or V8 has died");
Steve Blocka7e24c12009-10-30 11:49:00 +00003016}
3017
3018
3019void External::CheckCast(v8::Value* that) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003020 Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(),
3021 "v8::External::Cast()",
3022 "Could not convert to external");
Steve Blocka7e24c12009-10-30 11:49:00 +00003023}
3024
3025
3026void v8::Object::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003027 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003028 Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast()",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003029 "Could not convert to object");
Steve Blocka7e24c12009-10-30 11:49:00 +00003030}
3031
3032
3033void v8::Function::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003034 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003035 Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast()",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003036 "Could not convert to function");
3037}
3038
3039
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003040void v8::Boolean::CheckCast(v8::Value* that) {
3041 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3042 Utils::ApiCheck(obj->IsBoolean(),
3043 "v8::Boolean::Cast()",
3044 "Could not convert to boolean");
3045}
3046
3047
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003048void v8::Name::CheckCast(v8::Value* that) {
3049 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3050 Utils::ApiCheck(obj->IsName(),
3051 "v8::Name::Cast()",
3052 "Could not convert to name");
Steve Blocka7e24c12009-10-30 11:49:00 +00003053}
3054
3055
3056void v8::String::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003057 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003058 Utils::ApiCheck(obj->IsString(),
3059 "v8::String::Cast()",
3060 "Could not convert to string");
3061}
3062
3063
3064void v8::Symbol::CheckCast(v8::Value* that) {
3065 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3066 Utils::ApiCheck(obj->IsSymbol(),
3067 "v8::Symbol::Cast()",
3068 "Could not convert to symbol");
Steve Blocka7e24c12009-10-30 11:49:00 +00003069}
3070
3071
3072void v8::Number::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003073 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003074 Utils::ApiCheck(obj->IsNumber(),
3075 "v8::Number::Cast()",
3076 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00003077}
3078
3079
3080void v8::Integer::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003081 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003082 Utils::ApiCheck(obj->IsNumber(),
3083 "v8::Integer::Cast()",
3084 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00003085}
3086
3087
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003088void v8::Int32::CheckCast(v8::Value* that) {
3089 Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast()",
3090 "Could not convert to 32-bit signed integer");
3091}
3092
3093
3094void v8::Uint32::CheckCast(v8::Value* that) {
3095 Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast()",
3096 "Could not convert to 32-bit unsigned integer");
3097}
3098
3099
Steve Blocka7e24c12009-10-30 11:49:00 +00003100void v8::Array::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003101 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003102 Utils::ApiCheck(obj->IsJSArray(),
3103 "v8::Array::Cast()",
3104 "Could not convert to array");
3105}
3106
3107
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003108void v8::Map::CheckCast(Value* that) {
3109 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3110 Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast()",
3111 "Could not convert to Map");
3112}
3113
3114
3115void v8::Set::CheckCast(Value* that) {
3116 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3117 Utils::ApiCheck(obj->IsJSSet(), "v8::Set::Cast()",
3118 "Could not convert to Set");
3119}
3120
3121
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003122void v8::Promise::CheckCast(Value* that) {
3123 Utils::ApiCheck(that->IsPromise(),
3124 "v8::Promise::Cast()",
3125 "Could not convert to promise");
3126}
3127
3128
3129void v8::Promise::Resolver::CheckCast(Value* that) {
3130 Utils::ApiCheck(that->IsPromise(),
3131 "v8::Promise::Resolver::Cast()",
3132 "Could not convert to promise resolver");
3133}
3134
3135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003136void v8::Proxy::CheckCast(Value* that) {
3137 Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast()",
3138 "Could not convert to proxy");
3139}
3140
3141
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003142void v8::ArrayBuffer::CheckCast(Value* that) {
3143 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003144 Utils::ApiCheck(
3145 obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared(),
3146 "v8::ArrayBuffer::Cast()", "Could not convert to ArrayBuffer");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003147}
3148
3149
3150void v8::ArrayBufferView::CheckCast(Value* that) {
3151 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3152 Utils::ApiCheck(obj->IsJSArrayBufferView(),
3153 "v8::ArrayBufferView::Cast()",
3154 "Could not convert to ArrayBufferView");
3155}
3156
3157
3158void v8::TypedArray::CheckCast(Value* that) {
3159 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3160 Utils::ApiCheck(obj->IsJSTypedArray(),
3161 "v8::TypedArray::Cast()",
3162 "Could not convert to TypedArray");
3163}
3164
3165
3166#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \
3167 void v8::Type##Array::CheckCast(Value* that) { \
3168 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003169 Utils::ApiCheck( \
3170 obj->IsJSTypedArray() && \
3171 i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array, \
3172 "v8::" #Type "Array::Cast()", "Could not convert to " #Type "Array"); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003173 }
3174
3175
3176TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
3177
3178#undef CHECK_TYPED_ARRAY_CAST
3179
3180
3181void v8::DataView::CheckCast(Value* that) {
3182 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3183 Utils::ApiCheck(obj->IsJSDataView(),
3184 "v8::DataView::Cast()",
3185 "Could not convert to DataView");
Steve Blocka7e24c12009-10-30 11:49:00 +00003186}
3187
3188
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003189void v8::SharedArrayBuffer::CheckCast(Value* that) {
3190 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3191 Utils::ApiCheck(
3192 obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared(),
3193 "v8::SharedArrayBuffer::Cast()",
3194 "Could not convert to SharedArrayBuffer");
3195}
3196
3197
Steve Blocka7e24c12009-10-30 11:49:00 +00003198void v8::Date::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003199 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003200 i::Isolate* isolate = NULL;
3201 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3202 Utils::ApiCheck(isolate != NULL &&
3203 obj->HasSpecificClassOf(isolate->heap()->Date_string()),
3204 "v8::Date::Cast()",
3205 "Could not convert to date");
Steve Blocka7e24c12009-10-30 11:49:00 +00003206}
3207
3208
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003209void v8::StringObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003210 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003211 i::Isolate* isolate = NULL;
3212 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3213 Utils::ApiCheck(isolate != NULL &&
3214 obj->HasSpecificClassOf(isolate->heap()->String_string()),
3215 "v8::StringObject::Cast()",
3216 "Could not convert to StringObject");
3217}
3218
3219
3220void v8::SymbolObject::CheckCast(v8::Value* that) {
3221 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3222 i::Isolate* isolate = NULL;
3223 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3224 Utils::ApiCheck(isolate != NULL &&
3225 obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
3226 "v8::SymbolObject::Cast()",
3227 "Could not convert to SymbolObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003228}
3229
3230
3231void v8::NumberObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003232 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003233 i::Isolate* isolate = NULL;
3234 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3235 Utils::ApiCheck(isolate != NULL &&
3236 obj->HasSpecificClassOf(isolate->heap()->Number_string()),
3237 "v8::NumberObject::Cast()",
3238 "Could not convert to NumberObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003239}
3240
3241
3242void v8::BooleanObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003243 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003244 i::Isolate* isolate = NULL;
3245 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3246 Utils::ApiCheck(isolate != NULL &&
3247 obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
3248 "v8::BooleanObject::Cast()",
3249 "Could not convert to BooleanObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003250}
3251
3252
Ben Murdochf87a2032010-10-22 12:50:53 +01003253void v8::RegExp::CheckCast(v8::Value* that) {
Ben Murdochf87a2032010-10-22 12:50:53 +01003254 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003255 Utils::ApiCheck(obj->IsJSRegExp(),
3256 "v8::RegExp::Cast()",
3257 "Could not convert to regular expression");
Ben Murdochf87a2032010-10-22 12:50:53 +01003258}
3259
3260
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003261Maybe<bool> Value::BooleanValue(Local<Context> context) const {
3262 return Just(Utils::OpenHandle(this)->BooleanValue());
3263}
3264
3265
Steve Blocka7e24c12009-10-30 11:49:00 +00003266bool Value::BooleanValue() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003267 return Utils::OpenHandle(this)->BooleanValue();
Steve Blocka7e24c12009-10-30 11:49:00 +00003268}
3269
3270
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003271Maybe<double> Value::NumberValue(Local<Context> context) const {
3272 auto obj = Utils::OpenHandle(this);
3273 if (obj->IsNumber()) return Just(obj->Number());
3274 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "NumberValue", double);
3275 i::Handle<i::Object> num;
3276 has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num);
3277 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
3278 return Just(num->Number());
3279}
3280
3281
Steve Blocka7e24c12009-10-30 11:49:00 +00003282double Value::NumberValue() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003283 auto obj = Utils::OpenHandle(this);
3284 if (obj->IsNumber()) return obj->Number();
3285 return NumberValue(ContextFromHeapObject(obj))
3286 .FromMaybe(std::numeric_limits<double>::quiet_NaN());
3287}
3288
3289
3290Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
3291 auto obj = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003292 if (obj->IsNumber()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003293 return Just(NumberToInt64(*obj));
Steve Blocka7e24c12009-10-30 11:49:00 +00003294 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01003295 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "IntegerValue", int64_t);
3296 i::Handle<i::Object> num;
3297 has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
3298 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
3299 return Just(NumberToInt64(*num));
Steve Blocka7e24c12009-10-30 11:49:00 +00003300}
3301
3302
3303int64_t Value::IntegerValue() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003304 auto obj = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003305 if (obj->IsNumber()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003306 if (obj->IsSmi()) {
3307 return i::Smi::cast(*obj)->value();
3308 } else {
3309 return static_cast<int64_t>(obj->Number());
3310 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003311 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003312 return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0);
Steve Blocka7e24c12009-10-30 11:49:00 +00003313}
3314
3315
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003316Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
3317 auto obj = Utils::OpenHandle(this);
3318 if (obj->IsNumber()) return Just(NumberToInt32(*obj));
3319 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Int32Value", int32_t);
Steve Blocka7e24c12009-10-30 11:49:00 +00003320 i::Handle<i::Object> num;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003321 has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
3322 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
3323 return Just(num->IsSmi() ? i::Smi::cast(*num)->value()
3324 : static_cast<int32_t>(num->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003325}
3326
3327
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003328int32_t Value::Int32Value() const {
3329 auto obj = Utils::OpenHandle(this);
3330 if (obj->IsNumber()) return NumberToInt32(*obj);
3331 return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0);
3332}
3333
3334
3335Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
3336 auto obj = Utils::OpenHandle(this);
3337 if (obj->IsNumber()) return Just(NumberToUint32(*obj));
3338 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Uint32Value", uint32_t);
Steve Blocka7e24c12009-10-30 11:49:00 +00003339 i::Handle<i::Object> num;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003340 has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
3341 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
3342 return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value())
3343 : static_cast<uint32_t>(num->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003344}
3345
3346
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003347uint32_t Value::Uint32Value() const {
3348 auto obj = Utils::OpenHandle(this);
3349 if (obj->IsNumber()) return NumberToUint32(*obj);
3350 return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0);
3351}
3352
3353
3354MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
3355 auto self = Utils::OpenHandle(this);
3356 if (self->IsSmi()) {
3357 if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00003358 return Local<Uint32>();
3359 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003360 PREPARE_FOR_EXECUTION(context, "ToArrayIndex", Uint32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003361 i::Handle<i::Object> string_obj;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003362 has_pending_exception =
3363 !i::Object::ToString(isolate, self).ToHandle(&string_obj);
3364 RETURN_ON_FAILED_EXECUTION(Uint32);
Steve Blocka7e24c12009-10-30 11:49:00 +00003365 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
3366 uint32_t index;
3367 if (str->AsArrayIndex(&index)) {
3368 i::Handle<i::Object> value;
3369 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003370 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003371 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01003372 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003373 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003374 RETURN_ESCAPED(Utils::Uint32ToLocal(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00003375 }
3376 return Local<Uint32>();
3377}
3378
3379
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003380Local<Uint32> Value::ToArrayIndex() const {
3381 auto self = Utils::OpenHandle(this);
3382 if (self->IsSmi()) {
3383 if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
3384 return Local<Uint32>();
Steve Blocka7e24c12009-10-30 11:49:00 +00003385 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003386 auto context = ContextFromHeapObject(self);
3387 RETURN_TO_LOCAL_UNCHECKED(ToArrayIndex(context), Uint32);
Steve Blocka7e24c12009-10-30 11:49:00 +00003388}
3389
3390
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003391Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
3392 auto self = Utils::OpenHandle(this);
3393 auto other = Utils::OpenHandle(*that);
3394 return i::Object::Equals(self, other);
Steve Blocka7e24c12009-10-30 11:49:00 +00003395}
3396
3397
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003398bool Value::Equals(Local<Value> that) const {
3399 auto self = Utils::OpenHandle(this);
3400 auto other = Utils::OpenHandle(*that);
3401 if (self->IsSmi() && other->IsSmi()) {
3402 return self->Number() == other->Number();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003403 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003404 if (self->IsJSObject() && other->IsJSObject()) {
3405 return *self == *other;
Steve Blocka7e24c12009-10-30 11:49:00 +00003406 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003407 auto heap_object = self->IsSmi() ? other : self;
3408 auto context = ContextFromHeapObject(heap_object);
3409 return Equals(context, that).FromMaybe(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003410}
3411
3412
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003413bool Value::StrictEquals(Local<Value> that) const {
3414 auto self = Utils::OpenHandle(this);
3415 auto other = Utils::OpenHandle(*that);
3416 return self->StrictEquals(*other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003417}
3418
3419
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003420bool Value::SameValue(Local<Value> that) const {
3421 auto self = Utils::OpenHandle(this);
3422 auto other = Utils::OpenHandle(*that);
3423 return self->SameValue(*other);
Steve Blocka7e24c12009-10-30 11:49:00 +00003424}
3425
3426
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003427Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
3428 v8::Local<Value> key, v8::Local<Value> value) {
3429 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
3430 auto self = Utils::OpenHandle(this);
3431 auto key_obj = Utils::OpenHandle(*key);
3432 auto value_obj = Utils::OpenHandle(*value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003433 has_pending_exception =
3434 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
3435 i::SLOPPY).is_null();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003436 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3437 return Just(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003438}
3439
3440
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003441bool v8::Object::Set(v8::Local<Value> key, v8::Local<Value> value) {
3442 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3443 return Set(context, key, value).FromMaybe(false);
3444}
3445
3446
3447Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
3448 v8::Local<Value> value) {
3449 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
3450 auto self = Utils::OpenHandle(this);
3451 auto value_obj = Utils::OpenHandle(*value);
3452 has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
3453 i::SLOPPY).is_null();
3454 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3455 return Just(true);
3456}
3457
3458
3459bool v8::Object::Set(uint32_t index, v8::Local<Value> value) {
3460 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3461 return Set(context, index, value).FromMaybe(false);
3462}
3463
3464
3465Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
3466 v8::Local<Name> key,
3467 v8::Local<Value> value) {
3468 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
3469 bool);
3470 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3471 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
Steve Block6ded16b2010-05-10 14:33:55 +01003472 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003473
3474 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
3475 isolate, self, key_obj, i::LookupIterator::OWN);
3476 Maybe<bool> result =
3477 i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
3478 has_pending_exception = result.IsNothing();
3479 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3480 return result;
Steve Block6ded16b2010-05-10 14:33:55 +01003481}
3482
3483
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003484Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
3485 uint32_t index,
3486 v8::Local<Value> value) {
3487 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
3488 bool);
3489 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3490 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
3491
3492 i::LookupIterator it(isolate, self, index, i::LookupIterator::OWN);
3493 Maybe<bool> result =
3494 i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
3495 has_pending_exception = result.IsNothing();
3496 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3497 return result;
3498}
3499
3500
3501Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
3502 v8::Local<Name> key,
3503 v8::Local<Value> value,
3504 v8::PropertyAttribute attributes) {
3505 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DefineOwnProperty()",
3506 bool);
3507 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3508 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
3509 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
3510
3511 if (self->IsAccessCheckNeeded() &&
3512 !isolate->MayAccess(handle(isolate->context()),
3513 i::Handle<i::JSObject>::cast(self))) {
3514 isolate->ReportFailedAccessCheck(i::Handle<i::JSObject>::cast(self));
3515 return Nothing<bool>();
3516 }
3517
3518 i::PropertyDescriptor desc;
3519 desc.set_writable(!(attributes & v8::ReadOnly));
3520 desc.set_enumerable(!(attributes & v8::DontEnum));
3521 desc.set_configurable(!(attributes & v8::DontDelete));
3522 desc.set_value(value_obj);
3523 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
3524 isolate, self, key_obj, &desc, i::Object::DONT_THROW);
3525 // Even though we said DONT_THROW, there might be accessors that do throw.
3526 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3527 return success;
3528}
3529
3530
3531MUST_USE_RESULT
3532static i::MaybeHandle<i::Object> DefineObjectProperty(
3533 i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
3534 i::Handle<i::Object> value, i::PropertyAttributes attrs) {
3535 i::Isolate* isolate = js_object->GetIsolate();
3536 bool success = false;
3537 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
3538 isolate, js_object, key, &success, i::LookupIterator::OWN);
3539 if (!success) return i::MaybeHandle<i::Object>();
3540
Ben Murdoch097c5b22016-05-18 11:27:45 +01003541 return i::JSObject::DefineOwnPropertyIgnoreAttributes(
3542 &it, value, attrs, i::JSObject::FORCE_FIELD);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003543}
3544
3545
3546Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
3547 v8::Local<Value> key, v8::Local<Value> value,
3548 v8::PropertyAttribute attribs) {
3549 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::ForceSet()", bool);
3550 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
3551 auto key_obj = Utils::OpenHandle(*key);
3552 auto value_obj = Utils::OpenHandle(*value);
3553 has_pending_exception =
3554 DefineObjectProperty(self, key_obj, value_obj,
3555 static_cast<i::PropertyAttributes>(attribs))
3556 .is_null();
3557 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3558 return Just(true);
3559}
3560
3561
3562bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value,
Steve Blocka7e24c12009-10-30 11:49:00 +00003563 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01003564 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003565 PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(),
3566 "v8::Object::ForceSet", false, i::HandleScope,
3567 false);
3568 i::Handle<i::JSObject> self =
3569 i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00003570 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3571 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003572 has_pending_exception =
3573 DefineObjectProperty(self, key_obj, value_obj,
3574 static_cast<i::PropertyAttributes>(attribs))
3575 .is_null();
3576 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003577 return true;
3578}
3579
3580
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003581Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
3582 Local<Value> value) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003583 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrivate()", bool);
3584 auto self = Utils::OpenHandle(this);
3585 auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
3586 auto value_obj = Utils::OpenHandle(*value);
3587 if (self->IsJSProxy()) {
3588 i::PropertyDescriptor desc;
3589 desc.set_writable(true);
3590 desc.set_enumerable(false);
3591 desc.set_configurable(true);
3592 desc.set_value(value_obj);
3593 return i::JSProxy::SetPrivateProperty(
3594 isolate, i::Handle<i::JSProxy>::cast(self),
3595 i::Handle<i::Symbol>::cast(key_obj), &desc, i::Object::DONT_THROW);
3596 }
3597 auto js_object = i::Handle<i::JSObject>::cast(self);
3598 i::LookupIterator it(js_object, key_obj);
3599 has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
3600 &it, value_obj, i::DONT_ENUM)
3601 .is_null();
3602 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3603 return Just(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003604}
3605
3606
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003607MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
3608 Local<Value> key) {
3609 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
3610 auto self = Utils::OpenHandle(this);
3611 auto key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003612 i::Handle<i::Object> result;
3613 has_pending_exception =
3614 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003615 RETURN_ON_FAILED_EXECUTION(Value);
3616 RETURN_ESCAPED(Utils::ToLocal(result));
3617}
3618
3619
3620Local<Value> v8::Object::Get(v8::Local<Value> key) {
3621 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3622 RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value);
3623}
3624
3625
3626MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
3627 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
3628 auto self = Utils::OpenHandle(this);
3629 i::Handle<i::Object> result;
3630 has_pending_exception =
3631 !i::Object::GetElement(isolate, self, index).ToHandle(&result);
3632 RETURN_ON_FAILED_EXECUTION(Value);
3633 RETURN_ESCAPED(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003634}
3635
3636
Steve Block6ded16b2010-05-10 14:33:55 +01003637Local<Value> v8::Object::Get(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003638 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3639 RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value);
Steve Block6ded16b2010-05-10 14:33:55 +01003640}
3641
3642
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003643MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
3644 Local<Private> key) {
3645 return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003646}
3647
3648
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003649Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
3650 Local<Context> context, Local<Value> key) {
3651 PREPARE_FOR_EXECUTION_PRIMITIVE(
3652 context, "v8::Object::GetPropertyAttributes()", PropertyAttribute);
3653 auto self = Utils::OpenHandle(this);
3654 auto key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003655 if (!key_obj->IsName()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003656 has_pending_exception =
3657 !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
3658 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003659 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003660 auto key_name = i::Handle<i::Name>::cast(key_obj);
3661 auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
3662 has_pending_exception = result.IsNothing();
3663 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
3664 if (result.FromJust() == i::ABSENT) {
3665 return Just(static_cast<PropertyAttribute>(i::NONE));
3666 }
3667 return Just(static_cast<PropertyAttribute>(result.FromJust()));
3668}
3669
3670
3671PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) {
3672 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3673 return GetPropertyAttributes(context, key)
3674 .FromMaybe(static_cast<PropertyAttribute>(i::NONE));
3675}
3676
3677
3678MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
3679 Local<String> key) {
3680 PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyDescriptor()",
3681 Value);
3682 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
3683 i::Handle<i::String> key_name = Utils::OpenHandle(*key);
3684
3685 i::PropertyDescriptor desc;
3686 Maybe<bool> found =
3687 i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
3688 has_pending_exception = found.IsNothing();
3689 RETURN_ON_FAILED_EXECUTION(Value);
3690 if (!found.FromJust()) {
3691 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3692 }
3693 RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003694}
3695
3696
3697Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003698 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3699 RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyDescriptor(context, key), Value);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003700}
3701
3702
Steve Blocka7e24c12009-10-30 11:49:00 +00003703Local<Value> v8::Object::GetPrototype() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003704 auto isolate = Utils::OpenHandle(this)->GetIsolate();
3705 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003706 i::PrototypeIterator iter(isolate, self);
3707 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
Steve Blocka7e24c12009-10-30 11:49:00 +00003708}
3709
3710
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003711Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
3712 Local<Value> value) {
3713 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrototype()", bool);
3714 auto self = Utils::OpenHandle(this);
3715 auto value_obj = Utils::OpenHandle(*value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003716 // We do not allow exceptions thrown while setting the prototype
3717 // to propagate outside.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003718 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
3719 auto result = i::JSReceiver::SetPrototype(self, value_obj, false,
3720 i::Object::THROW_ON_ERROR);
3721 has_pending_exception = result.IsNothing();
3722 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3723 return Just(true);
3724}
3725
3726
3727bool v8::Object::SetPrototype(Local<Value> value) {
3728 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3729 return SetPrototype(context, value).FromMaybe(false);
Andrei Popescu402d9372010-02-26 13:31:12 +00003730}
3731
3732
Steve Blocka7e24c12009-10-30 11:49:00 +00003733Local<Object> v8::Object::FindInstanceInPrototypeChain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003734 v8::Local<FunctionTemplate> tmpl) {
3735 auto isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003736 i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this),
3737 i::PrototypeIterator::START_AT_RECEIVER);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003738 auto tmpl_info = *Utils::OpenHandle(*tmpl);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003739 while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) {
3740 iter.Advance();
3741 if (iter.IsAtEnd()) {
3742 return Local<Object>();
3743 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003744 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003745 // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
3746 return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
3747}
3748
3749
3750MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
3751 PREPARE_FOR_EXECUTION(context, "v8::Object::GetPropertyNames()", Array);
3752 auto self = Utils::OpenHandle(this);
3753 i::Handle<i::FixedArray> value;
3754 has_pending_exception =
Ben Murdoch097c5b22016-05-18 11:27:45 +01003755 !i::JSReceiver::GetKeys(self, i::INCLUDE_PROTOS, i::ENUMERABLE_STRINGS)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003756 .ToHandle(&value);
3757 RETURN_ON_FAILED_EXECUTION(Array);
3758 // Because we use caching to speed up enumeration it is important
3759 // to never change the result of the basic enumeration function so
3760 // we clone the result.
3761 auto elms = isolate->factory()->CopyFixedArray(value);
3762 auto result = isolate->factory()->NewJSArrayWithElements(elms);
3763 RETURN_ESCAPED(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003764}
3765
3766
3767Local<Array> v8::Object::GetPropertyNames() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003768 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3769 RETURN_TO_LOCAL_UNCHECKED(GetPropertyNames(context), Array);
3770}
3771
3772
3773MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
3774 PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyNames()", Array);
3775 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003776 i::Handle<i::FixedArray> value;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003777 has_pending_exception =
3778 !i::JSReceiver::GetKeys(self, i::OWN_ONLY, i::ENUMERABLE_STRINGS)
3779 .ToHandle(&value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003780 RETURN_ON_FAILED_EXECUTION(Array);
Steve Blocka7e24c12009-10-30 11:49:00 +00003781 // Because we use caching to speed up enumeration it is important
3782 // to never change the result of the basic enumeration function so
3783 // we clone the result.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003784 auto elms = isolate->factory()->CopyFixedArray(value);
3785 auto result = isolate->factory()->NewJSArrayWithElements(elms);
3786 RETURN_ESCAPED(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003787}
3788
3789
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003790Local<Array> v8::Object::GetOwnPropertyNames() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003791 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3792 RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyNames(context), Array);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003793}
3794
3795
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003796MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
3797 PREPARE_FOR_EXECUTION(context, "v8::Object::ObjectProtoToString", String);
3798 auto obj = Utils::OpenHandle(this);
3799 Local<String> result;
3800 has_pending_exception =
3801 !ToLocal<String>(i::JSObject::ObjectProtoToString(isolate, obj), &result);
3802 RETURN_ON_FAILED_EXECUTION(String);
3803 RETURN_ESCAPED(result);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003804}
3805
3806
Steve Blocka7e24c12009-10-30 11:49:00 +00003807Local<String> v8::Object::ObjectProtoToString() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003808 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3809 RETURN_TO_LOCAL_UNCHECKED(ObjectProtoToString(context), String);
Steve Blocka7e24c12009-10-30 11:49:00 +00003810}
3811
3812
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003813Local<String> v8::Object::GetConstructorName() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003814 auto self = Utils::OpenHandle(this);
3815 i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003816 return Utils::ToLocal(name);
3817}
3818
3819
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003820Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
3821 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Delete()", bool);
3822 auto self = Utils::OpenHandle(this);
3823 auto key_obj = Utils::OpenHandle(*key);
3824 Maybe<bool> result =
3825 i::Runtime::DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY);
3826 has_pending_exception = result.IsNothing();
3827 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3828 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003829}
3830
3831
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003832bool v8::Object::Delete(v8::Local<Value> key) {
3833 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3834 return Delete(context, key).FromMaybe(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003835}
3836
3837
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003838Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
3839 Local<Private> key) {
3840 return Delete(context, Local<Value>(reinterpret_cast<Value*>(*key)));
3841}
3842
3843
3844Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
3845 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
3846 auto self = Utils::OpenHandle(this);
3847 auto key_obj = Utils::OpenHandle(*key);
3848 Maybe<bool> maybe = Nothing<bool>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003849 // Check if the given key is an array index.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003850 uint32_t index = 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003851 if (key_obj->ToArrayIndex(&index)) {
3852 maybe = i::JSReceiver::HasElement(self, index);
3853 } else {
3854 // Convert the key to a name - possibly by calling back into JavaScript.
3855 i::Handle<i::Name> name;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003856 if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003857 maybe = i::JSReceiver::HasProperty(self, name);
3858 }
3859 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003860 has_pending_exception = maybe.IsNothing();
3861 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3862 return maybe;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003863}
3864
3865
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003866bool v8::Object::Has(v8::Local<Value> key) {
3867 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3868 return Has(context, key).FromMaybe(false);
3869}
3870
3871
3872Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
3873 return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
3874}
3875
3876
3877Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
3878 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DeleteProperty()",
3879 bool);
3880 auto self = Utils::OpenHandle(this);
3881 Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
3882 has_pending_exception = result.IsNothing();
3883 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3884 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003885}
3886
3887
3888bool v8::Object::Delete(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003889 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3890 return Delete(context, index).FromMaybe(false);
3891}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003892
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003893
3894Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
3895 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
3896 auto self = Utils::OpenHandle(this);
3897 auto maybe = i::JSReceiver::HasElement(self, index);
3898 has_pending_exception = maybe.IsNothing();
3899 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3900 return maybe;
Steve Blocka7e24c12009-10-30 11:49:00 +00003901}
3902
3903
3904bool v8::Object::Has(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003905 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3906 return Has(context, index).FromMaybe(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003907}
3908
3909
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003910template <typename Getter, typename Setter, typename Data>
3911static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
3912 Local<Name> name, Getter getter,
3913 Setter setter, Data data,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003914 AccessControl settings,
3915 PropertyAttribute attributes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003916 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetAccessor()", bool);
3917 if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
3918 i::Handle<i::JSObject> obj =
3919 i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
3920 v8::Local<AccessorSignature> signature;
3921 auto info = MakeAccessorInfo(name, getter, setter, data, settings, attributes,
Ben Murdoch097c5b22016-05-18 11:27:45 +01003922 signature, i::FLAG_disable_old_api_accessors);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003923 if (info.is_null()) return Nothing<bool>();
3924 bool fast = obj->HasFastProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003925 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003926 has_pending_exception =
3927 !i::JSObject::SetAccessor(obj, info).ToHandle(&result);
3928 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3929 if (result->IsUndefined()) return Nothing<bool>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003930 if (fast) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003931 i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003932 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003933 return Just(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003934}
3935
3936
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003937Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
3938 AccessorNameGetterCallback getter,
3939 AccessorNameSetterCallback setter,
3940 MaybeLocal<Value> data, AccessControl settings,
3941 PropertyAttribute attribute) {
3942 return ObjectSetAccessor(context, this, name, getter, setter,
3943 data.FromMaybe(Local<Value>()), settings, attribute);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003944}
3945
3946
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003947bool Object::SetAccessor(Local<String> name, AccessorGetterCallback getter,
3948 AccessorSetterCallback setter, v8::Local<Value> data,
3949 AccessControl settings, PropertyAttribute attributes) {
3950 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3951 return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
3952 attributes).FromMaybe(false);
3953}
3954
3955
3956bool Object::SetAccessor(Local<Name> name, AccessorNameGetterCallback getter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003957 AccessorNameSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003958 v8::Local<Value> data, AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003959 PropertyAttribute attributes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003960 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3961 return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
3962 attributes).FromMaybe(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003963}
3964
3965
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003966void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
3967 Local<Function> setter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003968 PropertyAttribute attribute,
3969 AccessControl settings) {
3970 // TODO(verwaest): Remove |settings|.
3971 DCHECK_EQ(v8::DEFAULT, settings);
Steve Block44f0eee2011-05-26 01:26:41 +01003972 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01003973 ENTER_V8(isolate);
3974 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003975 auto self = Utils::OpenHandle(this);
3976 if (!self->IsJSObject()) return;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003977 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
3978 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
3979 if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003980 i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
3981 v8::Utils::OpenHandle(*name), getter_i, setter_i,
3982 static_cast<i::PropertyAttributes>(attribute));
Leon Clarkef7060e22010-06-03 12:02:55 +01003983}
3984
3985
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003986Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
3987 Local<Name> key) {
3988 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasOwnProperty()",
3989 bool);
3990 auto self = Utils::OpenHandle(this);
3991 auto key_val = Utils::OpenHandle(*key);
3992 auto result = i::JSReceiver::HasOwnProperty(self, key_val);
3993 has_pending_exception = result.IsNothing();
3994 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3995 return result;
Ben Murdoch257744e2011-11-30 15:57:28 +00003996}
3997
3998
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003999bool v8::Object::HasOwnProperty(Local<String> key) {
4000 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4001 return HasOwnProperty(context, key).FromMaybe(false);
4002}
4003
4004
4005Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4006 Local<Name> key) {
4007 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasRealNamedProperty()",
4008 bool);
4009 auto self = Utils::OpenHandle(this);
4010 if (!self->IsJSObject()) return Just(false);
4011 auto key_val = Utils::OpenHandle(*key);
4012 auto result = i::JSObject::HasRealNamedProperty(
4013 i::Handle<i::JSObject>::cast(self), key_val);
4014 has_pending_exception = result.IsNothing();
4015 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4016 return result;
4017}
4018
4019
4020bool v8::Object::HasRealNamedProperty(Local<String> key) {
4021 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4022 return HasRealNamedProperty(context, key).FromMaybe(false);
4023}
4024
4025
4026Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4027 uint32_t index) {
4028 PREPARE_FOR_EXECUTION_PRIMITIVE(context,
4029 "v8::Object::HasRealIndexedProperty()", bool);
4030 auto self = Utils::OpenHandle(this);
4031 if (!self->IsJSObject()) return Just(false);
4032 auto result = i::JSObject::HasRealElementProperty(
4033 i::Handle<i::JSObject>::cast(self), index);
4034 has_pending_exception = result.IsNothing();
4035 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4036 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004037}
4038
4039
4040bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004041 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4042 return HasRealIndexedProperty(context, index).FromMaybe(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004043}
4044
4045
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004046Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4047 Local<Name> key) {
4048 PREPARE_FOR_EXECUTION_PRIMITIVE(
4049 context, "v8::Object::HasRealNamedCallbackProperty()", bool);
4050 auto self = Utils::OpenHandle(this);
4051 if (!self->IsJSObject()) return Just(false);
4052 auto key_val = Utils::OpenHandle(*key);
4053 auto result = i::JSObject::HasRealNamedCallbackProperty(
4054 i::Handle<i::JSObject>::cast(self), key_val);
4055 has_pending_exception = result.IsNothing();
4056 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4057 return result;
4058}
4059
4060
4061bool v8::Object::HasRealNamedCallbackProperty(Local<String> key) {
4062 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4063 return HasRealNamedCallbackProperty(context, key).FromMaybe(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004064}
4065
4066
4067bool v8::Object::HasNamedLookupInterceptor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004068 auto self = Utils::OpenHandle(this);
4069 return self->IsJSObject() &&
4070 i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00004071}
4072
4073
4074bool v8::Object::HasIndexedLookupInterceptor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004075 auto self = Utils::OpenHandle(this);
4076 return self->IsJSObject() &&
4077 i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00004078}
4079
4080
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004081MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4082 Local<Context> context, Local<Name> key) {
4083 PREPARE_FOR_EXECUTION(
4084 context, "v8::Object::GetRealNamedPropertyInPrototypeChain()", Value);
4085 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4086 if (!self->IsJSObject()) return MaybeLocal<Value>();
4087 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4088 i::PrototypeIterator iter(isolate, self);
4089 if (iter.IsAtEnd()) return MaybeLocal<Value>();
4090 i::Handle<i::JSReceiver> proto =
4091 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4092 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4093 isolate, self, key_obj, proto,
4094 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4095 Local<Value> result;
4096 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4097 RETURN_ON_FAILED_EXECUTION(Value);
4098 if (!it.IsFound()) return MaybeLocal<Value>();
4099 RETURN_ESCAPED(result);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004100}
4101
4102
Steve Blocka7e24c12009-10-30 11:49:00 +00004103Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004104 Local<String> key) {
4105 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4106 RETURN_TO_LOCAL_UNCHECKED(GetRealNamedPropertyInPrototypeChain(context, key),
4107 Value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004108}
4109
4110
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004111Maybe<PropertyAttribute>
4112v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
4113 Local<Context> context, Local<Name> key) {
4114 PREPARE_FOR_EXECUTION_PRIMITIVE(
4115 context, "v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()",
4116 PropertyAttribute);
4117 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4118 if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
4119 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4120 i::PrototypeIterator iter(isolate, self);
4121 if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
4122 i::Handle<i::JSReceiver> proto =
4123 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4124 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4125 isolate, self, key_obj, proto,
4126 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4127 Maybe<i::PropertyAttributes> result =
4128 i::JSReceiver::GetPropertyAttributes(&it);
4129 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4130 if (!it.IsFound()) return Nothing<PropertyAttribute>();
4131 if (result.FromJust() == i::ABSENT) return Just(None);
4132 return Just(static_cast<PropertyAttribute>(result.FromJust()));
Steve Blocka7e24c12009-10-30 11:49:00 +00004133}
4134
4135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004136Maybe<PropertyAttribute>
4137v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key) {
4138 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4139 return GetRealNamedPropertyAttributesInPrototypeChain(context, key);
4140}
Steve Blocka7e24c12009-10-30 11:49:00 +00004141
Ben Murdochb0fe1622011-05-05 13:52:32 +01004142
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004143MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
4144 Local<Name> key) {
4145 PREPARE_FOR_EXECUTION(context, "v8::Object::GetRealNamedProperty()", Value);
4146 auto self = Utils::OpenHandle(this);
4147 auto key_obj = Utils::OpenHandle(*key);
4148 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4149 isolate, self, key_obj,
4150 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4151 Local<Value> result;
4152 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4153 RETURN_ON_FAILED_EXECUTION(Value);
4154 if (!it.IsFound()) return MaybeLocal<Value>();
4155 RETURN_ESCAPED(result);
4156}
4157
4158
4159Local<Value> v8::Object::GetRealNamedProperty(Local<String> key) {
4160 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4161 RETURN_TO_LOCAL_UNCHECKED(GetRealNamedProperty(context, key), Value);
4162}
4163
4164
4165Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4166 Local<Context> context, Local<Name> key) {
4167 PREPARE_FOR_EXECUTION_PRIMITIVE(
4168 context, "v8::Object::GetRealNamedPropertyAttributes()",
4169 PropertyAttribute);
4170 auto self = Utils::OpenHandle(this);
4171 auto key_obj = Utils::OpenHandle(*key);
4172 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4173 isolate, self, key_obj,
4174 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4175 auto result = i::JSReceiver::GetPropertyAttributes(&it);
4176 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4177 if (!it.IsFound()) return Nothing<PropertyAttribute>();
4178 if (result.FromJust() == i::ABSENT) {
4179 return Just(static_cast<PropertyAttribute>(i::NONE));
4180 }
4181 return Just<PropertyAttribute>(
4182 static_cast<PropertyAttribute>(result.FromJust()));
4183}
4184
4185
4186Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4187 Local<String> key) {
4188 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4189 return GetRealNamedPropertyAttributes(context, key);
Steve Blocka7e24c12009-10-30 11:49:00 +00004190}
4191
4192
Steve Blocka7e24c12009-10-30 11:49:00 +00004193Local<v8::Object> v8::Object::Clone() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004194 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4195 auto isolate = self->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004196 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004197 auto result = isolate->factory()->CopyJSObject(self);
4198 CHECK(!result.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00004199 return Utils::ToLocal(result);
4200}
4201
4202
Ben Murdoch8b112d22011-06-08 16:22:53 +01004203Local<v8::Context> v8::Object::CreationContext() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004204 auto self = Utils::OpenHandle(this);
4205 auto context = handle(self->GetCreationContext());
4206 return Utils::ToLocal(context);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004207}
4208
4209
Steve Blocka7e24c12009-10-30 11:49:00 +00004210int v8::Object::GetIdentityHash() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004211 auto isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004212 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004213 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004214 return i::JSReceiver::GetOrCreateIdentityHash(self)->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00004215}
4216
4217
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004218bool v8::Object::SetHiddenValue(v8::Local<v8::String> key,
4219 v8::Local<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004220 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004221 ENTER_V8(isolate);
4222 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004223 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4224 if (!self->IsJSObject()) return false;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004225 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004226 i::Handle<i::String> key_string =
4227 isolate->factory()->InternalizeString(key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004228 if (value.IsEmpty()) {
4229 i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
4230 key_string);
4231 return true;
4232 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004233 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004234 i::Handle<i::Object> result = i::JSObject::SetHiddenProperty(
4235 i::Handle<i::JSObject>::cast(self), key_string, value_obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004236 return *result == *self;
Steve Blocka7e24c12009-10-30 11:49:00 +00004237}
4238
4239
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004240v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Local<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01004241 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004242 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004243 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4244 if (!self->IsJSObject()) return v8::Local<v8::Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +00004245 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004246 i::Handle<i::String> key_string =
4247 isolate->factory()->InternalizeString(key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004248 i::Handle<i::Object> result(
4249 i::Handle<i::JSObject>::cast(self)->GetHiddenProperty(key_string),
4250 isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004251 if (result->IsTheHole()) return v8::Local<v8::Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +00004252 return Utils::ToLocal(result);
4253}
4254
4255
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004256bool v8::Object::DeleteHiddenValue(v8::Local<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01004257 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004258 ENTER_V8(isolate);
4259 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004260 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4261 if (!self->IsJSObject()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00004262 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004263 i::Handle<i::String> key_string =
4264 isolate->factory()->InternalizeString(key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004265 i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
4266 key_string);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004267 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00004268}
4269
4270
Ben Murdoch257744e2011-11-30 15:57:28 +00004271bool v8::Object::IsCallable() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004272 auto self = Utils::OpenHandle(this);
4273 return self->IsCallable();
Ben Murdoch257744e2011-11-30 15:57:28 +00004274}
4275
4276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004277MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
4278 Local<Value> recv, int argc,
4279 Local<Value> argv[]) {
4280 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Object::CallAsFunction()",
4281 Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004282 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004283 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004284 auto self = Utils::OpenHandle(this);
4285 auto recv_obj = Utils::OpenHandle(*recv);
4286 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004287 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004288 Local<Value> result;
4289 has_pending_exception = !ToLocal<Value>(
4290 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
4291 RETURN_ON_FAILED_EXECUTION(Value);
4292 RETURN_ESCAPED(result);
4293}
4294
4295
4296Local<v8::Value> Object::CallAsFunction(v8::Local<v8::Value> recv, int argc,
4297 v8::Local<v8::Value> argv[]) {
4298 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4299 Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
4300 RETURN_TO_LOCAL_UNCHECKED(CallAsFunction(context, recv, argc, argv_cast),
4301 Value);
4302}
4303
4304
4305MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
4306 Local<Value> argv[]) {
4307 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context,
4308 "v8::Object::CallAsConstructor()", Value);
4309 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004310 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004311 auto self = Utils::OpenHandle(this);
4312 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
4313 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4314 Local<Value> result;
4315 has_pending_exception = !ToLocal<Value>(
4316 i::Execution::New(isolate, self, self, argc, args), &result);
4317 RETURN_ON_FAILED_EXECUTION(Value);
4318 RETURN_ESCAPED(result);
Ben Murdoch257744e2011-11-30 15:57:28 +00004319}
4320
4321
4322Local<v8::Value> Object::CallAsConstructor(int argc,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004323 v8::Local<v8::Value> argv[]) {
4324 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4325 Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
4326 RETURN_TO_LOCAL_UNCHECKED(CallAsConstructor(context, argc, argv_cast), Value);
Ben Murdoch257744e2011-11-30 15:57:28 +00004327}
4328
4329
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004330MaybeLocal<Function> Function::New(Local<Context> context,
4331 FunctionCallback callback, Local<Value> data,
4332 int length) {
4333 i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004334 LOG_API(isolate, "Function::New");
4335 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004336 return FunctionTemplateNew(isolate, callback, nullptr, data,
4337 Local<Signature>(), length, true)
4338 ->GetFunction(context);
4339}
4340
4341
4342Local<Function> Function::New(Isolate* v8_isolate, FunctionCallback callback,
4343 Local<Value> data, int length) {
4344 return Function::New(v8_isolate->GetCurrentContext(), callback, data, length)
4345 .FromMaybe(Local<Function>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004346}
4347
4348
Steve Blocka7e24c12009-10-30 11:49:00 +00004349Local<v8::Object> Function::NewInstance() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004350 return NewInstance(Isolate::GetCurrent()->GetCurrentContext(), 0, NULL)
4351 .FromMaybe(Local<Object>());
4352}
4353
4354
4355MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
4356 v8::Local<v8::Value> argv[]) const {
4357 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::NewInstance()",
4358 Object);
4359 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004360 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004361 auto self = Utils::OpenHandle(this);
4362 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
4363 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4364 Local<Object> result;
4365 has_pending_exception = !ToLocal<Object>(
4366 i::Execution::New(isolate, self, self, argc, args), &result);
4367 RETURN_ON_FAILED_EXECUTION(Object);
4368 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004369}
4370
4371
4372Local<v8::Object> Function::NewInstance(int argc,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004373 v8::Local<v8::Value> argv[]) const {
4374 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4375 RETURN_TO_LOCAL_UNCHECKED(NewInstance(context, argc, argv), Object);
Steve Blocka7e24c12009-10-30 11:49:00 +00004376}
4377
4378
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004379MaybeLocal<v8::Value> Function::Call(Local<Context> context,
4380 v8::Local<v8::Value> recv, int argc,
4381 v8::Local<v8::Value> argv[]) {
4382 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::Call()", Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004383 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004384 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004385 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004386 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004387 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004388 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004389 Local<Value> result;
4390 has_pending_exception = !ToLocal<Value>(
4391 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
4392 RETURN_ON_FAILED_EXECUTION(Value);
4393 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004394}
4395
4396
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004397Local<v8::Value> Function::Call(v8::Local<v8::Value> recv, int argc,
4398 v8::Local<v8::Value> argv[]) {
4399 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4400 RETURN_TO_LOCAL_UNCHECKED(Call(context, recv, argc, argv), Value);
4401}
4402
4403
4404void Function::SetName(v8::Local<v8::String> name) {
4405 auto self = Utils::OpenHandle(this);
4406 if (!self->IsJSFunction()) return;
4407 auto func = i::Handle<i::JSFunction>::cast(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00004408 func->shared()->set_name(*Utils::OpenHandle(*name));
4409}
4410
4411
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004412Local<Value> Function::GetName() const {
4413 auto self = Utils::OpenHandle(this);
4414 if (self->IsJSBoundFunction()) {
4415 auto func = i::Handle<i::JSBoundFunction>::cast(self);
4416 return Utils::ToLocal(handle(func->name(), func->GetIsolate()));
4417 }
4418 if (self->IsJSFunction()) {
4419 auto func = i::Handle<i::JSFunction>::cast(self);
4420 return Utils::ToLocal(handle(func->shared()->name(), func->GetIsolate()));
4421 }
4422 return ToApiHandle<Primitive>(
4423 self->GetIsolate()->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004424}
4425
4426
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004427Local<Value> Function::GetInferredName() const {
4428 auto self = Utils::OpenHandle(this);
4429 if (!self->IsJSFunction()) {
4430 return ToApiHandle<Primitive>(
4431 self->GetIsolate()->factory()->undefined_value());
4432 }
4433 auto func = i::Handle<i::JSFunction>::cast(self);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004434 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4435 func->GetIsolate()));
4436}
4437
4438
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004439Local<Value> Function::GetDebugName() const {
4440 auto self = Utils::OpenHandle(this);
4441 if (!self->IsJSFunction()) {
4442 return ToApiHandle<Primitive>(
4443 self->GetIsolate()->factory()->undefined_value());
4444 }
4445 auto func = i::Handle<i::JSFunction>::cast(self);
4446 i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
4447 return Utils::ToLocal(i::Handle<i::Object>(*name, name->GetIsolate()));
4448}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004450
4451Local<Value> Function::GetDisplayName() const {
4452 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4453 ENTER_V8(isolate);
4454 auto self = Utils::OpenHandle(this);
4455 if (!self->IsJSFunction()) {
4456 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
4457 }
4458 auto func = i::Handle<i::JSFunction>::cast(self);
4459 i::Handle<i::String> property_name =
4460 isolate->factory()->NewStringFromStaticChars("displayName");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004461 i::Handle<i::Object> value =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004462 i::JSReceiver::GetDataProperty(func, property_name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004463 if (value->IsString()) {
4464 i::Handle<i::String> name = i::Handle<i::String>::cast(value);
4465 if (name->length() > 0) return Utils::ToLocal(name);
4466 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004467 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004468}
4469
4470
Andrei Popescu402d9372010-02-26 13:31:12 +00004471ScriptOrigin Function::GetScriptOrigin() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004472 auto self = Utils::OpenHandle(this);
4473 if (!self->IsJSFunction()) {
4474 return v8::ScriptOrigin(Local<Value>());
4475 }
4476 auto func = i::Handle<i::JSFunction>::cast(self);
Andrei Popescu402d9372010-02-26 13:31:12 +00004477 if (func->shared()->script()->IsScript()) {
4478 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004479 return GetScriptOriginForScript(func->GetIsolate(), script);
Andrei Popescu402d9372010-02-26 13:31:12 +00004480 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004481 return v8::ScriptOrigin(Local<Value>());
Andrei Popescu402d9372010-02-26 13:31:12 +00004482}
4483
4484
4485const int Function::kLineOffsetNotFound = -1;
4486
4487
4488int Function::GetScriptLineNumber() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004489 auto self = Utils::OpenHandle(this);
4490 if (!self->IsJSFunction()) {
4491 return kLineOffsetNotFound;
4492 }
4493 auto func = i::Handle<i::JSFunction>::cast(self);
Andrei Popescu402d9372010-02-26 13:31:12 +00004494 if (func->shared()->script()->IsScript()) {
4495 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004496 return i::Script::GetLineNumber(script, func->shared()->start_position());
Andrei Popescu402d9372010-02-26 13:31:12 +00004497 }
4498 return kLineOffsetNotFound;
4499}
4500
4501
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004502int Function::GetScriptColumnNumber() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004503 auto self = Utils::OpenHandle(this);
4504 if (!self->IsJSFunction()) {
4505 return kLineOffsetNotFound;
4506 }
4507 auto func = i::Handle<i::JSFunction>::cast(self);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004508 if (func->shared()->script()->IsScript()) {
4509 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004510 return i::Script::GetColumnNumber(script, func->shared()->start_position());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004511 }
4512 return kLineOffsetNotFound;
4513}
4514
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004515
4516bool Function::IsBuiltin() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004517 auto self = Utils::OpenHandle(this);
4518 if (!self->IsJSFunction()) {
4519 return false;
4520 }
4521 auto func = i::Handle<i::JSFunction>::cast(self);
4522 return func->shared()->IsBuiltin();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004523}
4524
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004525
4526int Function::ScriptId() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004527 auto self = Utils::OpenHandle(this);
4528 if (!self->IsJSFunction()) {
4529 return v8::UnboundScript::kNoScriptId;
4530 }
4531 auto func = i::Handle<i::JSFunction>::cast(self);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004532 if (!func->shared()->script()->IsScript()) {
4533 return v8::UnboundScript::kNoScriptId;
4534 }
4535 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004536 return script->id();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004537}
4538
4539
4540Local<v8::Value> Function::GetBoundFunction() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004541 auto self = Utils::OpenHandle(this);
4542 if (self->IsJSBoundFunction()) {
4543 auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
4544 auto bound_target_function = i::handle(
4545 bound_function->bound_target_function(), bound_function->GetIsolate());
4546 return Utils::CallableToLocal(bound_target_function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004547 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004548 return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004549}
4550
4551
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004552int Name::GetIdentityHash() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004553 auto self = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004554 return static_cast<int>(self->Hash());
4555}
4556
4557
Steve Blocka7e24c12009-10-30 11:49:00 +00004558int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004559 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004560 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00004561}
4562
4563
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004564bool String::IsOneByte() const {
4565 i::Handle<i::String> str = Utils::OpenHandle(this);
4566 return str->HasOnlyOneByteChars();
4567}
4568
4569
4570// Helpers for ContainsOnlyOneByteHelper
4571template<size_t size> struct OneByteMask;
4572template<> struct OneByteMask<4> {
4573 static const uint32_t value = 0xFF00FF00;
4574};
4575template<> struct OneByteMask<8> {
4576 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4577};
4578static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4579static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4580static inline bool Unaligned(const uint16_t* chars) {
4581 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4582}
4583
4584
4585static inline const uint16_t* Align(const uint16_t* chars) {
4586 return reinterpret_cast<uint16_t*>(
4587 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4588}
4589
4590class ContainsOnlyOneByteHelper {
4591 public:
4592 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4593 bool Check(i::String* string) {
4594 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4595 if (cons_string == NULL) return is_one_byte_;
4596 return CheckCons(cons_string);
4597 }
4598 void VisitOneByteString(const uint8_t* chars, int length) {
4599 // Nothing to do.
4600 }
4601 void VisitTwoByteString(const uint16_t* chars, int length) {
4602 // Accumulated bits.
4603 uintptr_t acc = 0;
4604 // Align to uintptr_t.
4605 const uint16_t* end = chars + length;
4606 while (Unaligned(chars) && chars != end) {
4607 acc |= *chars++;
4608 }
4609 // Read word aligned in blocks,
4610 // checking the return value at the end of each block.
4611 const uint16_t* aligned_end = Align(end);
4612 const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4613 const int inner_loops = 16;
4614 while (chars + inner_loops*increment < aligned_end) {
4615 for (int i = 0; i < inner_loops; i++) {
4616 acc |= *reinterpret_cast<const uintptr_t*>(chars);
4617 chars += increment;
4618 }
4619 // Check for early return.
4620 if ((acc & kOneByteMask) != 0) {
4621 is_one_byte_ = false;
4622 return;
4623 }
4624 }
4625 // Read the rest.
4626 while (chars != end) {
4627 acc |= *chars++;
4628 }
4629 // Check result.
4630 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
4631 }
4632
4633 private:
4634 bool CheckCons(i::ConsString* cons_string) {
4635 while (true) {
4636 // Check left side if flat.
4637 i::String* left = cons_string->first();
4638 i::ConsString* left_as_cons =
4639 i::String::VisitFlat(this, left, 0);
4640 if (!is_one_byte_) return false;
4641 // Check right side if flat.
4642 i::String* right = cons_string->second();
4643 i::ConsString* right_as_cons =
4644 i::String::VisitFlat(this, right, 0);
4645 if (!is_one_byte_) return false;
4646 // Standard recurse/iterate trick.
4647 if (left_as_cons != NULL && right_as_cons != NULL) {
4648 if (left->length() < right->length()) {
4649 CheckCons(left_as_cons);
4650 cons_string = right_as_cons;
4651 } else {
4652 CheckCons(right_as_cons);
4653 cons_string = left_as_cons;
4654 }
4655 // Check fast return.
4656 if (!is_one_byte_) return false;
4657 continue;
4658 }
4659 // Descend left in place.
4660 if (left_as_cons != NULL) {
4661 cons_string = left_as_cons;
4662 continue;
4663 }
4664 // Descend right in place.
4665 if (right_as_cons != NULL) {
4666 cons_string = right_as_cons;
4667 continue;
4668 }
4669 // Terminate.
4670 break;
4671 }
4672 return is_one_byte_;
4673 }
4674 bool is_one_byte_;
4675 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4676};
4677
4678
4679bool String::ContainsOnlyOneByte() const {
4680 i::Handle<i::String> str = Utils::OpenHandle(this);
4681 if (str->HasOnlyOneByteChars()) return true;
4682 ContainsOnlyOneByteHelper helper;
4683 return helper.Check(*str);
4684}
4685
4686
4687class Utf8LengthHelper : public i::AllStatic {
4688 public:
4689 enum State {
4690 kEndsWithLeadingSurrogate = 1 << 0,
4691 kStartsWithTrailingSurrogate = 1 << 1,
4692 kLeftmostEdgeIsCalculated = 1 << 2,
4693 kRightmostEdgeIsCalculated = 1 << 3,
4694 kLeftmostEdgeIsSurrogate = 1 << 4,
4695 kRightmostEdgeIsSurrogate = 1 << 5
4696 };
4697
4698 static const uint8_t kInitialState = 0;
4699
4700 static inline bool EndsWithSurrogate(uint8_t state) {
4701 return state & kEndsWithLeadingSurrogate;
4702 }
4703
4704 static inline bool StartsWithSurrogate(uint8_t state) {
4705 return state & kStartsWithTrailingSurrogate;
4706 }
4707
4708 class Visitor {
4709 public:
4710 Visitor() : utf8_length_(0), state_(kInitialState) {}
4711
4712 void VisitOneByteString(const uint8_t* chars, int length) {
4713 int utf8_length = 0;
4714 // Add in length 1 for each non-Latin1 character.
4715 for (int i = 0; i < length; i++) {
4716 utf8_length += *chars++ >> 7;
4717 }
4718 // Add in length 1 for each character.
4719 utf8_length_ = utf8_length + length;
4720 state_ = kInitialState;
4721 }
4722
4723 void VisitTwoByteString(const uint16_t* chars, int length) {
4724 int utf8_length = 0;
4725 int last_character = unibrow::Utf16::kNoPreviousCharacter;
4726 for (int i = 0; i < length; i++) {
4727 uint16_t c = chars[i];
4728 utf8_length += unibrow::Utf8::Length(c, last_character);
4729 last_character = c;
4730 }
4731 utf8_length_ = utf8_length;
4732 uint8_t state = 0;
4733 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4734 state |= kStartsWithTrailingSurrogate;
4735 }
4736 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4737 state |= kEndsWithLeadingSurrogate;
4738 }
4739 state_ = state;
4740 }
4741
4742 static i::ConsString* VisitFlat(i::String* string,
4743 int* length,
4744 uint8_t* state) {
4745 Visitor visitor;
4746 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4747 *length = visitor.utf8_length_;
4748 *state = visitor.state_;
4749 return cons_string;
4750 }
4751
4752 private:
4753 int utf8_length_;
4754 uint8_t state_;
4755 DISALLOW_COPY_AND_ASSIGN(Visitor);
4756 };
4757
4758 static inline void MergeLeafLeft(int* length,
4759 uint8_t* state,
4760 uint8_t leaf_state) {
4761 bool edge_surrogate = StartsWithSurrogate(leaf_state);
4762 if (!(*state & kLeftmostEdgeIsCalculated)) {
4763 DCHECK(!(*state & kLeftmostEdgeIsSurrogate));
4764 *state |= kLeftmostEdgeIsCalculated
4765 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4766 } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4767 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4768 }
4769 if (EndsWithSurrogate(leaf_state)) {
4770 *state |= kEndsWithLeadingSurrogate;
4771 } else {
4772 *state &= ~kEndsWithLeadingSurrogate;
4773 }
4774 }
4775
4776 static inline void MergeLeafRight(int* length,
4777 uint8_t* state,
4778 uint8_t leaf_state) {
4779 bool edge_surrogate = EndsWithSurrogate(leaf_state);
4780 if (!(*state & kRightmostEdgeIsCalculated)) {
4781 DCHECK(!(*state & kRightmostEdgeIsSurrogate));
4782 *state |= (kRightmostEdgeIsCalculated
4783 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4784 } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4785 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4786 }
4787 if (StartsWithSurrogate(leaf_state)) {
4788 *state |= kStartsWithTrailingSurrogate;
4789 } else {
4790 *state &= ~kStartsWithTrailingSurrogate;
4791 }
4792 }
4793
4794 static inline void MergeTerminal(int* length,
4795 uint8_t state,
4796 uint8_t* state_out) {
4797 DCHECK((state & kLeftmostEdgeIsCalculated) &&
4798 (state & kRightmostEdgeIsCalculated));
4799 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4800 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4801 }
4802 *state_out = kInitialState |
4803 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4804 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4805 }
4806
4807 static int Calculate(i::ConsString* current, uint8_t* state_out) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004808 using internal::ConsString;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004809 int total_length = 0;
4810 uint8_t state = kInitialState;
4811 while (true) {
4812 i::String* left = current->first();
4813 i::String* right = current->second();
4814 uint8_t right_leaf_state;
4815 uint8_t left_leaf_state;
4816 int leaf_length;
4817 ConsString* left_as_cons =
4818 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4819 if (left_as_cons == NULL) {
4820 total_length += leaf_length;
4821 MergeLeafLeft(&total_length, &state, left_leaf_state);
4822 }
4823 ConsString* right_as_cons =
4824 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4825 if (right_as_cons == NULL) {
4826 total_length += leaf_length;
4827 MergeLeafRight(&total_length, &state, right_leaf_state);
4828 if (left_as_cons != NULL) {
4829 // 1 Leaf node. Descend in place.
4830 current = left_as_cons;
4831 continue;
4832 } else {
4833 // Terminal node.
4834 MergeTerminal(&total_length, state, state_out);
4835 return total_length;
4836 }
4837 } else if (left_as_cons == NULL) {
4838 // 1 Leaf node. Descend in place.
4839 current = right_as_cons;
4840 continue;
4841 }
4842 // Both strings are ConsStrings.
4843 // Recurse on smallest.
4844 if (left->length() < right->length()) {
4845 total_length += Calculate(left_as_cons, &left_leaf_state);
4846 MergeLeafLeft(&total_length, &state, left_leaf_state);
4847 current = right_as_cons;
4848 } else {
4849 total_length += Calculate(right_as_cons, &right_leaf_state);
4850 MergeLeafRight(&total_length, &state, right_leaf_state);
4851 current = left_as_cons;
4852 }
4853 }
4854 UNREACHABLE();
4855 return 0;
4856 }
4857
4858 static inline int Calculate(i::ConsString* current) {
4859 uint8_t state = kInitialState;
4860 return Calculate(current, &state);
4861 }
4862
4863 private:
4864 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
4865};
4866
4867
4868static int Utf8Length(i::String* str, i::Isolate* isolate) {
4869 int length = str->length();
4870 if (length == 0) return 0;
4871 uint8_t state;
4872 i::ConsString* cons_string =
4873 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4874 if (cons_string == NULL) return length;
4875 return Utf8LengthHelper::Calculate(cons_string);
4876}
4877
4878
Steve Blocka7e24c12009-10-30 11:49:00 +00004879int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004880 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004881 i::Isolate* isolate = str->GetIsolate();
4882 return v8::Utf8Length(*str, isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004883}
4884
4885
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004886class Utf8WriterVisitor {
4887 public:
4888 Utf8WriterVisitor(
4889 char* buffer,
4890 int capacity,
4891 bool skip_capacity_check,
4892 bool replace_invalid_utf8)
4893 : early_termination_(false),
4894 last_character_(unibrow::Utf16::kNoPreviousCharacter),
4895 buffer_(buffer),
4896 start_(buffer),
4897 capacity_(capacity),
4898 skip_capacity_check_(capacity == -1 || skip_capacity_check),
4899 replace_invalid_utf8_(replace_invalid_utf8),
4900 utf16_chars_read_(0) {
4901 }
4902
4903 static int WriteEndCharacter(uint16_t character,
4904 int last_character,
4905 int remaining,
4906 char* const buffer,
4907 bool replace_invalid_utf8) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004908 DCHECK_GT(remaining, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004909 // We can't use a local buffer here because Encode needs to modify
4910 // previous characters in the stream. We know, however, that
4911 // exactly one character will be advanced.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004912 if (unibrow::Utf16::IsSurrogatePair(last_character, character)) {
4913 int written = unibrow::Utf8::Encode(buffer, character, last_character,
4914 replace_invalid_utf8);
4915 DCHECK_EQ(written, 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004916 return written;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004917 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004918 // Use a scratch buffer to check the required characters.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004919 char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004920 // Can't encode using last_character as gcc has array bounds issues.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004921 int written = unibrow::Utf8::Encode(temp_buffer, character,
4922 unibrow::Utf16::kNoPreviousCharacter,
4923 replace_invalid_utf8);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004924 // Won't fit.
4925 if (written > remaining) return 0;
4926 // Copy over the character from temp_buffer.
4927 for (int j = 0; j < written; j++) {
4928 buffer[j] = temp_buffer[j];
4929 }
4930 return written;
4931 }
4932
4933 // Visit writes out a group of code units (chars) of a v8::String to the
4934 // internal buffer_. This is done in two phases. The first phase calculates a
4935 // pesimistic estimate (writable_length) on how many code units can be safely
4936 // written without exceeding the buffer capacity and without writing the last
4937 // code unit (it could be a lead surrogate). The estimated number of code
4938 // units is then written out in one go, and the reported byte usage is used
4939 // to correct the estimate. This is repeated until the estimate becomes <= 0
4940 // or all code units have been written out. The second phase writes out code
4941 // units until the buffer capacity is reached, would be exceeded by the next
4942 // unit, or all units have been written out.
4943 template<typename Char>
4944 void Visit(const Char* chars, const int length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004945 DCHECK(!early_termination_);
4946 if (length == 0) return;
4947 // Copy state to stack.
4948 char* buffer = buffer_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004949 int last_character = sizeof(Char) == 1
4950 ? unibrow::Utf16::kNoPreviousCharacter
4951 : last_character_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004952 int i = 0;
4953 // Do a fast loop where there is no exit capacity check.
4954 while (true) {
4955 int fast_length;
4956 if (skip_capacity_check_) {
4957 fast_length = length;
4958 } else {
4959 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
4960 // Need enough space to write everything but one character.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004961 STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit ==
4962 3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004963 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
4964 int writable_length =
4965 (remaining_capacity - max_size_per_char)/max_size_per_char;
4966 // Need to drop into slow loop.
4967 if (writable_length <= 0) break;
4968 fast_length = i + writable_length;
4969 if (fast_length > length) fast_length = length;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004970 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004971 // Write the characters to the stream.
4972 if (sizeof(Char) == 1) {
4973 for (; i < fast_length; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004974 buffer += unibrow::Utf8::EncodeOneByte(
4975 buffer, static_cast<uint8_t>(*chars++));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004976 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004977 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004978 } else {
4979 for (; i < fast_length; i++) {
4980 uint16_t character = *chars++;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004981 buffer += unibrow::Utf8::Encode(buffer, character, last_character,
4982 replace_invalid_utf8_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004983 last_character = character;
4984 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004985 }
4986 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004987 // Array is fully written. Exit.
4988 if (fast_length == length) {
4989 // Write state back out to object.
4990 last_character_ = last_character;
4991 buffer_ = buffer;
4992 utf16_chars_read_ += length;
4993 return;
4994 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004995 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004996 DCHECK(!skip_capacity_check_);
4997 // Slow loop. Must check capacity on each iteration.
4998 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004999 DCHECK_GE(remaining_capacity, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005000 for (; i < length && remaining_capacity > 0; i++) {
5001 uint16_t character = *chars++;
5002 // remaining_capacity is <= 3 bytes at this point, so we do not write out
5003 // an umatched lead surrogate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005004 if (replace_invalid_utf8_ && unibrow::Utf16::IsLeadSurrogate(character)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005005 early_termination_ = true;
5006 break;
5007 }
5008 int written = WriteEndCharacter(character,
5009 last_character,
5010 remaining_capacity,
5011 buffer,
5012 replace_invalid_utf8_);
5013 if (written == 0) {
5014 early_termination_ = true;
5015 break;
5016 }
5017 buffer += written;
5018 remaining_capacity -= written;
5019 last_character = character;
5020 }
5021 // Write state back out to object.
5022 last_character_ = last_character;
5023 buffer_ = buffer;
5024 utf16_chars_read_ += i;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005025 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005026
5027 inline bool IsDone() {
5028 return early_termination_;
5029 }
5030
5031 inline void VisitOneByteString(const uint8_t* chars, int length) {
5032 Visit(chars, length);
5033 }
5034
5035 inline void VisitTwoByteString(const uint16_t* chars, int length) {
5036 Visit(chars, length);
5037 }
5038
5039 int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
5040 // Write out number of utf16 characters written to the stream.
5041 if (utf16_chars_read_out != NULL) {
5042 *utf16_chars_read_out = utf16_chars_read_;
5043 }
5044 // Only null terminate if all of the string was written and there's space.
5045 if (write_null &&
5046 !early_termination_ &&
5047 (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
5048 *buffer_++ = '\0';
5049 }
5050 return static_cast<int>(buffer_ - start_);
5051 }
5052
5053 private:
5054 bool early_termination_;
5055 int last_character_;
5056 char* buffer_;
5057 char* const start_;
5058 int capacity_;
5059 bool const skip_capacity_check_;
5060 bool const replace_invalid_utf8_;
5061 int utf16_chars_read_;
5062 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
5063};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005064
5065
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005066static bool RecursivelySerializeToUtf8(i::String* current,
5067 Utf8WriterVisitor* writer,
5068 int recursion_budget) {
5069 while (!writer->IsDone()) {
5070 i::ConsString* cons_string = i::String::VisitFlat(writer, current);
5071 if (cons_string == NULL) return true; // Leaf node.
5072 if (recursion_budget <= 0) return false;
5073 // Must write the left branch first.
5074 i::String* first = cons_string->first();
5075 bool success = RecursivelySerializeToUtf8(first,
5076 writer,
5077 recursion_budget - 1);
5078 if (!success) return false;
5079 // Inline tail recurse for right branch.
5080 current = cons_string->second();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005081 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005082 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00005083}
5084
5085
Steve Block6ded16b2010-05-10 14:33:55 +01005086int String::WriteUtf8(char* buffer,
5087 int capacity,
5088 int* nchars_ref,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005089 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005090 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005091 LOG_API(isolate, "String::WriteUtf8");
5092 ENTER_V8(isolate);
Ben Murdoch85b71792012-04-11 18:30:58 +01005093 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005094 if (options & HINT_MANY_WRITES_EXPECTED) {
5095 str = i::String::Flatten(str); // Flatten the string for efficiency.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005096 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005097 const int string_length = str->length();
5098 bool write_null = !(options & NO_NULL_TERMINATION);
5099 bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
5100 int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
5101 // First check if we can just write the string without checking capacity.
5102 if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
5103 Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005104 const int kMaxRecursion = 100;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005105 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
5106 if (success) return writer.CompleteWrite(write_null, nchars_ref);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005107 } else if (capacity >= string_length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005108 // First check that the buffer is large enough.
5109 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005110 if (utf8_bytes <= capacity) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005111 // one-byte fast path.
5112 if (utf8_bytes == string_length) {
5113 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
5114 if (nchars_ref != NULL) *nchars_ref = string_length;
5115 if (write_null && (utf8_bytes+1 <= capacity)) {
5116 return string_length + 1;
5117 }
5118 return string_length;
5119 }
5120 if (write_null && (utf8_bytes+1 > capacity)) {
5121 options |= NO_NULL_TERMINATION;
5122 }
5123 // Recurse once without a capacity limit.
5124 // This will get into the first branch above.
5125 // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005126 return WriteUtf8(buffer, -1, nchars_ref, options);
5127 }
5128 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005129 // Recursive slow path can potentially be unreasonable slow. Flatten.
5130 str = i::String::Flatten(str);
5131 Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
5132 i::String::VisitFlat(&writer, *str);
5133 return writer.CompleteWrite(write_null, nchars_ref);
Steve Blocka7e24c12009-10-30 11:49:00 +00005134}
5135
5136
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005137template<typename CharType>
5138static inline int WriteHelper(const String* string,
5139 CharType* buffer,
5140 int start,
5141 int length,
5142 int options) {
5143 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005144 LOG_API(isolate, "String::Write");
5145 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005146 DCHECK(start >= 0 && length >= -1);
5147 i::Handle<i::String> str = Utils::OpenHandle(string);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005148 if (options & String::HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01005149 // Flatten the string for efficiency. This applies whether we are
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005150 // using StringCharacterStream or Get(i) to access the characters.
5151 str = i::String::Flatten(str);
Steve Block6ded16b2010-05-10 14:33:55 +01005152 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01005153 int end = start + length;
5154 if ((length == -1) || (length > str->length() - start) )
5155 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00005156 if (end < 0) return 0;
5157 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005158 if (!(options & String::NO_NULL_TERMINATION) &&
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005159 (length == -1 || end - start < length)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005160 buffer[end - start] = '\0';
5161 }
5162 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00005163}
5164
5165
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005166int String::WriteOneByte(uint8_t* buffer,
5167 int start,
5168 int length,
5169 int options) const {
5170 return WriteHelper(this, buffer, start, length, options);
5171}
5172
5173
5174int String::Write(uint16_t* buffer,
5175 int start,
5176 int length,
5177 int options) const {
5178 return WriteHelper(this, buffer, start, length, options);
5179}
5180
5181
Steve Blocka7e24c12009-10-30 11:49:00 +00005182bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005183 i::Handle<i::String> str = Utils::OpenHandle(this);
5184 return i::StringShape(*str).IsExternalTwoByte();
5185}
5186
5187
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005188bool v8::String::IsExternalOneByte() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005189 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005190 return i::StringShape(*str).IsExternalOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00005191}
5192
5193
5194void v8::String::VerifyExternalStringResource(
5195 v8::String::ExternalStringResource* value) const {
5196 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005197 const v8::String::ExternalStringResource* expected;
Steve Blocka7e24c12009-10-30 11:49:00 +00005198 if (i::StringShape(*str).IsExternalTwoByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005199 const void* resource =
5200 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
5201 expected = reinterpret_cast<const ExternalStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00005202 } else {
5203 expected = NULL;
5204 }
5205 CHECK_EQ(expected, value);
5206}
5207
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005208void v8::String::VerifyExternalStringResourceBase(
5209 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005210 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005211 const v8::String::ExternalStringResourceBase* expected;
5212 Encoding expectedEncoding;
5213 if (i::StringShape(*str).IsExternalOneByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005214 const void* resource =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005215 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5216 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5217 expectedEncoding = ONE_BYTE_ENCODING;
5218 } else if (i::StringShape(*str).IsExternalTwoByte()) {
5219 const void* resource =
5220 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
5221 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5222 expectedEncoding = TWO_BYTE_ENCODING;
5223 } else {
5224 expected = NULL;
5225 expectedEncoding =
5226 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5227 }
5228 CHECK_EQ(expected, value);
5229 CHECK_EQ(expectedEncoding, encoding);
5230}
5231
5232const v8::String::ExternalOneByteStringResource*
5233v8::String::GetExternalOneByteStringResource() const {
5234 i::Handle<i::String> str = Utils::OpenHandle(this);
5235 if (i::StringShape(*str).IsExternalOneByte()) {
5236 const void* resource =
5237 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5238 return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00005239 } else {
5240 return NULL;
5241 }
5242}
5243
5244
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005245Local<Value> Symbol::Name() const {
5246 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5247 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
5248 return Utils::ToLocal(name);
5249}
5250
5251
5252Local<Value> Private::Name() const {
5253 return reinterpret_cast<const Symbol*>(this)->Name();
5254}
5255
5256
Steve Blocka7e24c12009-10-30 11:49:00 +00005257double Number::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005258 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5259 return obj->Number();
5260}
5261
5262
5263bool Boolean::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005264 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5265 return obj->IsTrue();
5266}
5267
5268
5269int64_t Integer::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005270 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5271 if (obj->IsSmi()) {
5272 return i::Smi::cast(*obj)->value();
5273 } else {
5274 return static_cast<int64_t>(obj->Number());
5275 }
5276}
5277
5278
5279int32_t Int32::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005280 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5281 if (obj->IsSmi()) {
5282 return i::Smi::cast(*obj)->value();
5283 } else {
5284 return static_cast<int32_t>(obj->Number());
5285 }
5286}
5287
5288
Steve Block6ded16b2010-05-10 14:33:55 +01005289uint32_t Uint32::Value() const {
Steve Block6ded16b2010-05-10 14:33:55 +01005290 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5291 if (obj->IsSmi()) {
5292 return i::Smi::cast(*obj)->value();
5293 } else {
5294 return static_cast<uint32_t>(obj->Number());
5295 }
5296}
5297
5298
Steve Blocka7e24c12009-10-30 11:49:00 +00005299int v8::Object::InternalFieldCount() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005300 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5301 if (!self->IsJSObject()) return 0;
5302 return i::Handle<i::JSObject>::cast(self)->GetInternalFieldCount();
Steve Blocka7e24c12009-10-30 11:49:00 +00005303}
5304
5305
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005306static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005307 const char* location) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005308 return Utils::ApiCheck(
5309 obj->IsJSObject() &&
5310 (index < i::Handle<i::JSObject>::cast(obj)->GetInternalFieldCount()),
5311 location, "Internal field out of bounds");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005312}
5313
5314
5315Local<Value> v8::Object::SlowGetInternalField(int index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005316 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005317 const char* location = "v8::Object::GetInternalField()";
5318 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005319 i::Handle<i::Object> value(
5320 i::Handle<i::JSObject>::cast(obj)->GetInternalField(index),
5321 obj->GetIsolate());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005322 return Utils::ToLocal(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00005323}
5324
5325
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005326void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
5327 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005328 const char* location = "v8::Object::SetInternalField()";
5329 if (!InternalFieldOK(obj, index, location)) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00005330 i::Handle<i::Object> val = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005331 i::Handle<i::JSObject>::cast(obj)->SetInternalField(index, *val);
Steve Blocka7e24c12009-10-30 11:49:00 +00005332}
5333
5334
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005335void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005336 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005337 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5338 if (!InternalFieldOK(obj, index, location)) return NULL;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005339 return DecodeSmiToAligned(
5340 i::Handle<i::JSObject>::cast(obj)->GetInternalField(index), location);
Ben Murdochb8e0da22011-05-16 14:20:40 +01005341}
5342
5343
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005344void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005345 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005346 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5347 if (!InternalFieldOK(obj, index, location)) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005348 i::Handle<i::JSObject>::cast(obj)
5349 ->SetInternalField(index, EncodeAlignedAsSmi(value, location));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005350 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
Ben Murdochb8e0da22011-05-16 14:20:40 +01005351}
5352
5353
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005354static void* ExternalValue(i::Object* obj) {
5355 // Obscure semantics for undefined, but somehow checked in our unit tests...
5356 if (obj->IsUndefined()) return NULL;
5357 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
5358 return i::Foreign::cast(foreign)->foreign_address();
Steve Blocka7e24c12009-10-30 11:49:00 +00005359}
5360
5361
5362// --- E n v i r o n m e n t ---
5363
Steve Block44f0eee2011-05-26 01:26:41 +01005364
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005365void v8::V8::InitializePlatform(Platform* platform) {
5366 i::V8::InitializePlatform(platform);
Steve Blocka7e24c12009-10-30 11:49:00 +00005367}
5368
5369
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005370void v8::V8::ShutdownPlatform() {
5371 i::V8::ShutdownPlatform();
5372}
5373
5374
5375bool v8::V8::Initialize() {
5376 i::V8::Initialize();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005377#ifdef V8_USE_EXTERNAL_STARTUP_DATA
5378 i::ReadNatives();
5379#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005380 return true;
5381}
5382
5383
5384void v8::V8::SetEntropySource(EntropySource entropy_source) {
5385 base::RandomNumberGenerator::SetEntropySource(entropy_source);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005386}
5387
5388
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005389void v8::V8::SetReturnAddressLocationResolver(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005390 ReturnAddressLocationResolver return_address_resolver) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005391 i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005392}
5393
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005394
Steve Blocka7e24c12009-10-30 11:49:00 +00005395bool v8::V8::Dispose() {
5396 i::V8::TearDown();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005397#ifdef V8_USE_EXTERNAL_STARTUP_DATA
5398 i::DisposeNatives();
5399#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005400 return true;
5401}
5402
5403
Russell Brenner90bac252010-11-18 13:33:46 -08005404HeapStatistics::HeapStatistics(): total_heap_size_(0),
5405 total_heap_size_executable_(0),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005406 total_physical_size_(0),
Ben Murdochb8e0da22011-05-16 14:20:40 +01005407 used_heap_size_(0),
5408 heap_size_limit_(0) { }
Steve Block3ce2e202009-11-05 08:53:23 +00005409
5410
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005411HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
5412 space_size_(0),
5413 space_used_size_(0),
5414 space_available_size_(0),
5415 physical_space_size_(0) { }
5416
5417
5418HeapObjectStatistics::HeapObjectStatistics()
5419 : object_type_(nullptr),
5420 object_sub_type_(nullptr),
5421 object_count_(0),
5422 object_size_(0) {}
5423
5424
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005425bool v8::V8::InitializeICU(const char* icu_data_file) {
5426 return i::InitializeICU(icu_data_file);
Steve Block6ded16b2010-05-10 14:33:55 +01005427}
5428
5429
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005430void v8::V8::InitializeExternalStartupData(const char* directory_path) {
5431 i::InitializeExternalStartupData(directory_path);
5432}
5433
5434
5435void v8::V8::InitializeExternalStartupData(const char* natives_blob,
5436 const char* snapshot_blob) {
5437 i::InitializeExternalStartupData(natives_blob, snapshot_blob);
5438}
5439
5440
Steve Blocka7e24c12009-10-30 11:49:00 +00005441const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01005442 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00005443}
5444
5445
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005446static i::Handle<i::Context> CreateEnvironment(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005447 i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
5448 v8::Local<ObjectTemplate> global_template,
5449 v8::Local<Value> maybe_global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005450 i::Handle<i::Context> env;
Steve Blocka7e24c12009-10-30 11:49:00 +00005451
5452 // Enter V8 via an ENTER_V8 scope.
Steve Blocka7e24c12009-10-30 11:49:00 +00005453 {
Steve Block44f0eee2011-05-26 01:26:41 +01005454 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005455 v8::Local<ObjectTemplate> proxy_template = global_template;
Steve Blocka7e24c12009-10-30 11:49:00 +00005456 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5457 i::Handle<i::FunctionTemplateInfo> global_constructor;
5458
5459 if (!global_template.IsEmpty()) {
5460 // Make sure that the global_template has a constructor.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005461 global_constructor = EnsureConstructor(isolate, *global_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005462
5463 // Create a fresh template for the global proxy object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005464 proxy_template = ObjectTemplate::New(
5465 reinterpret_cast<v8::Isolate*>(isolate));
5466 proxy_constructor = EnsureConstructor(isolate, *proxy_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005467
5468 // Set the global template to be the prototype template of
5469 // global proxy template.
5470 proxy_constructor->set_prototype_template(
5471 *Utils::OpenHandle(*global_template));
5472
5473 // Migrate security handlers from global_template to
5474 // proxy_template. Temporarily removing access check
5475 // information from the global template.
5476 if (!global_constructor->access_check_info()->IsUndefined()) {
5477 proxy_constructor->set_access_check_info(
5478 global_constructor->access_check_info());
5479 proxy_constructor->set_needs_access_check(
5480 global_constructor->needs_access_check());
5481 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01005482 global_constructor->set_access_check_info(
5483 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00005484 }
5485 }
5486
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005487 i::Handle<i::Object> proxy = Utils::OpenHandle(*maybe_global_proxy, true);
5488 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
5489 if (!proxy.is_null()) {
5490 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(proxy);
5491 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005492 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01005493 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005494 maybe_proxy, proxy_template, extensions);
Steve Blocka7e24c12009-10-30 11:49:00 +00005495
5496 // Restore the access check info on the global template.
5497 if (!global_template.IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005498 DCHECK(!global_constructor.is_null());
5499 DCHECK(!proxy_constructor.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00005500 global_constructor->set_access_check_info(
5501 proxy_constructor->access_check_info());
5502 global_constructor->set_needs_access_check(
5503 proxy_constructor->needs_access_check());
5504 }
5505 }
5506 // Leave V8.
5507
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005508 return env;
5509}
5510
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005511Local<Context> v8::Context::New(v8::Isolate* external_isolate,
5512 v8::ExtensionConfiguration* extensions,
5513 v8::Local<ObjectTemplate> global_template,
5514 v8::Local<Value> global_object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005515 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5516 LOG_API(isolate, "Context::New");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005517 i::HandleScope scope(isolate);
5518 ExtensionConfiguration no_extensions;
5519 if (extensions == NULL) extensions = &no_extensions;
5520 i::Handle<i::Context> env =
5521 CreateEnvironment(isolate, extensions, global_template, global_object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005522 if (env.is_null()) {
5523 if (isolate->has_pending_exception()) {
5524 isolate->OptionalRescheduleException(true);
5525 }
5526 return Local<Context>();
5527 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005528 return Utils::ToLocal(scope.CloseAndEscape(env));
Steve Blocka7e24c12009-10-30 11:49:00 +00005529}
5530
5531
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005532void v8::Context::SetSecurityToken(Local<Value> token) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005533 i::Handle<i::Context> env = Utils::OpenHandle(this);
5534 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
5535 env->set_security_token(*token_handle);
5536}
5537
5538
5539void v8::Context::UseDefaultSecurityToken() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005540 i::Handle<i::Context> env = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005541 env->set_security_token(env->global_object());
Steve Blocka7e24c12009-10-30 11:49:00 +00005542}
5543
5544
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005545Local<Value> v8::Context::GetSecurityToken() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005546 i::Handle<i::Context> env = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005547 i::Isolate* isolate = env->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +00005548 i::Object* security_token = env->security_token();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005549 i::Handle<i::Object> token_handle(security_token, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005550 return Utils::ToLocal(token_handle);
5551}
5552
5553
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005554v8::Isolate* Context::GetIsolate() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005555 i::Handle<i::Context> env = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005556 return reinterpret_cast<Isolate*>(env->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00005557}
5558
5559
5560v8::Local<v8::Object> Context::Global() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005561 i::Handle<i::Context> context = Utils::OpenHandle(this);
5562 i::Isolate* isolate = context->GetIsolate();
5563 i::Handle<i::Object> global(context->global_proxy(), isolate);
5564 // TODO(dcarney): This should always return the global proxy
5565 // but can't presently as calls to GetProtoype will return the wrong result.
5566 if (i::Handle<i::JSGlobalProxy>::cast(
5567 global)->IsDetachedFrom(context->global_object())) {
5568 global = i::Handle<i::Object>(context->global_object(), isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005569 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005570 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5571}
5572
5573
5574void Context::DetachGlobal() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005575 i::Handle<i::Context> context = Utils::OpenHandle(this);
5576 i::Isolate* isolate = context->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005577 ENTER_V8(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005578 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00005579}
5580
5581
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005582Local<v8::Object> Context::GetExtrasBindingObject() {
5583 i::Handle<i::Context> context = Utils::OpenHandle(this);
5584 i::Isolate* isolate = context->GetIsolate();
5585 i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
5586 return Utils::ToLocal(binding);
5587}
5588
5589
Ben Murdoch257744e2011-11-30 15:57:28 +00005590void Context::AllowCodeGenerationFromStrings(bool allow) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005591 i::Handle<i::Context> context = Utils::OpenHandle(this);
5592 i::Isolate* isolate = context->GetIsolate();
Ben Murdoch257744e2011-11-30 15:57:28 +00005593 ENTER_V8(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005594 context->set_allow_code_gen_from_strings(
5595 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5596}
5597
5598
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005599bool Context::IsCodeGenerationFromStringsAllowed() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005600 i::Handle<i::Context> context = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005601 return !context->allow_code_gen_from_strings()->IsFalse();
5602}
5603
5604
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005605void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005606 i::Handle<i::Context> context = Utils::OpenHandle(this);
5607 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
5608 context->set_error_message_for_code_gen_from_strings(*error_handle);
Andrei Popescu74b3c142010-03-29 12:03:09 +01005609}
5610
5611
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005612size_t Context::EstimatedSize() {
5613 return static_cast<size_t>(
5614 i::ContextMeasure(*Utils::OpenHandle(this)).Size());
5615}
5616
5617
5618MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
5619 PREPARE_FOR_EXECUTION(context, "v8::ObjectTemplate::NewInstance()", Object);
5620 auto self = Utils::OpenHandle(this);
5621 Local<Object> result;
5622 has_pending_exception =
5623 !ToLocal<Object>(i::ApiNatives::InstantiateObject(self), &result);
5624 RETURN_ON_FAILED_EXECUTION(Object);
5625 RETURN_ESCAPED(result);
5626}
5627
5628
Steve Blocka7e24c12009-10-30 11:49:00 +00005629Local<v8::Object> ObjectTemplate::NewInstance() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005630 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5631 RETURN_TO_LOCAL_UNCHECKED(NewInstance(context), Object);
5632}
5633
5634
5635MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
5636 PREPARE_FOR_EXECUTION(context, "v8::FunctionTemplate::GetFunction()",
5637 Function);
5638 auto self = Utils::OpenHandle(this);
5639 Local<Function> result;
5640 has_pending_exception =
5641 !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
5642 RETURN_ON_FAILED_EXECUTION(Function);
5643 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00005644}
5645
5646
5647Local<v8::Function> FunctionTemplate::GetFunction() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005648 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5649 RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function);
Steve Blocka7e24c12009-10-30 11:49:00 +00005650}
5651
5652
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005653bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
5654 auto self = Utils::OpenHandle(this);
5655 auto obj = Utils::OpenHandle(*value);
5656 return self->IsTemplateFor(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005657}
5658
5659
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005660Local<External> v8::External::New(Isolate* isolate, void* value) {
5661 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
5662 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5663 LOG_API(i_isolate, "External::New");
5664 ENTER_V8(i_isolate);
5665 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
5666 return Utils::ExternalToLocal(external);
Steve Blocka7e24c12009-10-30 11:49:00 +00005667}
5668
5669
5670void* External::Value() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005671 return ExternalValue(*Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00005672}
5673
5674
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005675// anonymous namespace for string creation helper functions
5676namespace {
5677
5678inline int StringLength(const char* string) {
5679 return i::StrLength(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005680}
5681
5682
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005683inline int StringLength(const uint8_t* string) {
5684 return i::StrLength(reinterpret_cast<const char*>(string));
5685}
5686
5687
5688inline int StringLength(const uint16_t* string) {
5689 int length = 0;
5690 while (string[length] != '\0')
5691 length++;
5692 return length;
5693}
5694
5695
5696MUST_USE_RESULT
5697inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005698 v8::NewStringType type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005699 i::Vector<const char> string) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005700 if (type == v8::NewStringType::kInternalized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005701 return factory->InternalizeUtf8String(string);
5702 }
5703 return factory->NewStringFromUtf8(string);
5704}
5705
5706
5707MUST_USE_RESULT
5708inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005709 v8::NewStringType type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005710 i::Vector<const uint8_t> string) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005711 if (type == v8::NewStringType::kInternalized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005712 return factory->InternalizeOneByteString(string);
5713 }
5714 return factory->NewStringFromOneByte(string);
5715}
5716
5717
5718MUST_USE_RESULT
5719inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005720 v8::NewStringType type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005721 i::Vector<const uint16_t> string) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005722 if (type == v8::NewStringType::kInternalized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005723 return factory->InternalizeTwoByteString(string);
5724 }
5725 return factory->NewStringFromTwoByte(string);
5726}
5727
5728
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005729STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
5730
5731
5732template <typename Char>
5733inline MaybeLocal<String> NewString(Isolate* v8_isolate, const char* location,
5734 const char* env, const Char* data,
5735 v8::NewStringType type, int length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005736 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005737 if (length == 0) return String::Empty(v8_isolate);
5738 // TODO(dcarney): throw a context free exception.
5739 if (length > i::String::kMaxLength) return MaybeLocal<String>();
Steve Block44f0eee2011-05-26 01:26:41 +01005740 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005741 LOG_API(isolate, env);
5742 if (length < 0) length = StringLength(data);
5743 i::Handle<i::String> result =
5744 NewString(isolate->factory(), type, i::Vector<const Char>(data, length))
5745 .ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00005746 return Utils::ToLocal(result);
5747}
5748
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005749} // anonymous namespace
5750
5751
5752Local<String> String::NewFromUtf8(Isolate* isolate,
5753 const char* data,
5754 NewStringType type,
5755 int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005756 RETURN_TO_LOCAL_UNCHECKED(
5757 NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
5758 data, static_cast<v8::NewStringType>(type), length),
5759 String);
5760}
5761
5762
5763MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
5764 v8::NewStringType type, int length) {
5765 return NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
5766 data, type, length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005767}
5768
5769
5770Local<String> String::NewFromOneByte(Isolate* isolate,
5771 const uint8_t* data,
5772 NewStringType type,
5773 int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005774 RETURN_TO_LOCAL_UNCHECKED(
5775 NewString(isolate, "v8::String::NewFromOneByte()",
5776 "String::NewFromOneByte", data,
5777 static_cast<v8::NewStringType>(type), length),
5778 String);
5779}
5780
5781
5782MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
5783 v8::NewStringType type, int length) {
5784 return NewString(isolate, "v8::String::NewFromOneByte()",
5785 "String::NewFromOneByte", data, type, length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005786}
5787
5788
5789Local<String> String::NewFromTwoByte(Isolate* isolate,
5790 const uint16_t* data,
5791 NewStringType type,
5792 int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005793 RETURN_TO_LOCAL_UNCHECKED(
5794 NewString(isolate, "v8::String::NewFromTwoByte()",
5795 "String::NewFromTwoByte", data,
5796 static_cast<v8::NewStringType>(type), length),
5797 String);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005798}
5799
Steve Blocka7e24c12009-10-30 11:49:00 +00005800
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005801MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
5802 const uint16_t* data,
5803 v8::NewStringType type, int length) {
5804 return NewString(isolate, "v8::String::NewFromTwoByte()",
5805 "String::NewFromTwoByte", data, type, length);
5806}
5807
5808
5809Local<String> v8::String::Concat(Local<String> left, Local<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00005810 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01005811 i::Isolate* isolate = left_string->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005812 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005813 LOG_API(isolate, "v8::String::Concat");
Steve Block3ce2e202009-11-05 08:53:23 +00005814 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005815 // If we are steering towards a range error, do not wait for the error to be
5816 // thrown, and return the null handle instead.
5817 if (left_string->length() + right_string->length() > i::String::kMaxLength) {
5818 return Local<String>();
5819 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005820 i::Handle<i::String> result = isolate->factory()->NewConsString(
5821 left_string, right_string).ToHandleChecked();
Steve Block3ce2e202009-11-05 08:53:23 +00005822 return Utils::ToLocal(result);
5823}
5824
5825
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005826MaybeLocal<String> v8::String::NewExternalTwoByte(
5827 Isolate* isolate, v8::String::ExternalStringResource* resource) {
5828 CHECK(resource && resource->data());
5829 // TODO(dcarney): throw a context free exception.
5830 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
5831 return MaybeLocal<String>();
5832 }
5833 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5834 ENTER_V8(i_isolate);
5835 LOG_API(i_isolate, "String::NewExternalTwoByte");
5836 i::Handle<i::String> string = i_isolate->factory()
5837 ->NewExternalStringFromTwoByte(resource)
5838 .ToHandleChecked();
5839 i_isolate->heap()->RegisterExternalString(*string);
5840 return Utils::ToLocal(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005841}
5842
5843
Steve Blocka7e24c12009-10-30 11:49:00 +00005844Local<String> v8::String::NewExternal(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005845 Isolate* isolate, v8::String::ExternalStringResource* resource) {
5846 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String);
5847}
5848
5849
5850MaybeLocal<String> v8::String::NewExternalOneByte(
5851 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005852 CHECK(resource && resource->data());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005853 // TODO(dcarney): throw a context free exception.
5854 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
5855 return MaybeLocal<String>();
5856 }
5857 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5858 ENTER_V8(i_isolate);
5859 LOG_API(i_isolate, "String::NewExternalOneByte");
5860 i::Handle<i::String> string = i_isolate->factory()
5861 ->NewExternalStringFromOneByte(resource)
5862 .ToHandleChecked();
5863 i_isolate->heap()->RegisterExternalString(*string);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005864 return Utils::ToLocal(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005865}
5866
5867
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005868Local<String> v8::String::NewExternal(
5869 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5870 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String);
5871}
5872
5873
Steve Blocka7e24c12009-10-30 11:49:00 +00005874bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005875 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005876 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005877 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005878 return false; // Already an external string.
5879 }
5880 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005881 if (isolate->heap()->IsInGCPostProcessing()) {
5882 return false;
5883 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005884 CHECK(resource && resource->data());
5885
Steve Blocka7e24c12009-10-30 11:49:00 +00005886 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005887 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5888 DCHECK(!CanMakeExternal() || result);
5889 if (result) {
5890 DCHECK(obj->IsExternalString());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005891 isolate->heap()->RegisterExternalString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005892 }
5893 return result;
5894}
5895
5896
Steve Blocka7e24c12009-10-30 11:49:00 +00005897bool v8::String::MakeExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005898 v8::String::ExternalOneByteStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005899 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005900 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005901 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005902 return false; // Already an external string.
5903 }
5904 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005905 if (isolate->heap()->IsInGCPostProcessing()) {
5906 return false;
5907 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005908 CHECK(resource && resource->data());
5909
Steve Blocka7e24c12009-10-30 11:49:00 +00005910 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005911 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5912 DCHECK(!CanMakeExternal() || result);
5913 if (result) {
5914 DCHECK(obj->IsExternalString());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005915 isolate->heap()->RegisterExternalString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005916 }
5917 return result;
5918}
5919
5920
5921bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005922 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005923 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005924
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005925 // Old space strings should be externalized.
5926 if (!isolate->heap()->new_space()->Contains(*obj)) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00005927 int size = obj->Size(); // Byte size of the original string.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005928 if (size <= i::ExternalString::kShortSize) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00005929 i::StringShape shape(*obj);
5930 return !shape.IsExternal();
5931}
5932
5933
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005934Isolate* v8::Object::GetIsolate() {
5935 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
5936 return reinterpret_cast<Isolate*>(i_isolate);
5937}
5938
5939
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005940Local<v8::Object> v8::Object::New(Isolate* isolate) {
5941 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5942 LOG_API(i_isolate, "Object::New");
5943 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005944 i::Handle<i::JSObject> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005945 i_isolate->factory()->NewJSObject(i_isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00005946 return Utils::ToLocal(obj);
5947}
5948
5949
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005950Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
5951 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5952 LOG_API(i_isolate, "NumberObject::New");
5953 ENTER_V8(i_isolate);
5954 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
5955 i::Handle<i::Object> obj =
5956 i::Object::ToObject(i_isolate, number).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005957 return Utils::ToLocal(obj);
5958}
5959
5960
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005961double v8::NumberObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005962 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5963 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005964 i::Isolate* isolate = jsvalue->GetIsolate();
5965 LOG_API(isolate, "NumberObject::NumberValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005966 return jsvalue->value()->Number();
5967}
5968
5969
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005970Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
5971 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5972 LOG_API(i_isolate, "BooleanObject::New");
5973 ENTER_V8(i_isolate);
5974 i::Handle<i::Object> boolean(value ? i_isolate->heap()->true_value()
5975 : i_isolate->heap()->false_value(),
5976 i_isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005977 i::Handle<i::Object> obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005978 i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005979 return Utils::ToLocal(obj);
5980}
5981
5982
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005983Local<v8::Value> v8::BooleanObject::New(bool value) {
5984 return New(Isolate::GetCurrent(), value);
5985}
5986
5987
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005988bool v8::BooleanObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005989 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5990 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005991 i::Isolate* isolate = jsvalue->GetIsolate();
5992 LOG_API(isolate, "BooleanObject::BooleanValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005993 return jsvalue->value()->IsTrue();
5994}
5995
5996
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005997Local<v8::Value> v8::StringObject::New(Local<String> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005998 i::Handle<i::String> string = Utils::OpenHandle(*value);
5999 i::Isolate* isolate = string->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006000 LOG_API(isolate, "StringObject::New");
6001 ENTER_V8(isolate);
6002 i::Handle<i::Object> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006003 i::Object::ToObject(isolate, string).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006004 return Utils::ToLocal(obj);
6005}
6006
6007
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006008Local<v8::String> v8::StringObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006009 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6010 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006011 i::Isolate* isolate = jsvalue->GetIsolate();
6012 LOG_API(isolate, "StringObject::StringValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006013 return Utils::ToLocal(
6014 i::Handle<i::String>(i::String::cast(jsvalue->value())));
6015}
6016
6017
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006018Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006019 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6020 LOG_API(i_isolate, "SymbolObject::New");
6021 ENTER_V8(i_isolate);
6022 i::Handle<i::Object> obj = i::Object::ToObject(
6023 i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00006024 return Utils::ToLocal(obj);
6025}
6026
6027
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006028Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
6029 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6030 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
6031 i::Isolate* isolate = jsvalue->GetIsolate();
6032 LOG_API(isolate, "SymbolObject::SymbolValue");
6033 return Utils::ToLocal(
6034 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
6035}
6036
6037
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006038MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006039 if (std::isnan(time)) {
6040 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006041 time = std::numeric_limits<double>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006042 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006043 PREPARE_FOR_EXECUTION(context, "Date::New", Value);
6044 Local<Value> result;
6045 has_pending_exception = !ToLocal<Value>(
6046 i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
6047 &result);
6048 RETURN_ON_FAILED_EXECUTION(Value);
6049 RETURN_ESCAPED(result);
6050}
6051
6052
6053Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
6054 auto context = isolate->GetCurrentContext();
6055 RETURN_TO_LOCAL_UNCHECKED(New(context, time), Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006056}
6057
6058
6059double v8::Date::ValueOf() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00006060 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006061 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006062 i::Isolate* isolate = jsdate->GetIsolate();
6063 LOG_API(isolate, "Date::NumberValue");
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006064 return jsdate->value()->Number();
Steve Blocka7e24c12009-10-30 11:49:00 +00006065}
6066
6067
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006068void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
6069 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006070 LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
6071 ENTER_V8(i_isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006072 i_isolate->date_cache()->ResetDateCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006073 if (!i_isolate->eternal_handles()->Exists(
6074 i::EternalHandles::DATE_CACHE_VERSION)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01006075 return;
6076 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006077 i::Handle<i::FixedArray> date_cache_version =
6078 i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
6079 i::EternalHandles::DATE_CACHE_VERSION));
6080 DCHECK_EQ(1, date_cache_version->length());
6081 CHECK(date_cache_version->get(0)->IsSmi());
6082 date_cache_version->set(
6083 0,
6084 i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1));
Ben Murdochb0fe1622011-05-05 13:52:32 +01006085}
6086
6087
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006088MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
6089 Local<String> pattern, Flags flags) {
6090 PREPARE_FOR_EXECUTION(context, "RegExp::New", RegExp);
6091 Local<v8::RegExp> result;
6092 has_pending_exception =
6093 !ToLocal<RegExp>(i::JSRegExp::New(Utils::OpenHandle(*pattern),
6094 static_cast<i::JSRegExp::Flags>(flags)),
6095 &result);
6096 RETURN_ON_FAILED_EXECUTION(RegExp);
6097 RETURN_ESCAPED(result);
Ben Murdochf87a2032010-10-22 12:50:53 +01006098}
6099
6100
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006101Local<v8::RegExp> v8::RegExp::New(Local<String> pattern, Flags flags) {
6102 auto isolate =
6103 reinterpret_cast<Isolate*>(Utils::OpenHandle(*pattern)->GetIsolate());
6104 auto context = isolate->GetCurrentContext();
6105 RETURN_TO_LOCAL_UNCHECKED(New(context, pattern, flags), RegExp);
Ben Murdochf87a2032010-10-22 12:50:53 +01006106}
6107
6108
6109Local<v8::String> v8::RegExp::GetSource() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01006110 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
6111 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
6112}
6113
6114
6115// Assert that the static flags cast in GetFlags is valid.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006116#define REGEXP_FLAG_ASSERT_EQ(flag) \
6117 STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
6118 static_cast<int>(i::JSRegExp::flag))
6119REGEXP_FLAG_ASSERT_EQ(kNone);
6120REGEXP_FLAG_ASSERT_EQ(kGlobal);
6121REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
6122REGEXP_FLAG_ASSERT_EQ(kMultiline);
6123REGEXP_FLAG_ASSERT_EQ(kSticky);
6124REGEXP_FLAG_ASSERT_EQ(kUnicode);
Ben Murdochf87a2032010-10-22 12:50:53 +01006125#undef REGEXP_FLAG_ASSERT_EQ
6126
6127v8::RegExp::Flags v8::RegExp::GetFlags() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01006128 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006129 return RegExp::Flags(static_cast<int>(obj->GetFlags()));
Ben Murdochf87a2032010-10-22 12:50:53 +01006130}
6131
6132
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006133Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
6134 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6135 LOG_API(i_isolate, "Array::New");
6136 ENTER_V8(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01006137 int real_length = length > 0 ? length : 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006138 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01006139 i::Handle<i::Object> length_obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006140 i_isolate->factory()->NewNumberFromInt(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01006141 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00006142 return Utils::ToLocal(obj);
6143}
6144
6145
6146uint32_t v8::Array::Length() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00006147 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
6148 i::Object* length = obj->length();
6149 if (length->IsSmi()) {
6150 return i::Smi::cast(length)->value();
6151 } else {
6152 return static_cast<uint32_t>(length->Number());
6153 }
6154}
6155
6156
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006157MaybeLocal<Object> Array::CloneElementAt(Local<Context> context,
6158 uint32_t index) {
6159 PREPARE_FOR_EXECUTION(context, "v8::Array::CloneElementAt()", Object);
6160 auto self = Utils::OpenHandle(this);
6161 if (!self->HasFastObjectElements()) return Local<Object>();
Steve Blocka7e24c12009-10-30 11:49:00 +00006162 i::FixedArray* elms = i::FixedArray::cast(self->elements());
6163 i::Object* paragon = elms->get(index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006164 if (!paragon->IsJSObject()) return Local<Object>();
Steve Blocka7e24c12009-10-30 11:49:00 +00006165 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006166 Local<Object> result;
6167 has_pending_exception =
6168 !ToLocal<Object>(isolate->factory()->CopyJSObject(paragon_handle),
6169 &result);
6170 RETURN_ON_FAILED_EXECUTION(Object);
6171 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00006172}
6173
6174
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006175Local<Object> Array::CloneElementAt(uint32_t index) { return Local<Object>(); }
6176
6177
6178Local<v8::Map> v8::Map::New(Isolate* isolate) {
6179 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6180 LOG_API(i_isolate, "Map::New");
6181 ENTER_V8(i_isolate);
6182 i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
6183 return Utils::ToLocal(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006184}
6185
6186
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006187size_t v8::Map::Size() const {
6188 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
6189 return i::OrderedHashMap::cast(obj->table())->NumberOfElements();
6190}
6191
6192
6193void Map::Clear() {
6194 auto self = Utils::OpenHandle(this);
6195 i::Isolate* isolate = self->GetIsolate();
6196 LOG_API(isolate, "Map::Clear");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006197 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006198 i::JSMap::Clear(self);
6199}
6200
6201
6202MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
6203 PREPARE_FOR_EXECUTION(context, "Map::Get", Value);
6204 auto self = Utils::OpenHandle(this);
6205 Local<Value> result;
6206 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6207 has_pending_exception =
6208 !ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
6209 arraysize(argv), argv),
6210 &result);
6211 RETURN_ON_FAILED_EXECUTION(Value);
6212 RETURN_ESCAPED(result);
6213}
6214
6215
6216MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
6217 Local<Value> value) {
6218 PREPARE_FOR_EXECUTION(context, "Map::Set", Map);
6219 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006220 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006221 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
6222 Utils::OpenHandle(*value)};
6223 has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self,
6224 arraysize(argv), argv)
6225 .ToHandle(&result);
6226 RETURN_ON_FAILED_EXECUTION(Map);
6227 RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
6228}
6229
6230
6231Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
6232 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Has", bool);
6233 auto self = Utils::OpenHandle(this);
6234 i::Handle<i::Object> result;
6235 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6236 has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self,
6237 arraysize(argv), argv)
6238 .ToHandle(&result);
6239 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6240 return Just(result->IsTrue());
6241}
6242
6243
6244Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
6245 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Delete", bool);
6246 auto self = Utils::OpenHandle(this);
6247 i::Handle<i::Object> result;
6248 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6249 has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(),
6250 self, arraysize(argv), argv)
6251 .ToHandle(&result);
6252 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6253 return Just(result->IsTrue());
6254}
6255
6256
6257Local<Array> Map::AsArray() const {
6258 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
6259 i::Isolate* isolate = obj->GetIsolate();
6260 i::Factory* factory = isolate->factory();
6261 LOG_API(isolate, "Map::AsArray");
6262 ENTER_V8(isolate);
6263 i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(obj->table()));
6264 int size = table->NumberOfElements();
6265 int length = size * 2;
6266 i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
6267 for (int i = 0; i < size; ++i) {
6268 if (table->KeyAt(i)->IsTheHole()) continue;
6269 result->set(i * 2, table->KeyAt(i));
6270 result->set(i * 2 + 1, table->ValueAt(i));
6271 }
6272 i::Handle<i::JSArray> result_array =
6273 factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
6274 return Utils::ToLocal(result_array);
6275}
6276
6277
6278Local<v8::Set> v8::Set::New(Isolate* isolate) {
6279 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6280 LOG_API(i_isolate, "Set::New");
6281 ENTER_V8(i_isolate);
6282 i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
6283 return Utils::ToLocal(obj);
6284}
6285
6286
6287size_t v8::Set::Size() const {
6288 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
6289 return i::OrderedHashSet::cast(obj->table())->NumberOfElements();
6290}
6291
6292
6293void Set::Clear() {
6294 auto self = Utils::OpenHandle(this);
6295 i::Isolate* isolate = self->GetIsolate();
6296 LOG_API(isolate, "Set::Clear");
6297 ENTER_V8(isolate);
6298 i::JSSet::Clear(self);
6299}
6300
6301
6302MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
6303 PREPARE_FOR_EXECUTION(context, "Set::Add", Set);
6304 auto self = Utils::OpenHandle(this);
6305 i::Handle<i::Object> result;
6306 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6307 has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self,
6308 arraysize(argv), argv)
6309 .ToHandle(&result);
6310 RETURN_ON_FAILED_EXECUTION(Set);
6311 RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
6312}
6313
6314
6315Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
6316 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Has", bool);
6317 auto self = Utils::OpenHandle(this);
6318 i::Handle<i::Object> result;
6319 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6320 has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self,
6321 arraysize(argv), argv)
6322 .ToHandle(&result);
6323 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6324 return Just(result->IsTrue());
6325}
6326
6327
6328Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
6329 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Delete", bool);
6330 auto self = Utils::OpenHandle(this);
6331 i::Handle<i::Object> result;
6332 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6333 has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(),
6334 self, arraysize(argv), argv)
6335 .ToHandle(&result);
6336 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6337 return Just(result->IsTrue());
6338}
6339
6340
6341Local<Array> Set::AsArray() const {
6342 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
6343 i::Isolate* isolate = obj->GetIsolate();
6344 i::Factory* factory = isolate->factory();
6345 LOG_API(isolate, "Set::AsArray");
6346 ENTER_V8(isolate);
6347 i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(obj->table()));
6348 int length = table->NumberOfElements();
6349 i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
6350 for (int i = 0; i < length; ++i) {
6351 i::Object* key = table->KeyAt(i);
6352 if (!key->IsTheHole()) {
6353 result->set(i, key);
6354 }
6355 }
6356 i::Handle<i::JSArray> result_array =
6357 factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
6358 return Utils::ToLocal(result_array);
6359}
6360
6361
6362MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
6363 PREPARE_FOR_EXECUTION(context, "Promise::Resolver::New", Resolver);
6364 i::Handle<i::Object> result;
6365 has_pending_exception =
6366 !i::Execution::Call(isolate, isolate->promise_create(),
6367 isolate->factory()->undefined_value(), 0, NULL)
6368 .ToHandle(&result);
6369 RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
6370 RETURN_ESCAPED(Local<Promise::Resolver>::Cast(Utils::ToLocal(result)));
6371}
6372
6373
6374Local<Promise::Resolver> Promise::Resolver::New(Isolate* isolate) {
6375 RETURN_TO_LOCAL_UNCHECKED(New(isolate->GetCurrentContext()),
6376 Promise::Resolver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006377}
6378
6379
6380Local<Promise> Promise::Resolver::GetPromise() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006381 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006382 return Local<Promise>::Cast(Utils::ToLocal(promise));
6383}
6384
6385
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006386Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
6387 Local<Value> value) {
6388 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
6389 auto self = Utils::OpenHandle(this);
6390 i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
6391 has_pending_exception =
6392 i::Execution::Call(isolate, isolate->promise_resolve(),
6393 isolate->factory()->undefined_value(), arraysize(argv),
6394 argv)
6395 .is_null();
6396 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6397 return Just(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006398}
6399
6400
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006401void Promise::Resolver::Resolve(Local<Value> value) {
6402 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6403 USE(Resolve(context, value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006404}
6405
6406
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006407Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
6408 Local<Value> value) {
6409 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
6410 auto self = Utils::OpenHandle(this);
6411 i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
6412 has_pending_exception =
6413 i::Execution::Call(isolate, isolate->promise_reject(),
6414 isolate->factory()->undefined_value(), arraysize(argv),
6415 argv)
6416 .is_null();
6417 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6418 return Just(true);
6419}
6420
6421
6422void Promise::Resolver::Reject(Local<Value> value) {
6423 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6424 USE(Reject(context, value));
6425}
6426
6427
6428namespace {
6429
6430MaybeLocal<Promise> DoChain(Value* value, Local<Context> context,
6431 Local<Function> handler) {
6432 PREPARE_FOR_EXECUTION(context, "Promise::Chain", Promise);
6433 auto self = Utils::OpenHandle(value);
6434 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
6435 i::Handle<i::Object> result;
6436 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_chain(),
6437 self, arraysize(argv), argv)
6438 .ToHandle(&result);
6439 RETURN_ON_FAILED_EXECUTION(Promise);
6440 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
6441}
6442
6443} // namespace
6444
6445
6446MaybeLocal<Promise> Promise::Chain(Local<Context> context,
6447 Local<Function> handler) {
6448 return DoChain(this, context, handler);
6449}
6450
6451
6452Local<Promise> Promise::Chain(Local<Function> handler) {
6453 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6454 RETURN_TO_LOCAL_UNCHECKED(DoChain(this, context, handler), Promise);
6455}
6456
6457
6458MaybeLocal<Promise> Promise::Catch(Local<Context> context,
6459 Local<Function> handler) {
6460 PREPARE_FOR_EXECUTION(context, "Promise::Catch", Promise);
6461 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006462 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
6463 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006464 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(),
6465 self, arraysize(argv), argv)
6466 .ToHandle(&result);
6467 RETURN_ON_FAILED_EXECUTION(Promise);
6468 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006469}
6470
6471
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006472Local<Promise> Promise::Catch(Local<Function> handler) {
6473 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6474 RETURN_TO_LOCAL_UNCHECKED(Catch(context, handler), Promise);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006475}
6476
6477
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006478MaybeLocal<Promise> Promise::Then(Local<Context> context,
6479 Local<Function> handler) {
6480 PREPARE_FOR_EXECUTION(context, "Promise::Then", Promise);
6481 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006482 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
6483 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006484 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
6485 self, arraysize(argv), argv)
6486 .ToHandle(&result);
6487 RETURN_ON_FAILED_EXECUTION(Promise);
6488 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
6489}
6490
6491
6492Local<Promise> Promise::Then(Local<Function> handler) {
6493 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6494 RETURN_TO_LOCAL_UNCHECKED(Then(context, handler), Promise);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006495}
6496
6497
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006498bool Promise::HasHandler() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006499 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006500 i::Isolate* isolate = promise->GetIsolate();
6501 LOG_API(isolate, "Promise::HasRejectHandler");
6502 ENTER_V8(isolate);
6503 i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006504 return i::JSReceiver::GetDataProperty(promise, key)->IsTrue();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006505}
6506
6507
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006508Local<Object> Proxy::GetTarget() {
6509 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6510 i::Handle<i::JSReceiver> target(self->target());
6511 return Utils::ToLocal(target);
6512}
6513
6514
6515Local<Value> Proxy::GetHandler() {
6516 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6517 i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
6518 return Utils::ToLocal(handler);
6519}
6520
6521
6522bool Proxy::IsRevoked() {
6523 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6524 return self->IsRevoked();
6525}
6526
6527
6528void Proxy::Revoke() {
6529 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6530 i::JSProxy::Revoke(self);
6531}
6532
6533
6534MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
6535 Local<Object> local_handler) {
6536 PREPARE_FOR_EXECUTION(context, "Proxy::New", Proxy);
6537 i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
6538 i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
6539 Local<Proxy> result;
6540 has_pending_exception =
6541 !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
6542 RETURN_ON_FAILED_EXECUTION(Proxy);
6543 RETURN_ESCAPED(result);
6544}
6545
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006546bool v8::ArrayBuffer::IsExternal() const {
6547 return Utils::OpenHandle(this)->is_external();
6548}
6549
6550
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006551bool v8::ArrayBuffer::IsNeuterable() const {
6552 return Utils::OpenHandle(this)->is_neuterable();
6553}
6554
6555
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006556v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006557 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6558 i::Isolate* isolate = self->GetIsolate();
6559 Utils::ApiCheck(!self->is_external(), "v8::ArrayBuffer::Externalize",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006560 "ArrayBuffer already externalized");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006561 self->set_is_external(true);
6562 isolate->heap()->UnregisterArrayBuffer(*self);
6563
6564 return GetContents();
6565}
6566
6567
6568v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
6569 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6570 size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006571 Contents contents;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006572 contents.data_ = self->backing_store();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006573 contents.byte_length_ = byte_length;
6574 return contents;
6575}
6576
6577
6578void v8::ArrayBuffer::Neuter() {
6579 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6580 i::Isolate* isolate = obj->GetIsolate();
6581 Utils::ApiCheck(obj->is_external(),
6582 "v8::ArrayBuffer::Neuter",
6583 "Only externalized ArrayBuffers can be neutered");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006584 Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
6585 "Only neuterable ArrayBuffers can be neutered");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006586 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
6587 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006588 obj->Neuter();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006589}
6590
6591
6592size_t v8::ArrayBuffer::ByteLength() const {
6593 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6594 return static_cast<size_t>(obj->byte_length()->Number());
6595}
6596
6597
6598Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
6599 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6600 LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
6601 ENTER_V8(i_isolate);
6602 i::Handle<i::JSArrayBuffer> obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006603 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
6604 i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006605 return Utils::ToLocal(obj);
6606}
6607
6608
6609Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006610 size_t byte_length,
6611 ArrayBufferCreationMode mode) {
6612 // Embedders must guarantee that the external backing store is valid.
6613 CHECK(byte_length == 0 || data != NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006614 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6615 LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
6616 ENTER_V8(i_isolate);
6617 i::Handle<i::JSArrayBuffer> obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006618 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
6619 i::JSArrayBuffer::Setup(obj, i_isolate,
6620 mode == ArrayBufferCreationMode::kExternalized, data,
6621 byte_length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006622 return Utils::ToLocal(obj);
6623}
6624
6625
6626Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
6627 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6628 i::Handle<i::JSArrayBuffer> buffer;
6629 if (obj->IsJSDataView()) {
6630 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj));
6631 DCHECK(data_view->buffer()->IsJSArrayBuffer());
6632 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()));
6633 } else {
6634 DCHECK(obj->IsJSTypedArray());
6635 buffer = i::JSTypedArray::cast(*obj)->GetBuffer();
6636 }
6637 return Utils::ToLocal(buffer);
6638}
6639
6640
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006641size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
6642 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
6643 i::Isolate* isolate = self->GetIsolate();
6644 size_t byte_offset = i::NumberToSize(isolate, self->byte_offset());
6645 size_t bytes_to_copy =
6646 i::Min(byte_length, i::NumberToSize(isolate, self->byte_length()));
6647 if (bytes_to_copy) {
6648 i::DisallowHeapAllocation no_gc;
6649 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
6650 const char* source = reinterpret_cast<char*>(buffer->backing_store());
6651 if (source == nullptr) {
6652 DCHECK(self->IsJSTypedArray());
6653 i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self));
6654 i::Handle<i::FixedTypedArrayBase> fixed_array(
6655 i::FixedTypedArrayBase::cast(typed_array->elements()));
6656 source = reinterpret_cast<char*>(fixed_array->DataPtr());
6657 }
6658 memcpy(dest, source + byte_offset, bytes_to_copy);
6659 }
6660 return bytes_to_copy;
6661}
6662
6663
6664bool v8::ArrayBufferView::HasBuffer() const {
6665 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
6666 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
6667 return buffer->backing_store() != nullptr;
6668}
6669
6670
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006671size_t v8::ArrayBufferView::ByteOffset() {
6672 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6673 return static_cast<size_t>(obj->byte_offset()->Number());
6674}
6675
6676
6677size_t v8::ArrayBufferView::ByteLength() {
6678 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6679 return static_cast<size_t>(obj->byte_length()->Number());
6680}
6681
6682
6683size_t v8::TypedArray::Length() {
6684 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006685 return static_cast<size_t>(obj->length_value());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006686}
6687
6688
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006689#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
6690 Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
6691 size_t byte_offset, size_t length) { \
6692 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
6693 LOG_API(isolate, \
6694 "v8::" #Type "Array::New(Local<ArrayBuffer>, size_t, size_t)"); \
6695 ENTER_V8(isolate); \
6696 if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
6697 "v8::" #Type \
6698 "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
6699 "length exceeds max allowed value")) { \
6700 return Local<Type##Array>(); \
6701 } \
6702 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
6703 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
6704 i::kExternal##Type##Array, buffer, byte_offset, length); \
6705 return Utils::ToLocal##Type##Array(obj); \
6706 } \
6707 Local<Type##Array> Type##Array::New( \
6708 Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
6709 size_t length) { \
6710 CHECK(i::FLAG_harmony_sharedarraybuffer); \
6711 i::Isolate* isolate = \
6712 Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
6713 LOG_API(isolate, "v8::" #Type \
6714 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)"); \
6715 ENTER_V8(isolate); \
6716 if (!Utils::ApiCheck( \
6717 length <= static_cast<size_t>(i::Smi::kMaxValue), \
6718 "v8::" #Type \
6719 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
6720 "length exceeds max allowed value")) { \
6721 return Local<Type##Array>(); \
6722 } \
6723 i::Handle<i::JSArrayBuffer> buffer = \
6724 Utils::OpenHandle(*shared_array_buffer); \
6725 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
6726 i::kExternal##Type##Array, buffer, byte_offset, length); \
6727 return Utils::ToLocal##Type##Array(obj); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006728 }
6729
6730
6731TYPED_ARRAYS(TYPED_ARRAY_NEW)
6732#undef TYPED_ARRAY_NEW
6733
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006734Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006735 size_t byte_offset, size_t byte_length) {
6736 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6737 i::Isolate* isolate = buffer->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006738 LOG_API(isolate, "v8::DataView::New(Local<ArrayBuffer>, size_t, size_t)");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006739 ENTER_V8(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006740 i::Handle<i::JSDataView> obj =
6741 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006742 return Utils::ToLocal(obj);
6743}
6744
6745
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006746Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
6747 size_t byte_offset, size_t byte_length) {
6748 CHECK(i::FLAG_harmony_sharedarraybuffer);
6749 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
6750 i::Isolate* isolate = buffer->GetIsolate();
6751 LOG_API(isolate,
6752 "v8::DataView::New(Local<SharedArrayBuffer>, size_t, size_t)");
6753 ENTER_V8(isolate);
6754 i::Handle<i::JSDataView> obj =
6755 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
6756 return Utils::ToLocal(obj);
6757}
6758
6759
6760bool v8::SharedArrayBuffer::IsExternal() const {
6761 return Utils::OpenHandle(this)->is_external();
6762}
6763
6764
6765v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
6766 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6767 i::Isolate* isolate = self->GetIsolate();
6768 Utils::ApiCheck(!self->is_external(), "v8::SharedArrayBuffer::Externalize",
6769 "SharedArrayBuffer already externalized");
6770 self->set_is_external(true);
6771 isolate->heap()->UnregisterArrayBuffer(*self);
6772 return GetContents();
6773}
6774
6775
6776v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() {
6777 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6778 size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
6779 Contents contents;
6780 contents.data_ = self->backing_store();
6781 contents.byte_length_ = byte_length;
6782 return contents;
6783}
6784
6785
6786size_t v8::SharedArrayBuffer::ByteLength() const {
6787 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6788 return static_cast<size_t>(obj->byte_length()->Number());
6789}
6790
6791
6792Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
6793 size_t byte_length) {
6794 CHECK(i::FLAG_harmony_sharedarraybuffer);
6795 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6796 LOG_API(i_isolate, "v8::SharedArrayBuffer::New(size_t)");
6797 ENTER_V8(i_isolate);
6798 i::Handle<i::JSArrayBuffer> obj =
6799 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
6800 i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length, true,
6801 i::SharedFlag::kShared);
6802 return Utils::ToLocalShared(obj);
6803}
6804
6805
6806Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
6807 Isolate* isolate, void* data, size_t byte_length,
6808 ArrayBufferCreationMode mode) {
6809 CHECK(i::FLAG_harmony_sharedarraybuffer);
6810 // Embedders must guarantee that the external backing store is valid.
6811 CHECK(byte_length == 0 || data != NULL);
6812 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6813 LOG_API(i_isolate, "v8::SharedArrayBuffer::New(void*, size_t)");
6814 ENTER_V8(i_isolate);
6815 i::Handle<i::JSArrayBuffer> obj =
6816 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
6817 i::JSArrayBuffer::Setup(obj, i_isolate,
6818 mode == ArrayBufferCreationMode::kExternalized, data,
6819 byte_length, i::SharedFlag::kShared);
6820 return Utils::ToLocalShared(obj);
6821}
6822
6823
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006824Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
6825 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6826 LOG_API(i_isolate, "Symbol::New()");
6827 ENTER_V8(i_isolate);
6828 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6829 if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
Steve Blocka7e24c12009-10-30 11:49:00 +00006830 return Utils::ToLocal(result);
6831}
6832
6833
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006834static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
6835 i::Handle<i::String> name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006836 i::Handle<i::String> part,
6837 bool private_symbol) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006838 i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
6839 i::Handle<i::JSObject> symbols =
6840 i::Handle<i::JSObject>::cast(
6841 i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6842 i::Handle<i::Object> symbol =
6843 i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
6844 if (!symbol->IsSymbol()) {
6845 DCHECK(symbol->IsUndefined());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006846 if (private_symbol)
6847 symbol = isolate->factory()->NewPrivateSymbol();
6848 else
6849 symbol = isolate->factory()->NewSymbol();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006850 i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
6851 i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert();
Steve Blockd0582a62009-12-15 09:54:21 +00006852 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006853 return i::Handle<i::Symbol>::cast(symbol);
6854}
6855
6856
6857Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
6858 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6859 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6860 i::Handle<i::String> part = i_isolate->factory()->for_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006861 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006862}
6863
6864
6865Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
6866 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6867 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6868 i::Handle<i::String> part = i_isolate->factory()->for_api_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006869 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006870}
6871
6872
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006873Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006874 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6875 return Utils::ToLocal(i_isolate->factory()->iterator_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006876}
6877
6878
6879Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006880 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6881 return Utils::ToLocal(i_isolate->factory()->unscopables_symbol());
6882}
6883
6884
6885Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) {
6886 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6887 return Utils::ToLocal(i_isolate->factory()->to_string_tag_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006888}
6889
6890
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006891Local<Symbol> v8::Symbol::GetIsConcatSpreadable(Isolate* isolate) {
6892 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6893 return Utils::ToLocal(i_isolate->factory()->is_concat_spreadable_symbol());
6894}
6895
6896
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006897Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
6898 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6899 LOG_API(i_isolate, "Private::New()");
6900 ENTER_V8(i_isolate);
6901 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
6902 if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
6903 Local<Symbol> result = Utils::ToLocal(symbol);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006904 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006905}
6906
6907
6908Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
6909 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6910 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006911 i::Handle<i::String> part = i_isolate->factory()->private_api_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006912 Local<Symbol> result =
6913 Utils::ToLocal(SymbolFor(i_isolate, i_name, part, true));
6914 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006915}
6916
6917
6918Local<Number> v8::Number::New(Isolate* isolate, double value) {
6919 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006920 if (std::isnan(value)) {
6921 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006922 value = std::numeric_limits<double>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006923 }
6924 ENTER_V8(internal_isolate);
6925 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006926 return Utils::NumberToLocal(result);
6927}
6928
6929
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006930Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
6931 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006932 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01006933 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006934 internal_isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00006935 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006936 ENTER_V8(internal_isolate);
6937 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00006938 return Utils::IntegerToLocal(result);
6939}
6940
6941
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006942Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
6943 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00006944 bool fits_into_int32_t = (value & (1 << 31)) == 0;
6945 if (fits_into_int32_t) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006946 return Integer::New(isolate, static_cast<int32_t>(value));
Steve Block3ce2e202009-11-05 08:53:23 +00006947 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006948 ENTER_V8(internal_isolate);
6949 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00006950 return Utils::IntegerToLocal(result);
6951}
6952
6953
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006954void Isolate::ReportExternalAllocationLimitReached() {
6955 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
6956 if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
6957 heap->ReportExternalMemoryPressure(
6958 "external memory allocation limit reached.");
Steve Blocka7e24c12009-10-30 11:49:00 +00006959}
6960
6961
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006962HeapProfiler* Isolate::GetHeapProfiler() {
6963 i::HeapProfiler* heap_profiler =
6964 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
6965 return reinterpret_cast<HeapProfiler*>(heap_profiler);
Steve Blocka7e24c12009-10-30 11:49:00 +00006966}
6967
6968
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006969CpuProfiler* Isolate::GetCpuProfiler() {
6970 i::CpuProfiler* cpu_profiler =
6971 reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
6972 return reinterpret_cast<CpuProfiler*>(cpu_profiler);
6973}
6974
6975
6976bool Isolate::InContext() {
6977 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6978 return isolate->context() != NULL;
6979}
6980
6981
6982v8::Local<v8::Context> Isolate::GetCurrentContext() {
6983 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6984 i::Context* context = isolate->context();
6985 if (context == NULL) return Local<Context>();
6986 i::Context* native_context = context->native_context();
6987 if (native_context == NULL) return Local<Context>();
6988 return Utils::ToLocal(i::Handle<i::Context>(native_context));
6989}
6990
6991
6992v8::Local<v8::Context> Isolate::GetCallingContext() {
6993 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
6994 i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
6995 if (calling.is_null()) return Local<Context>();
6996 return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
6997}
6998
6999
7000v8::Local<v8::Context> Isolate::GetEnteredContext() {
7001 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7002 i::Handle<i::Object> last =
7003 isolate->handle_scope_implementer()->LastEnteredContext();
7004 if (last.is_null()) return Local<Context>();
7005 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
7006}
7007
7008
7009v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
7010 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7011 ENTER_V8(isolate);
7012 // If we're passed an empty handle, we throw an undefined exception
7013 // to deal more gracefully with out of memory situations.
7014 if (value.IsEmpty()) {
7015 isolate->ScheduleThrow(isolate->heap()->undefined_value());
7016 } else {
7017 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Block44f0eee2011-05-26 01:26:41 +01007018 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007019 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00007020}
7021
7022
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007023void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
7024 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
7025 internal_isolate->global_handles()->SetObjectGroupId(
7026 v8::internal::Handle<v8::internal::Object>(object).location(),
7027 id);
Steve Blocka7e24c12009-10-30 11:49:00 +00007028}
7029
7030
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007031void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
7032 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
7033 internal_isolate->global_handles()->SetReferenceFromGroup(
7034 id,
7035 v8::internal::Handle<v8::internal::Object>(object).location());
7036}
7037
7038
7039void Isolate::SetReference(internal::Object** parent,
7040 internal::Object** child) {
7041 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
7042 i::Object** parent_location =
7043 v8::internal::Handle<v8::internal::Object>(parent).location();
7044 internal_isolate->global_handles()->SetReference(
7045 reinterpret_cast<i::HeapObject**>(parent_location),
7046 v8::internal::Handle<v8::internal::Object>(child).location());
7047}
7048
7049
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007050void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007051 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7052 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
7053}
7054
7055
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007056void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007057 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7058 isolate->heap()->RemoveGCPrologueCallback(callback);
7059}
7060
7061
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007062void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007063 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7064 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
7065}
7066
7067
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007068void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007069 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7070 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00007071}
7072
7073
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007074void V8::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01007075 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007076 isolate->heap()->AddGCPrologueCallback(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007077 reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
Steve Block6ded16b2010-05-10 14:33:55 +01007078}
7079
7080
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007081void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01007082 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007083 isolate->heap()->AddGCEpilogueCallback(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007084 reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
Steve Block6ded16b2010-05-10 14:33:55 +01007085}
7086
7087
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007088void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
7089 ObjectSpace space,
7090 AllocationAction action) {
7091 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01007092 isolate->memory_allocator()->AddMemoryAllocationCallback(
7093 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01007094}
7095
7096
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007097void Isolate::RemoveMemoryAllocationCallback(
7098 MemoryAllocationCallback callback) {
7099 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01007100 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
7101 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01007102}
7103
7104
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007105void Isolate::TerminateExecution() {
7106 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7107 isolate->stack_guard()->RequestTerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00007108}
7109
7110
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007111bool Isolate::IsExecutionTerminating() {
7112 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7113 return IsExecutionTerminatingCheck(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01007114}
7115
7116
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007117void Isolate::CancelTerminateExecution() {
7118 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7119 isolate->stack_guard()->ClearTerminateExecution();
7120 isolate->CancelTerminateExecution();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007121}
7122
7123
7124void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007125 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7126 isolate->RequestInterrupt(callback, data);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007127}
7128
7129
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007130void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
7131 CHECK(i::FLAG_expose_gc);
7132 if (type == kMinorGarbageCollection) {
7133 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
7134 i::NEW_SPACE, "Isolate::RequestGarbageCollection",
7135 kGCCallbackFlagForced);
7136 } else {
7137 DCHECK_EQ(kFullGarbageCollection, type);
7138 reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
7139 i::Heap::kAbortIncrementalMarkingMask,
7140 "Isolate::RequestGarbageCollection", kGCCallbackFlagForced);
7141 }
7142}
7143
7144
Steve Block44f0eee2011-05-26 01:26:41 +01007145Isolate* Isolate::GetCurrent() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007146 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01007147 return reinterpret_cast<Isolate*>(isolate);
7148}
7149
7150
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007151Isolate* Isolate::New(const Isolate::CreateParams& params) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007152 i::Isolate* isolate = new i::Isolate(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007153 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007154 CHECK(params.array_buffer_allocator != NULL);
7155 isolate->set_array_buffer_allocator(params.array_buffer_allocator);
7156 if (params.snapshot_blob != NULL) {
7157 isolate->set_snapshot_blob(params.snapshot_blob);
7158 } else {
7159 isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
7160 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007161 if (params.entry_hook) {
7162 isolate->set_function_entry_hook(params.entry_hook);
7163 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01007164 auto code_event_handler = params.code_event_handler;
7165#ifdef ENABLE_GDB_JIT_INTERFACE
7166 if (code_event_handler == nullptr && i::FLAG_gdbjit) {
7167 code_event_handler = i::GDBJITInterface::EventHandler;
7168 }
7169#endif // ENABLE_GDB_JIT_INTERFACE
7170 if (code_event_handler) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007171 isolate->InitializeLoggingAndCounters();
7172 isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007173 code_event_handler);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007174 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007175 if (params.counter_lookup_callback) {
7176 v8_isolate->SetCounterFunction(params.counter_lookup_callback);
7177 }
7178
7179 if (params.create_histogram_callback) {
7180 v8_isolate->SetCreateHistogramFunction(params.create_histogram_callback);
7181 }
7182
7183 if (params.add_histogram_sample_callback) {
7184 v8_isolate->SetAddHistogramSampleFunction(
7185 params.add_histogram_sample_callback);
7186 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007187 SetResourceConstraints(isolate, params.constraints);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007188 // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
7189 Isolate::Scope isolate_scope(v8_isolate);
7190 if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
7191 // If the isolate has a function entry hook, it needs to re-build all its
7192 // code stubs with entry hooks embedded, so don't deserialize a snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007193 if (i::Snapshot::EmbedsScript(isolate)) {
7194 // If the snapshot embeds a script, we cannot initialize the isolate
7195 // without the snapshot as a fallback. This is unlikely to happen though.
7196 V8_Fatal(__FILE__, __LINE__,
7197 "Initializing isolate from custom startup snapshot failed");
7198 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007199 isolate->Init(NULL);
7200 }
7201 return v8_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +01007202}
7203
7204
7205void Isolate::Dispose() {
7206 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007207 if (!Utils::ApiCheck(!isolate->IsInUse(),
7208 "v8::Isolate::Dispose()",
7209 "Disposing the isolate that is entered by a thread.")) {
Steve Block44f0eee2011-05-26 01:26:41 +01007210 return;
Steve Block6ded16b2010-05-10 14:33:55 +01007211 }
Steve Block44f0eee2011-05-26 01:26:41 +01007212 isolate->TearDown();
7213}
7214
7215
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007216void Isolate::DiscardThreadSpecificMetadata() {
7217 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7218 isolate->DiscardPerThreadDataForThisThread();
7219}
7220
7221
Steve Block44f0eee2011-05-26 01:26:41 +01007222void Isolate::Enter() {
7223 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7224 isolate->Enter();
7225}
7226
7227
7228void Isolate::Exit() {
7229 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7230 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01007231}
7232
7233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007234void Isolate::SetAbortOnUncaughtExceptionCallback(
7235 AbortOnUncaughtExceptionCallback callback) {
7236 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7237 isolate->SetAbortOnUncaughtExceptionCallback(callback);
7238}
7239
7240
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007241Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
7242 Isolate* isolate,
7243 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
7244 : on_failure_(on_failure) {
7245 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7246 if (on_failure_ == CRASH_ON_FAILURE) {
7247 internal_ = reinterpret_cast<void*>(
7248 new i::DisallowJavascriptExecution(i_isolate));
7249 } else {
7250 DCHECK_EQ(THROW_ON_FAILURE, on_failure);
7251 internal_ = reinterpret_cast<void*>(
7252 new i::ThrowOnJavascriptExecution(i_isolate));
7253 }
Ben Murdoch257744e2011-11-30 15:57:28 +00007254}
7255
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007256
7257Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
7258 if (on_failure_ == CRASH_ON_FAILURE) {
7259 delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
7260 } else {
7261 delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
7262 }
7263}
7264
7265
7266Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
7267 Isolate* isolate) {
7268 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7269 internal_assert_ = reinterpret_cast<void*>(
7270 new i::AllowJavascriptExecution(i_isolate));
7271 internal_throws_ = reinterpret_cast<void*>(
7272 new i::NoThrowOnJavascriptExecution(i_isolate));
7273}
7274
7275
7276Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
7277 delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
7278 delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
7279}
7280
7281
7282Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
7283 Isolate* isolate)
7284 : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
7285 isolate_->handle_scope_implementer()->IncrementCallDepth();
7286}
7287
7288
7289Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
7290 isolate_->handle_scope_implementer()->DecrementCallDepth();
7291}
7292
7293
7294void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
Ben Murdoch257744e2011-11-30 15:57:28 +00007295 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007296 i::Heap* heap = isolate->heap();
7297 heap_statistics->total_heap_size_ = heap->CommittedMemory();
7298 heap_statistics->total_heap_size_executable_ =
7299 heap->CommittedMemoryExecutable();
7300 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007301 heap_statistics->total_available_size_ = heap->Available();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007302 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
7303 heap_statistics->heap_size_limit_ = heap->MaxReserved();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007304 heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
7305}
7306
7307
7308size_t Isolate::NumberOfHeapSpaces() {
7309 return i::LAST_SPACE - i::FIRST_SPACE + 1;
7310}
7311
7312
7313bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
7314 size_t index) {
7315 if (!space_statistics) return false;
7316 if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
7317 return false;
7318
7319 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7320 i::Heap* heap = isolate->heap();
7321 i::Space* space = heap->space(static_cast<int>(index));
7322
7323 space_statistics->space_name_ = heap->GetSpaceName(static_cast<int>(index));
7324 space_statistics->space_size_ = space->CommittedMemory();
7325 space_statistics->space_used_size_ = space->SizeOfObjects();
7326 space_statistics->space_available_size_ = space->Available();
7327 space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
7328 return true;
7329}
7330
7331
7332size_t Isolate::NumberOfTrackedHeapObjectTypes() {
7333 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7334 i::Heap* heap = isolate->heap();
7335 return heap->NumberOfTrackedHeapObjectTypes();
7336}
7337
7338
7339bool Isolate::GetHeapObjectStatisticsAtLastGC(
7340 HeapObjectStatistics* object_statistics, size_t type_index) {
7341 if (!object_statistics) return false;
7342 if (!i::FLAG_track_gc_object_stats) return false;
7343
7344 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7345 i::Heap* heap = isolate->heap();
7346 if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
7347
7348 const char* object_type;
7349 const char* object_sub_type;
7350 size_t object_count = heap->ObjectCountAtLastGC(type_index);
7351 size_t object_size = heap->ObjectSizeAtLastGC(type_index);
7352 if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
7353 // There should be no objects counted when the type is unknown.
7354 DCHECK_EQ(object_count, 0U);
7355 DCHECK_EQ(object_size, 0U);
7356 return false;
7357 }
7358
7359 object_statistics->object_type_ = object_type;
7360 object_statistics->object_sub_type_ = object_sub_type;
7361 object_statistics->object_count_ = object_count;
7362 object_statistics->object_size_ = object_size;
7363 return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007364}
7365
7366
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007367void Isolate::GetStackSample(const RegisterState& state, void** frames,
7368 size_t frames_limit, SampleInfo* sample_info) {
7369 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7370 i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame,
7371 frames, frames_limit, sample_info);
7372}
7373
7374
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007375void Isolate::SetEventLogger(LogEventCallback that) {
7376 // Do not overwrite the event logger if we want to log explicitly.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007377 if (i::FLAG_log_internal_timer_events) return;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007378 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7379 isolate->set_event_logger(that);
7380}
7381
7382
Ben Murdoch097c5b22016-05-18 11:27:45 +01007383void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
7384 if (callback == NULL) return;
7385 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7386 isolate->AddBeforeCallEnteredCallback(callback);
7387}
7388
7389
7390void Isolate::RemoveBeforeCallEnteredCallback(
7391 BeforeCallEnteredCallback callback) {
7392 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7393 isolate->RemoveBeforeCallEnteredCallback(callback);
7394}
7395
7396
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007397void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
7398 if (callback == NULL) return;
7399 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7400 isolate->AddCallCompletedCallback(callback);
7401}
7402
7403
7404void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
7405 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7406 isolate->RemoveCallCompletedCallback(callback);
7407}
7408
7409
Ben Murdoch097c5b22016-05-18 11:27:45 +01007410void Isolate::AddCallCompletedCallback(
7411 DeprecatedCallCompletedCallback callback) {
7412 AddCallCompletedCallback(reinterpret_cast<CallCompletedCallback>(callback));
7413}
7414
7415
7416void Isolate::RemoveCallCompletedCallback(
7417 DeprecatedCallCompletedCallback callback) {
7418 RemoveCallCompletedCallback(
7419 reinterpret_cast<CallCompletedCallback>(callback));
7420}
7421
7422
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007423void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
7424 if (callback == NULL) return;
7425 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7426 isolate->SetPromiseRejectCallback(callback);
7427}
7428
7429
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007430void Isolate::RunMicrotasks() {
7431 reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
7432}
7433
7434
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007435void Isolate::EnqueueMicrotask(Local<Function> microtask) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007436 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7437 isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
7438}
7439
7440
7441void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
7442 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7443 i::HandleScope scope(isolate);
7444 i::Handle<i::CallHandlerInfo> callback_info =
7445 i::Handle<i::CallHandlerInfo>::cast(
7446 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE));
7447 SET_FIELD_WRAPPED(callback_info, set_callback, microtask);
7448 SET_FIELD_WRAPPED(callback_info, set_data, data);
7449 isolate->EnqueueMicrotask(callback_info);
7450}
7451
7452
7453void Isolate::SetAutorunMicrotasks(bool autorun) {
7454 reinterpret_cast<i::Isolate*>(this)->set_autorun_microtasks(autorun);
7455}
7456
7457
7458bool Isolate::WillAutorunMicrotasks() const {
7459 return reinterpret_cast<const i::Isolate*>(this)->autorun_microtasks();
7460}
7461
7462
7463void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
7464 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
7465}
7466
7467
7468void Isolate::SetCounterFunction(CounterLookupCallback callback) {
7469 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7470 isolate->stats_table()->SetCounterFunction(callback);
7471 isolate->InitializeLoggingAndCounters();
7472 isolate->counters()->ResetCounters();
7473}
7474
7475
7476void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
7477 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7478 isolate->stats_table()->SetCreateHistogramFunction(callback);
7479 isolate->InitializeLoggingAndCounters();
7480 isolate->counters()->ResetHistograms();
7481}
7482
7483
7484void Isolate::SetAddHistogramSampleFunction(
7485 AddHistogramSampleCallback callback) {
7486 reinterpret_cast<i::Isolate*>(this)
7487 ->stats_table()
7488 ->SetAddHistogramSampleFunction(callback);
7489}
7490
7491
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007492bool Isolate::IdleNotification(int idle_time_in_ms) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007493 // Returning true tells the caller that it need not
7494 // continue to call IdleNotification.
7495 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7496 if (!i::FLAG_use_idle_notification) return true;
7497 return isolate->heap()->IdleNotification(idle_time_in_ms);
7498}
7499
7500
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007501bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
7502 // Returning true tells the caller that it need not
7503 // continue to call IdleNotification.
7504 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7505 if (!i::FLAG_use_idle_notification) return true;
7506 return isolate->heap()->IdleNotification(deadline_in_seconds);
7507}
7508
7509
7510void Isolate::LowMemoryNotification() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007511 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7512 {
7513 i::HistogramTimerScope idle_notification_scope(
7514 isolate->counters()->gc_low_memory_notification());
Ben Murdoch097c5b22016-05-18 11:27:45 +01007515 TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007516 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
7517 }
7518}
7519
7520
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007521int Isolate::ContextDisposedNotification(bool dependant_context) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007522 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007523 return isolate->heap()->NotifyContextDisposed(dependant_context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007524}
7525
7526
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007527void Isolate::IsolateInForegroundNotification() {
7528 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7529 return isolate->heap()->SetOptimizeForLatency();
7530}
7531
7532
7533void Isolate::IsolateInBackgroundNotification() {
7534 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7535 return isolate->heap()->SetOptimizeForMemoryUsage();
7536}
7537
7538
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007539void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
7540 JitCodeEventHandler event_handler) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007541 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7542 // Ensure that logging is initialized for our isolate.
7543 isolate->InitializeLoggingAndCounters();
7544 isolate->logger()->SetCodeEventHandler(options, event_handler);
7545}
7546
7547
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007548void Isolate::SetStackLimit(uintptr_t stack_limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007549 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7550 CHECK(stack_limit);
7551 isolate->stack_guard()->SetStackLimit(stack_limit);
Ben Murdoch257744e2011-11-30 15:57:28 +00007552}
7553
7554
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007555void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
7556 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7557 if (isolate->code_range()->valid()) {
7558 *start = isolate->code_range()->start();
7559 *length_in_bytes = isolate->code_range()->size();
7560 } else {
7561 *start = NULL;
7562 *length_in_bytes = 0;
7563 }
7564}
7565
7566
7567void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
7568 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7569 isolate->set_exception_behavior(that);
7570}
7571
7572
7573void Isolate::SetAllowCodeGenerationFromStringsCallback(
7574 AllowCodeGenerationFromStringsCallback callback) {
7575 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7576 isolate->set_allow_code_gen_callback(callback);
7577}
7578
7579
7580bool Isolate::IsDead() {
7581 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7582 return isolate->IsDead();
7583}
7584
7585
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007586bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007587 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007588 ENTER_V8(isolate);
7589 i::HandleScope scope(isolate);
7590 NeanderArray listeners(isolate->factory()->message_listeners());
7591 NeanderObject obj(isolate, 2);
7592 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
7593 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
7594 : *Utils::OpenHandle(*data));
7595 listeners.add(isolate, obj.value());
7596 return true;
7597}
7598
7599
7600void Isolate::RemoveMessageListeners(MessageCallback that) {
7601 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007602 ENTER_V8(isolate);
7603 i::HandleScope scope(isolate);
7604 NeanderArray listeners(isolate->factory()->message_listeners());
7605 for (int i = 0; i < listeners.length(); i++) {
7606 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
7607
7608 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
7609 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
7610 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
7611 listeners.set(i, isolate->heap()->undefined_value());
7612 }
7613 }
7614}
7615
7616
7617void Isolate::SetFailedAccessCheckCallbackFunction(
7618 FailedAccessCheckCallback callback) {
7619 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7620 isolate->SetFailedAccessCheckCallback(callback);
7621}
7622
7623
7624void Isolate::SetCaptureStackTraceForUncaughtExceptions(
7625 bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
7626 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7627 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
7628 options);
7629}
7630
7631
7632void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
7633 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7634 isolate->heap()->VisitExternalResources(visitor);
7635}
7636
7637
7638class VisitorAdapter : public i::ObjectVisitor {
7639 public:
7640 explicit VisitorAdapter(PersistentHandleVisitor* visitor)
7641 : visitor_(visitor) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007642 void VisitPointers(i::Object** start, i::Object** end) override {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007643 UNREACHABLE();
7644 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007645 void VisitEmbedderReference(i::Object** p, uint16_t class_id) override {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007646 Value* value = ToApi<Value>(i::Handle<i::Object>(p));
7647 visitor_->VisitPersistentHandle(
7648 reinterpret_cast<Persistent<Value>*>(&value), class_id);
7649 }
7650
7651 private:
7652 PersistentHandleVisitor* visitor_;
7653};
7654
7655
7656void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
7657 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7658 i::DisallowHeapAllocation no_allocation;
7659 VisitorAdapter visitor_adapter(visitor);
7660 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
7661}
7662
7663
7664void Isolate::VisitHandlesForPartialDependence(
7665 PersistentHandleVisitor* visitor) {
7666 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7667 i::DisallowHeapAllocation no_allocation;
7668 VisitorAdapter visitor_adapter(visitor);
7669 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
7670 &visitor_adapter);
7671}
7672
7673
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007674void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
7675 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7676 i::DisallowHeapAllocation no_allocation;
7677 VisitorAdapter visitor_adapter(visitor);
7678 isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds(
7679 &visitor_adapter);
7680}
7681
7682
7683String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
Ben Murdoch257744e2011-11-30 15:57:28 +00007684 : str_(NULL), length_(0) {
Ben Murdoch257744e2011-11-30 15:57:28 +00007685 if (obj.IsEmpty()) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007686 i::Isolate* isolate = i::Isolate::Current();
7687 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01007688 ENTER_V8(isolate);
7689 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007690 Local<Context> context = v8_isolate->GetCurrentContext();
7691 TryCatch try_catch(v8_isolate);
7692 Local<String> str;
7693 if (!obj->ToString(context).ToLocal(&str)) return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007694 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007695 length_ = v8::Utf8Length(*i_str, isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00007696 str_ = i::NewArray<char>(length_ + 1);
7697 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00007698}
7699
7700
7701String::Utf8Value::~Utf8Value() {
7702 i::DeleteArray(str_);
7703}
7704
7705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007706String::Value::Value(v8::Local<v8::Value> obj) : str_(NULL), length_(0) {
Ben Murdoch257744e2011-11-30 15:57:28 +00007707 if (obj.IsEmpty()) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007708 i::Isolate* isolate = i::Isolate::Current();
7709 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01007710 ENTER_V8(isolate);
7711 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007712 Local<Context> context = v8_isolate->GetCurrentContext();
7713 TryCatch try_catch(v8_isolate);
7714 Local<String> str;
7715 if (!obj->ToString(context).ToLocal(&str)) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00007716 length_ = str->Length();
7717 str_ = i::NewArray<uint16_t>(length_ + 1);
7718 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00007719}
7720
7721
7722String::Value::~Value() {
7723 i::DeleteArray(str_);
7724}
7725
Steve Blocka7e24c12009-10-30 11:49:00 +00007726
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007727#define DEFINE_ERROR(NAME, name) \
7728 Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \
7729 i::Isolate* isolate = i::Isolate::Current(); \
7730 LOG_API(isolate, #NAME); \
7731 ENTER_V8(isolate); \
7732 i::Object* error; \
7733 { \
7734 i::HandleScope scope(isolate); \
7735 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
7736 i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
7737 error = *isolate->factory()->NewError(constructor, message); \
7738 } \
7739 i::Handle<i::Object> result(error, isolate); \
7740 return Utils::ToLocal(result); \
Steve Blocka7e24c12009-10-30 11:49:00 +00007741 }
Steve Blocka7e24c12009-10-30 11:49:00 +00007742
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007743DEFINE_ERROR(RangeError, range_error)
7744DEFINE_ERROR(ReferenceError, reference_error)
7745DEFINE_ERROR(SyntaxError, syntax_error)
7746DEFINE_ERROR(TypeError, type_error)
7747DEFINE_ERROR(Error, error)
Steve Blocka7e24c12009-10-30 11:49:00 +00007748
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007749#undef DEFINE_ERROR
Steve Blocka7e24c12009-10-30 11:49:00 +00007750
7751
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007752Local<Message> Exception::CreateMessage(Isolate* isolate,
7753 Local<Value> exception) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007754 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007755 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7756 ENTER_V8(i_isolate);
7757 i::HandleScope scope(i_isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007758 return Utils::MessageToLocal(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007759 scope.CloseAndEscape(i_isolate->CreateMessage(obj, NULL)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007760}
7761
7762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007763Local<Message> Exception::CreateMessage(Local<Value> exception) {
7764 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
7765 if (!obj->IsHeapObject()) return Local<Message>();
7766 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
7767 return CreateMessage(reinterpret_cast<Isolate*>(isolate), exception);
7768}
7769
7770
7771Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007772 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
7773 if (!obj->IsJSObject()) return Local<StackTrace>();
7774 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
7775 i::Isolate* isolate = js_obj->GetIsolate();
7776 ENTER_V8(isolate);
7777 return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
7778}
7779
7780
Steve Blocka7e24c12009-10-30 11:49:00 +00007781// --- D e b u g S u p p o r t ---
7782
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007783bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that,
7784 Local<Value> data) {
7785 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7786 ENTER_V8(i_isolate);
7787 i::HandleScope scope(i_isolate);
7788 i::Handle<i::Object> foreign = i_isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00007789 if (that != NULL) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007790 foreign = i_isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00007791 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007792 i_isolate->debug()->SetEventListener(foreign, Utils::OpenHandle(*data, true));
Steve Blocka7e24c12009-10-30 11:49:00 +00007793 return true;
7794}
7795
7796
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007797bool Debug::SetDebugEventListener(EventCallback that, Local<Value> data) {
7798 return SetDebugEventListener(
7799 reinterpret_cast<Isolate*>(i::Isolate::Current()), that, data);
7800}
7801
7802
Steve Block44f0eee2011-05-26 01:26:41 +01007803void Debug::DebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007804 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
Steve Blocka7e24c12009-10-30 11:49:00 +00007805}
7806
7807
Steve Block44f0eee2011-05-26 01:26:41 +01007808void Debug::CancelDebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007809 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7810 internal_isolate->stack_guard()->ClearDebugBreak();
Ben Murdochf87a2032010-10-22 12:50:53 +01007811}
7812
7813
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007814bool Debug::CheckDebugBreak(Isolate* isolate) {
7815 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7816 return internal_isolate->stack_guard()->CheckDebugBreak();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01007817}
7818
7819
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007820void Debug::SetMessageHandler(Isolate* isolate,
7821 v8::Debug::MessageHandler handler) {
7822 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7823 ENTER_V8(i_isolate);
7824 i_isolate->debug()->SetMessageHandler(handler);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007825}
7826
7827
7828void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007829 SetMessageHandler(reinterpret_cast<Isolate*>(i::Isolate::Current()), handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00007830}
7831
7832
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007833void Debug::SendCommand(Isolate* isolate,
7834 const uint16_t* command,
7835 int length,
7836 ClientData* client_data) {
7837 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7838 internal_isolate->debug()->EnqueueCommandMessage(
7839 i::Vector<const uint16_t>(command, length), client_data);
Steve Blockd0582a62009-12-15 09:54:21 +00007840}
7841
7842
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007843MaybeLocal<Value> Debug::Call(Local<Context> context,
7844 v8::Local<v8::Function> fun,
7845 v8::Local<v8::Value> data) {
7846 PREPARE_FOR_EXECUTION(context, "v8::Debug::Call()", Value);
7847 i::Handle<i::Object> data_obj;
Steve Blocka7e24c12009-10-30 11:49:00 +00007848 if (data.IsEmpty()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007849 data_obj = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00007850 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007851 data_obj = Utils::OpenHandle(*data);
Steve Blocka7e24c12009-10-30 11:49:00 +00007852 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007853 Local<Value> result;
7854 has_pending_exception =
7855 !ToLocal<Value>(isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj),
7856 &result);
7857 RETURN_ON_FAILED_EXECUTION(Value);
7858 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00007859}
7860
7861
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007862Local<Value> Debug::Call(v8::Local<v8::Function> fun,
7863 v8::Local<v8::Value> data) {
7864 auto context = ContextFromHeapObject(Utils::OpenHandle(*fun));
7865 RETURN_TO_LOCAL_UNCHECKED(Call(context, fun, data), Value);
7866}
7867
7868
7869MaybeLocal<Value> Debug::GetMirror(Local<Context> context,
7870 v8::Local<v8::Value> obj) {
7871 PREPARE_FOR_EXECUTION(context, "v8::Debug::GetMirror()", Value);
Steve Block44f0eee2011-05-26 01:26:41 +01007872 i::Debug* isolate_debug = isolate->debug();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007873 has_pending_exception = !isolate_debug->Load();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007874 RETURN_ON_FAILED_EXECUTION(Value);
7875 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
7876 auto name = isolate->factory()->NewStringFromStaticChars("MakeMirror");
7877 auto fun_obj = i::Object::GetProperty(debug, name).ToHandleChecked();
7878 auto v8_fun = Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(fun_obj));
7879 const int kArgc = 1;
7880 v8::Local<v8::Value> argv[kArgc] = {obj};
7881 Local<Value> result;
7882 has_pending_exception =
7883 !v8_fun->Call(context, Utils::ToLocal(debug), kArgc, argv)
7884 .ToLocal(&result);
7885 RETURN_ON_FAILED_EXECUTION(Value);
7886 RETURN_ESCAPED(result);
7887}
7888
7889
7890Local<Value> Debug::GetMirror(v8::Local<v8::Value> obj) {
7891 RETURN_TO_LOCAL_UNCHECKED(GetMirror(Local<Context>(), obj), Value);
7892}
7893
7894
7895void Debug::ProcessDebugMessages(Isolate* isolate) {
7896 reinterpret_cast<i::Isolate*>(isolate)->debug()->ProcessDebugMessages(true);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007897}
7898
7899
Leon Clarkee46be812010-01-19 14:06:41 +00007900void Debug::ProcessDebugMessages() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007901 ProcessDebugMessages(reinterpret_cast<Isolate*>(i::Isolate::Current()));
7902}
7903
7904
7905Local<Context> Debug::GetDebugContext(Isolate* isolate) {
7906 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7907 ENTER_V8(i_isolate);
7908 return Utils::ToLocal(i_isolate->debug()->GetDebugContext());
Leon Clarkee46be812010-01-19 14:06:41 +00007909}
7910
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007911
Steve Block6ded16b2010-05-10 14:33:55 +01007912Local<Context> Debug::GetDebugContext() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007913 return GetDebugContext(reinterpret_cast<Isolate*>(i::Isolate::Current()));
Steve Block6ded16b2010-05-10 14:33:55 +01007914}
7915
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007916
7917void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
7918 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
7919 internal_isolate->debug()->set_live_edit_enabled(enable);
7920}
Steve Blocka7e24c12009-10-30 11:49:00 +00007921
Steve Block6ded16b2010-05-10 14:33:55 +01007922
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007923MaybeLocal<Array> Debug::GetInternalProperties(Isolate* v8_isolate,
7924 Local<Value> value) {
7925 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
7926 ENTER_V8(isolate);
7927 i::Handle<i::Object> val = Utils::OpenHandle(*value);
7928 i::Handle<i::JSArray> result;
7929 if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result))
7930 return MaybeLocal<Array>();
7931 return Utils::ToLocal(result);
7932}
7933
7934
7935Local<String> CpuProfileNode::GetFunctionName() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007936 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007937 i::Isolate* isolate = node->isolate();
Steve Block6ded16b2010-05-10 14:33:55 +01007938 const i::CodeEntry* entry = node->entry();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007939 i::Handle<i::String> name =
7940 isolate->factory()->InternalizeUtf8String(entry->name());
Steve Block6ded16b2010-05-10 14:33:55 +01007941 if (!entry->has_name_prefix()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007942 return ToApiHandle<String>(name);
Steve Block6ded16b2010-05-10 14:33:55 +01007943 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007944 // We do not expect this to fail. Change this if it does.
7945 i::Handle<i::String> cons = isolate->factory()->NewConsString(
7946 isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
7947 name).ToHandleChecked();
7948 return ToApiHandle<String>(cons);
Steve Block6ded16b2010-05-10 14:33:55 +01007949 }
7950}
7951
7952
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007953int CpuProfileNode::GetScriptId() const {
7954 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7955 const i::CodeEntry* entry = node->entry();
7956 return entry->script_id();
7957}
7958
7959
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007960Local<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007961 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007962 i::Isolate* isolate = node->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007963 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
7964 node->entry()->resource_name()));
Steve Block6ded16b2010-05-10 14:33:55 +01007965}
7966
7967
7968int CpuProfileNode::GetLineNumber() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007969 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
7970}
7971
7972
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007973int CpuProfileNode::GetColumnNumber() const {
7974 return reinterpret_cast<const i::ProfileNode*>(this)->
7975 entry()->column_number();
Steve Block6ded16b2010-05-10 14:33:55 +01007976}
7977
7978
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007979unsigned int CpuProfileNode::GetHitLineCount() const {
7980 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7981 return node->GetHitLineCount();
7982}
7983
7984
7985bool CpuProfileNode::GetLineTicks(LineTick* entries,
7986 unsigned int length) const {
7987 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7988 return node->GetLineTicks(entries, length);
7989}
7990
7991
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007992const char* CpuProfileNode::GetBailoutReason() const {
7993 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
7994 return node->entry()->bailout_reason();
Steve Block6ded16b2010-05-10 14:33:55 +01007995}
7996
7997
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007998unsigned CpuProfileNode::GetHitCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01007999 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
8000}
8001
8002
8003unsigned CpuProfileNode::GetCallUid() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008004 return reinterpret_cast<const i::ProfileNode*>(this)->function_id();
Steve Block6ded16b2010-05-10 14:33:55 +01008005}
8006
8007
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008008unsigned CpuProfileNode::GetNodeId() const {
8009 return reinterpret_cast<const i::ProfileNode*>(this)->id();
8010}
8011
8012
Steve Block6ded16b2010-05-10 14:33:55 +01008013int CpuProfileNode::GetChildrenCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008014 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
8015}
8016
8017
8018const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block6ded16b2010-05-10 14:33:55 +01008019 const i::ProfileNode* child =
8020 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
8021 return reinterpret_cast<const CpuProfileNode*>(child);
8022}
8023
8024
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008025const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
8026 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
8027 return node->deopt_infos();
Steve Block6ded16b2010-05-10 14:33:55 +01008028}
8029
8030
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008031void CpuProfile::Delete() {
8032 i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
8033 i::Isolate* isolate = profile->top_down()->isolate();
8034 i::CpuProfiler* profiler = isolate->cpu_profiler();
8035 DCHECK(profiler != NULL);
8036 profiler->DeleteProfile(profile);
8037}
8038
8039
8040Local<String> CpuProfile::GetTitle() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008041 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008042 i::Isolate* isolate = profile->top_down()->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008043 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
8044 profile->title()));
Steve Block6ded16b2010-05-10 14:33:55 +01008045}
8046
8047
8048const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008049 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8050 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
8051}
8052
8053
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008054const CpuProfileNode* CpuProfile::GetSample(int index) const {
8055 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8056 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
Steve Block6ded16b2010-05-10 14:33:55 +01008057}
8058
8059
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008060int64_t CpuProfile::GetSampleTimestamp(int index) const {
8061 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8062 return (profile->sample_timestamp(index) - base::TimeTicks())
8063 .InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01008064}
8065
8066
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008067int64_t CpuProfile::GetStartTime() const {
8068 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8069 return (profile->start_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01008070}
8071
8072
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008073int64_t CpuProfile::GetEndTime() const {
8074 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8075 return (profile->end_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01008076}
8077
8078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008079int CpuProfile::GetSamplesCount() const {
8080 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
8081}
8082
8083
8084void CpuProfiler::SetSamplingInterval(int us) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008085 DCHECK_GE(us, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008086 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
8087 base::TimeDelta::FromMicroseconds(us));
8088}
8089
Ben Murdoch097c5b22016-05-18 11:27:45 +01008090void CpuProfiler::CollectSample() {
8091 reinterpret_cast<i::CpuProfiler*>(this)->CollectSample();
8092}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008093
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008094void CpuProfiler::StartProfiling(Local<String> title, bool record_samples) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008095 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
8096 *Utils::OpenHandle(*title), record_samples);
8097}
8098
8099
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008100CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008101 return reinterpret_cast<CpuProfile*>(
8102 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
Leon Clarkef7060e22010-06-03 12:02:55 +01008103 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01008104}
8105
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008106
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008107void CpuProfiler::SetIdle(bool is_idle) {
8108 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008109 v8::StateTag state = isolate->current_vm_state();
8110 DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008111 if (isolate->js_entry_sp() != NULL) return;
8112 if (is_idle) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008113 isolate->set_current_vm_state(v8::IDLE);
8114 } else if (state == v8::IDLE) {
8115 isolate->set_current_vm_state(v8::EXTERNAL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008116 }
Steve Block44f0eee2011-05-26 01:26:41 +01008117}
8118
8119
Iain Merrick75681382010-08-19 15:07:18 +01008120static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
8121 return const_cast<i::HeapGraphEdge*>(
8122 reinterpret_cast<const i::HeapGraphEdge*>(edge));
8123}
8124
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008125
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008126HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01008127 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008128}
8129
8130
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008131Local<Value> HeapGraphEdge::GetName() const {
Iain Merrick75681382010-08-19 15:07:18 +01008132 i::HeapGraphEdge* edge = ToInternal(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008133 i::Isolate* isolate = edge->isolate();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008134 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01008135 case i::HeapGraphEdge::kContextVariable:
8136 case i::HeapGraphEdge::kInternal:
8137 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08008138 case i::HeapGraphEdge::kShortcut:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008139 case i::HeapGraphEdge::kWeak:
8140 return ToApiHandle<String>(
8141 isolate->factory()->InternalizeUtf8String(edge->name()));
Iain Merrick75681382010-08-19 15:07:18 +01008142 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08008143 case i::HeapGraphEdge::kHidden:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008144 return ToApiHandle<Number>(
8145 isolate->factory()->NewNumberFromInt(edge->index()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008146 default: UNREACHABLE();
8147 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008148 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008149}
8150
8151
8152const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008153 const i::HeapEntry* from = ToInternal(this)->from();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008154 return reinterpret_cast<const HeapGraphNode*>(from);
8155}
8156
8157
8158const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Iain Merrick75681382010-08-19 15:07:18 +01008159 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008160 return reinterpret_cast<const HeapGraphNode*>(to);
8161}
8162
8163
Iain Merrick75681382010-08-19 15:07:18 +01008164static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
8165 return const_cast<i::HeapEntry*>(
8166 reinterpret_cast<const i::HeapEntry*>(entry));
8167}
8168
8169
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008170HeapGraphNode::Type HeapGraphNode::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01008171 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008172}
8173
8174
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008175Local<String> HeapGraphNode::GetName() const {
8176 i::Isolate* isolate = ToInternal(this)->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008177 return ToApiHandle<String>(
8178 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008179}
8180
8181
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008182SnapshotObjectId HeapGraphNode::GetId() const {
Iain Merrick75681382010-08-19 15:07:18 +01008183 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01008184}
8185
8186
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008187size_t HeapGraphNode::GetShallowSize() const {
Iain Merrick75681382010-08-19 15:07:18 +01008188 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008189}
8190
8191
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008192int HeapGraphNode::GetChildrenCount() const {
Iain Merrick75681382010-08-19 15:07:18 +01008193 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008194}
8195
8196
8197const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008198 return reinterpret_cast<const HeapGraphEdge*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008199 ToInternal(this)->children()[index]);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008200}
8201
8202
Iain Merrick75681382010-08-19 15:07:18 +01008203static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
8204 return const_cast<i::HeapSnapshot*>(
8205 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
8206}
8207
8208
Steve Block44f0eee2011-05-26 01:26:41 +01008209void HeapSnapshot::Delete() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008210 i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008211 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
Steve Block44f0eee2011-05-26 01:26:41 +01008212 ToInternal(this)->Delete();
8213 } else {
8214 // If this is the last snapshot, clean up all accessory data as well.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008215 isolate->heap_profiler()->DeleteAllSnapshots();
Steve Block44f0eee2011-05-26 01:26:41 +01008216 }
8217}
8218
8219
Ben Murdoch3bec4d22010-07-22 14:51:16 +01008220const HeapGraphNode* HeapSnapshot::GetRoot() const {
Iain Merrick75681382010-08-19 15:07:18 +01008221 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008222}
8223
8224
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008225const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
Ben Murdochb0fe1622011-05-05 13:52:32 +01008226 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008227 ToInternal(this)->GetEntryById(id));
Ben Murdochb0fe1622011-05-05 13:52:32 +01008228}
8229
8230
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008231int HeapSnapshot::GetNodesCount() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008232 return ToInternal(this)->entries().length();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008233}
8234
8235
8236const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008237 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008238 &ToInternal(this)->entries().at(index));
8239}
8240
8241
8242SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
8243 return ToInternal(this)->max_snapshot_js_object_id();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008244}
8245
8246
Kristian Monsen0d5e1162010-09-30 15:31:59 +01008247void HeapSnapshot::Serialize(OutputStream* stream,
8248 HeapSnapshot::SerializationFormat format) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008249 Utils::ApiCheck(format == kJSON,
8250 "v8::HeapSnapshot::Serialize",
8251 "Unknown serialization format");
8252 Utils::ApiCheck(stream->GetChunkSize() > 0,
8253 "v8::HeapSnapshot::Serialize",
8254 "Invalid stream chunk size");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01008255 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
8256 serializer.Serialize(stream);
8257}
8258
8259
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008260// static
8261STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
8262 HeapProfiler::kUnknownObjectId;
8263
8264
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008265int HeapProfiler::GetSnapshotCount() {
8266 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008267}
8268
8269
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008270const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008271 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008272 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008273}
8274
8275
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008276SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008277 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
8278 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
8279}
8280
8281
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008282Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008283 i::Handle<i::Object> obj =
8284 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
8285 if (obj.is_null()) return Local<Value>();
8286 return Utils::ToLocal(obj);
8287}
8288
8289
8290void HeapProfiler::ClearObjectIds() {
8291 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
8292}
8293
8294
8295const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008296 ActivityControl* control, ObjectNameResolver* resolver) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008297 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008298 reinterpret_cast<i::HeapProfiler*>(this)
8299 ->TakeSnapshot(control, resolver));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008300}
8301
8302
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008303void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
8304 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
8305 track_allocations);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008306}
8307
Steve Block44f0eee2011-05-26 01:26:41 +01008308
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008309void HeapProfiler::StopTrackingHeapObjects() {
8310 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
Steve Block44f0eee2011-05-26 01:26:41 +01008311}
8312
8313
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008314SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
8315 int64_t* timestamp_us) {
8316 i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
8317 return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
Steve Block44f0eee2011-05-26 01:26:41 +01008318}
8319
Steve Block6ded16b2010-05-10 14:33:55 +01008320
Ben Murdoch097c5b22016-05-18 11:27:45 +01008321bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
8322 int stack_depth) {
8323 return reinterpret_cast<i::HeapProfiler*>(this)
8324 ->StartSamplingHeapProfiler(sample_interval, stack_depth);
8325}
8326
8327
8328void HeapProfiler::StopSamplingHeapProfiler() {
8329 reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
8330}
8331
8332
8333AllocationProfile* HeapProfiler::GetAllocationProfile() {
8334 return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
8335}
8336
8337
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008338void HeapProfiler::DeleteAllHeapSnapshots() {
8339 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
8340}
8341
8342
8343void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
8344 WrapperInfoCallback callback) {
8345 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
8346 callback);
8347}
8348
8349
8350size_t HeapProfiler::GetProfilerMemorySize() {
8351 return reinterpret_cast<i::HeapProfiler*>(this)->
8352 GetMemorySizeUsedByProfiler();
8353}
8354
8355
8356void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
8357 RetainedObjectInfo* info) {
8358 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008359}
8360
Steve Block6ded16b2010-05-10 14:33:55 +01008361
Ben Murdochb0fe1622011-05-05 13:52:32 +01008362v8::Testing::StressType internal::Testing::stress_type_ =
8363 v8::Testing::kStressTypeOpt;
8364
8365
8366void Testing::SetStressRunType(Testing::StressType type) {
8367 internal::Testing::set_stress_type(type);
8368}
8369
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008370
Ben Murdochb0fe1622011-05-05 13:52:32 +01008371int Testing::GetStressRuns() {
8372 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
8373#ifdef DEBUG
8374 // In debug mode the code runs much slower so stressing will only make two
8375 // runs.
8376 return 2;
8377#else
8378 return 5;
8379#endif
8380}
8381
8382
8383static void SetFlagsFromString(const char* flags) {
8384 V8::SetFlagsFromString(flags, i::StrLength(flags));
8385}
8386
8387
8388void Testing::PrepareStressRun(int run) {
8389 static const char* kLazyOptimizations =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008390 "--prepare-always-opt "
8391 "--max-inlined-source-size=999999 "
8392 "--max-inlined-nodes=999999 "
8393 "--max-inlined-nodes-cumulative=999999 "
8394 "--noalways-opt";
Ben Murdochb0fe1622011-05-05 13:52:32 +01008395 static const char* kForcedOptimizations = "--always-opt";
8396
8397 // If deoptimization stressed turn on frequent deoptimization. If no value
8398 // is spefified through --deopt-every-n-times use a default default value.
8399 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
8400 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
8401 internal::FLAG_deopt_every_n_times == 0) {
8402 SetFlagsFromString(kDeoptEvery13Times);
8403 }
8404
8405#ifdef DEBUG
8406 // As stressing in debug mode only make two runs skip the deopt stressing
8407 // here.
8408 if (run == GetStressRuns() - 1) {
8409 SetFlagsFromString(kForcedOptimizations);
8410 } else {
Ben Murdochb0fe1622011-05-05 13:52:32 +01008411 SetFlagsFromString(kLazyOptimizations);
8412 }
8413#else
8414 if (run == GetStressRuns() - 1) {
8415 SetFlagsFromString(kForcedOptimizations);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008416 } else if (run != GetStressRuns() - 2) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01008417 SetFlagsFromString(kLazyOptimizations);
8418 }
8419#endif
8420}
8421
8422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008423void Testing::DeoptimizeAll(Isolate* isolate) {
8424 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8425 i::HandleScope scope(i_isolate);
8426 internal::Deoptimizer::DeoptimizeAll(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00008427}
8428
8429
Steve Block44f0eee2011-05-26 01:26:41 +01008430namespace internal {
8431
8432
Steve Blocka7e24c12009-10-30 11:49:00 +00008433void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01008434 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00008435}
8436
8437
8438char* HandleScopeImplementer::ArchiveThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008439 HandleScopeData* current = isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00008440 handle_scope_data_ = *current;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008441 MemCopy(storage, this, sizeof(*this));
Steve Blocka7e24c12009-10-30 11:49:00 +00008442
8443 ResetAfterArchive();
8444 current->Initialize();
8445
8446 return storage + ArchiveSpacePerThread();
8447}
8448
8449
8450int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01008451 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00008452}
8453
8454
8455char* HandleScopeImplementer::RestoreThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008456 MemCopy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00008457 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00008458 return storage + ArchiveSpacePerThread();
8459}
8460
8461
8462void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008463#ifdef DEBUG
8464 bool found_block_before_deferred = false;
8465#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00008466 // Iterate over all handles in the blocks except for the last.
8467 for (int i = blocks()->length() - 2; i >= 0; --i) {
8468 Object** block = blocks()->at(i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008469 if (last_handle_before_deferred_block_ != NULL &&
8470 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
8471 (last_handle_before_deferred_block_ >= block)) {
8472 v->VisitPointers(block, last_handle_before_deferred_block_);
8473 DCHECK(!found_block_before_deferred);
8474#ifdef DEBUG
8475 found_block_before_deferred = true;
8476#endif
8477 } else {
8478 v->VisitPointers(block, &block[kHandleBlockSize]);
8479 }
Steve Blocka7e24c12009-10-30 11:49:00 +00008480 }
8481
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008482 DCHECK(last_handle_before_deferred_block_ == NULL ||
8483 found_block_before_deferred);
8484
Steve Blocka7e24c12009-10-30 11:49:00 +00008485 // Iterate over live handles in the last block (if any).
8486 if (!blocks()->is_empty()) {
8487 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
8488 }
8489
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008490 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
8491 for (unsigned i = 0; i < arraysize(context_lists); i++) {
8492 if (context_lists[i]->is_empty()) continue;
8493 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
8494 v->VisitPointers(start, start + context_lists[i]->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00008495 }
8496}
8497
8498
8499void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008500 HandleScopeData* current = isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01008501 handle_scope_data_ = *current;
8502 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00008503}
8504
8505
8506char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01008507 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00008508 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01008509 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00008510 return storage + ArchiveSpacePerThread();
8511}
8512
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008513
8514DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
8515 DeferredHandles* deferred =
8516 new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
8517
8518 while (!blocks_.is_empty()) {
8519 Object** block_start = blocks_.last();
8520 Object** block_limit = &block_start[kHandleBlockSize];
8521 // We should not need to check for SealHandleScope here. Assert this.
8522 DCHECK(prev_limit == block_limit ||
8523 !(block_start <= prev_limit && prev_limit <= block_limit));
8524 if (prev_limit == block_limit) break;
8525 deferred->blocks_.Add(blocks_.last());
8526 blocks_.RemoveLast();
8527 }
8528
8529 // deferred->blocks_ now contains the blocks installed on the
8530 // HandleScope stack since BeginDeferredScope was called, but in
8531 // reverse order.
8532
8533 DCHECK(prev_limit == NULL || !blocks_.is_empty());
8534
8535 DCHECK(!blocks_.is_empty() && prev_limit != NULL);
8536 DCHECK(last_handle_before_deferred_block_ != NULL);
8537 last_handle_before_deferred_block_ = NULL;
8538 return deferred;
8539}
8540
8541
8542void HandleScopeImplementer::BeginDeferredScope() {
8543 DCHECK(last_handle_before_deferred_block_ == NULL);
8544 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
8545}
8546
8547
8548DeferredHandles::~DeferredHandles() {
8549 isolate_->UnlinkDeferredHandles(this);
8550
8551 for (int i = 0; i < blocks_.length(); i++) {
8552#ifdef ENABLE_HANDLE_ZAPPING
8553 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
8554#endif
8555 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
8556 }
8557}
8558
8559
8560void DeferredHandles::Iterate(ObjectVisitor* v) {
8561 DCHECK(!blocks_.is_empty());
8562
8563 DCHECK((first_block_limit_ >= blocks_.first()) &&
8564 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
8565
8566 v->VisitPointers(blocks_.first(), first_block_limit_);
8567
8568 for (int i = 1; i < blocks_.length(); i++) {
8569 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
8570 }
8571}
8572
8573
8574void InvokeAccessorGetterCallback(
8575 v8::Local<v8::Name> property,
8576 const v8::PropertyCallbackInfo<v8::Value>& info,
8577 v8::AccessorNameGetterCallback getter) {
8578 // Leaving JavaScript.
8579 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
8580 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
8581 getter));
8582 VMState<EXTERNAL> state(isolate);
8583 ExternalCallbackScope call_scope(isolate, getter_address);
8584 getter(property, info);
8585}
8586
8587
8588void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
8589 v8::FunctionCallback callback) {
8590 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
8591 Address callback_address =
8592 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
8593 VMState<EXTERNAL> state(isolate);
8594 ExternalCallbackScope call_scope(isolate, callback_address);
8595 callback(info);
8596}
8597
8598
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008599} // namespace internal
8600} // namespace v8