blob: 853bd50f2195a411776c24fef760df3b3931b503 [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
Ben Murdochda12d292016-06-02 14:46:10 +0100159#ifdef DEBUG
160void CheckMicrotasksScopesConsistency(i::Isolate* isolate) {
161 auto handle_scope_implementer = isolate->handle_scope_implementer();
162 if (handle_scope_implementer->microtasks_policy() ==
163 v8::MicrotasksPolicy::kScoped) {
164 DCHECK(handle_scope_implementer->GetMicrotasksScopeDepth() ||
165 !handle_scope_implementer->DebugMicrotasksScopeDepthIsZero());
166 }
167}
168#endif
169
170
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000171class CallDepthScope {
172 public:
173 explicit CallDepthScope(i::Isolate* isolate, Local<Context> context,
174 bool do_callback)
175 : isolate_(isolate),
176 context_(context),
177 escaped_(false),
178 do_callback_(do_callback) {
179 // TODO(dcarney): remove this when blink stops crashing.
180 DCHECK(!isolate_->external_caught_exception());
181 isolate_->IncrementJsCallsFromApiCounter();
182 isolate_->handle_scope_implementer()->IncrementCallDepth();
183 if (!context_.IsEmpty()) context_->Enter();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100184 if (do_callback_) isolate_->FireBeforeCallEnteredCallback();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000185 }
186 ~CallDepthScope() {
187 if (!context_.IsEmpty()) context_->Exit();
188 if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
189 if (do_callback_) isolate_->FireCallCompletedCallback();
Ben Murdochda12d292016-06-02 14:46:10 +0100190#ifdef DEBUG
191 if (do_callback_) CheckMicrotasksScopesConsistency(isolate_);
192#endif
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000193 }
194
195 void Escape() {
196 DCHECK(!escaped_);
197 escaped_ = true;
198 auto handle_scope_implementer = isolate_->handle_scope_implementer();
199 handle_scope_implementer->DecrementCallDepth();
200 bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();
201 isolate_->OptionalRescheduleException(call_depth_is_zero);
202 }
203
204 private:
205 i::Isolate* const isolate_;
206 Local<Context> context_;
207 bool escaped_;
208 bool do_callback_;
209};
210
211} // namespace
212
213
214static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
215 i::Handle<i::Script> script) {
216 i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
217 i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
218 v8::Isolate* v8_isolate =
219 reinterpret_cast<v8::Isolate*>(script->GetIsolate());
220 ScriptOriginOptions options(script->origin_options());
221 v8::ScriptOrigin origin(
222 Utils::ToLocal(scriptName),
223 v8::Integer::New(v8_isolate, script->line_offset()),
224 v8::Integer::New(v8_isolate, script->column_offset()),
225 v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()),
226 v8::Integer::New(v8_isolate, script->id()),
227 v8::Boolean::New(v8_isolate, options.IsEmbedderDebugScript()),
228 Utils::ToLocal(source_map_url),
229 v8::Boolean::New(v8_isolate, options.IsOpaque()));
230 return origin;
231}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100232
233
Steve Blocka7e24c12009-10-30 11:49:00 +0000234// --- E x c e p t i o n B e h a v i o r ---
235
236
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800237void i::FatalProcessOutOfMemory(const char* location) {
238 i::V8::FatalProcessOutOfMemory(location, false);
239}
240
Steve Blocka7e24c12009-10-30 11:49:00 +0000241
242// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
243// The default fatal error handler is called and execution is stopped.
Ben Murdochbb769b22010-08-11 14:56:33 +0100244void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245 i::Isolate* isolate = i::Isolate::Current();
246 char last_few_messages[Heap::kTraceRingBufferSize + 1];
247 char js_stacktrace[Heap::kStacktraceBufferSize + 1];
248 memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
249 memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
250
Steve Blockd0582a62009-12-15 09:54:21 +0000251 i::HeapStats heap_stats;
252 int start_marker;
253 heap_stats.start_marker = &start_marker;
254 int new_space_size;
255 heap_stats.new_space_size = &new_space_size;
256 int new_space_capacity;
257 heap_stats.new_space_capacity = &new_space_capacity;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000258 intptr_t old_space_size;
259 heap_stats.old_space_size = &old_space_size;
260 intptr_t old_space_capacity;
261 heap_stats.old_space_capacity = &old_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100262 intptr_t code_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000263 heap_stats.code_space_size = &code_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100264 intptr_t code_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000265 heap_stats.code_space_capacity = &code_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100266 intptr_t map_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000267 heap_stats.map_space_size = &map_space_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100268 intptr_t map_space_capacity;
Steve Blockd0582a62009-12-15 09:54:21 +0000269 heap_stats.map_space_capacity = &map_space_capacity;
Ben Murdochf87a2032010-10-22 12:50:53 +0100270 intptr_t lo_space_size;
Steve Blockd0582a62009-12-15 09:54:21 +0000271 heap_stats.lo_space_size = &lo_space_size;
272 int global_handle_count;
273 heap_stats.global_handle_count = &global_handle_count;
274 int weak_global_handle_count;
275 heap_stats.weak_global_handle_count = &weak_global_handle_count;
276 int pending_global_handle_count;
277 heap_stats.pending_global_handle_count = &pending_global_handle_count;
278 int near_death_global_handle_count;
279 heap_stats.near_death_global_handle_count = &near_death_global_handle_count;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000280 int free_global_handle_count;
281 heap_stats.free_global_handle_count = &free_global_handle_count;
Ben Murdochf87a2032010-10-22 12:50:53 +0100282 intptr_t memory_allocator_size;
Ben Murdochbb769b22010-08-11 14:56:33 +0100283 heap_stats.memory_allocator_size = &memory_allocator_size;
Ben Murdochf87a2032010-10-22 12:50:53 +0100284 intptr_t memory_allocator_capacity;
Ben Murdochbb769b22010-08-11 14:56:33 +0100285 heap_stats.memory_allocator_capacity = &memory_allocator_capacity;
286 int objects_per_type[LAST_TYPE + 1] = {0};
287 heap_stats.objects_per_type = objects_per_type;
288 int size_per_type[LAST_TYPE + 1] = {0};
289 heap_stats.size_per_type = size_per_type;
Iain Merrick75681382010-08-19 15:07:18 +0100290 int os_error;
291 heap_stats.os_error = &os_error;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000292 heap_stats.last_few_messages = last_few_messages;
293 heap_stats.js_stacktrace = js_stacktrace;
Steve Blockd0582a62009-12-15 09:54:21 +0000294 int end_marker;
295 heap_stats.end_marker = &end_marker;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000296 if (isolate->heap()->HasBeenSetUp()) {
297 // BUG(1718): Don't use the take_snapshot since we don't support
298 // HeapIterator here without doing a special GC.
299 isolate->heap()->RecordStats(&heap_stats, false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000300 char* first_newline = strchr(last_few_messages, '\n');
301 if (first_newline == NULL || first_newline[1] == '\0')
302 first_newline = last_few_messages;
303 PrintF("\n<--- Last few GCs --->\n%s\n", first_newline);
304 PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
Steve Blocka7e24c12009-10-30 11:49:00 +0000305 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000306 Utils::ApiCheck(false, location, "Allocation failed - process out of memory");
307 // If the fatal error handler returns, we stop execution.
308 FATAL("API fatal error handler returned after process out of memory");
Steve Blocka7e24c12009-10-30 11:49:00 +0000309}
310
311
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000312void Utils::ReportApiFailure(const char* location, const char* message) {
313 i::Isolate* isolate = i::Isolate::Current();
314 FatalErrorCallback callback = isolate->exception_behavior();
315 if (callback == NULL) {
316 base::OS::PrintError("\n#\n# Fatal error in %s\n# %s\n#\n\n", location,
317 message);
318 base::OS::Abort();
319 } else {
320 callback(location, message);
321 }
322 isolate->SignalFatalError();
Steve Blocka7e24c12009-10-30 11:49:00 +0000323}
324
325
Steve Block44f0eee2011-05-26 01:26:41 +0100326static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +0100327 if (isolate->has_scheduled_exception()) {
328 return isolate->scheduled_exception() ==
329 isolate->heap()->termination_exception();
330 }
331 return false;
332}
333
334
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000335void V8::SetNativesDataBlob(StartupData* natives_blob) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400336 i::V8::SetNativesBlob(natives_blob);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000337}
338
339
340void V8::SetSnapshotDataBlob(StartupData* snapshot_blob) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400341 i::V8::SetSnapshotBlob(snapshot_blob);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000342}
343
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000344namespace {
345
346class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
347 public:
348 virtual void* Allocate(size_t length) {
349 void* data = AllocateUninitialized(length);
350 return data == NULL ? data : memset(data, 0, length);
351 }
352 virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
353 virtual void Free(void* data, size_t) { free(data); }
354};
355
Ben Murdochda12d292016-06-02 14:46:10 +0100356bool RunExtraCode(Isolate* isolate, Local<Context> context,
357 const char* utf8_source, const char* name) {
358 base::ElapsedTimer timer;
359 timer.Start();
360 Context::Scope context_scope(context);
361 TryCatch try_catch(isolate);
362 Local<String> source_string;
363 if (!String::NewFromUtf8(isolate, utf8_source, NewStringType::kNormal)
364 .ToLocal(&source_string)) {
365 return false;
366 }
367 Local<String> resource_name =
368 String::NewFromUtf8(isolate, name, NewStringType::kNormal)
369 .ToLocalChecked();
370 ScriptOrigin origin(resource_name);
371 ScriptCompiler::Source source(source_string, origin);
372 Local<Script> script;
373 if (!ScriptCompiler::Compile(context, &source).ToLocal(&script)) return false;
374 if (script->Run(context).IsEmpty()) return false;
375 if (i::FLAG_profile_deserialization) {
376 i::PrintF("Executing custom snapshot script %s took %0.3f ms\n", name,
377 timer.Elapsed().InMillisecondsF());
378 }
379 timer.Stop();
380 CHECK(!try_catch.HasCaught());
381 return true;
382}
383
384StartupData SerializeIsolateAndContext(
385 Isolate* isolate, Persistent<Context>* context,
386 i::Snapshot::Metadata metadata,
387 i::StartupSerializer::FunctionCodeHandling function_code_handling) {
388 if (context->IsEmpty()) return {NULL, 0};
389
390 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
391
392 // If we don't do this then we end up with a stray root pointing at the
393 // context even after we have disposed of the context.
394 internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
395
396 // GC may have cleared weak cells, so compact any WeakFixedArrays
397 // found on the heap.
398 i::HeapIterator iterator(internal_isolate->heap(),
399 i::HeapIterator::kFilterUnreachable);
400 for (i::HeapObject* o = iterator.next(); o != NULL; o = iterator.next()) {
401 if (o->IsPrototypeInfo()) {
402 i::Object* prototype_users = i::PrototypeInfo::cast(o)->prototype_users();
403 if (prototype_users->IsWeakFixedArray()) {
404 i::WeakFixedArray* array = i::WeakFixedArray::cast(prototype_users);
405 array->Compact<i::JSObject::PrototypeRegistryCompactionCallback>();
406 }
407 } else if (o->IsScript()) {
408 i::Object* shared_list = i::Script::cast(o)->shared_function_infos();
409 if (shared_list->IsWeakFixedArray()) {
410 i::WeakFixedArray* array = i::WeakFixedArray::cast(shared_list);
411 array->Compact<i::WeakFixedArray::NullCallback>();
412 }
413 }
414 }
415
416 i::Object* raw_context = *v8::Utils::OpenPersistent(*context);
417 context->Reset();
418
419 i::SnapshotByteSink snapshot_sink;
420 i::StartupSerializer ser(internal_isolate, &snapshot_sink,
421 function_code_handling);
422 ser.SerializeStrongReferences();
423
424 i::SnapshotByteSink context_sink;
425 i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
426 context_ser.Serialize(&raw_context);
427 ser.SerializeWeakReferencesAndDeferred();
428
429 return i::Snapshot::CreateSnapshotBlob(ser, context_ser, metadata);
430}
431
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000432} // namespace
433
Ben Murdochda12d292016-06-02 14:46:10 +0100434StartupData V8::CreateSnapshotDataBlob(const char* embedded_source) {
435 // Create a new isolate and a new context from scratch, optionally run
436 // a script to embed, and serialize to create a snapshot blob.
437 StartupData result = {NULL, 0};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000438
Ben Murdochda12d292016-06-02 14:46:10 +0100439 base::ElapsedTimer timer;
440 timer.Start();
441
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000442 ArrayBufferAllocator allocator;
Ben Murdochda12d292016-06-02 14:46:10 +0100443 i::Isolate* internal_isolate = new i::Isolate(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000444 internal_isolate->set_array_buffer_allocator(&allocator);
445 Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
Ben Murdochda12d292016-06-02 14:46:10 +0100446
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400447 {
448 Isolate::Scope isolate_scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000449 internal_isolate->Init(NULL);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400450 Persistent<Context> context;
451 {
452 HandleScope handle_scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 Local<Context> new_context = Context::New(isolate);
454 context.Reset(isolate, new_context);
Ben Murdochda12d292016-06-02 14:46:10 +0100455 if (embedded_source != NULL &&
456 !RunExtraCode(isolate, new_context, embedded_source, "<embedded>")) {
457 context.Reset();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000458 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400459 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000460
Ben Murdochda12d292016-06-02 14:46:10 +0100461 i::Snapshot::Metadata metadata;
462 metadata.set_embeds_script(embedded_source != NULL);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000463
Ben Murdochda12d292016-06-02 14:46:10 +0100464 result = SerializeIsolateAndContext(
465 isolate, &context, metadata, i::StartupSerializer::CLEAR_FUNCTION_CODE);
466 DCHECK(context.IsEmpty());
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400467 }
468 isolate->Dispose();
Ben Murdochda12d292016-06-02 14:46:10 +0100469
470 if (i::FLAG_profile_deserialization) {
471 i::PrintF("Creating snapshot took %0.3f ms\n",
472 timer.Elapsed().InMillisecondsF());
473 }
474 timer.Stop();
475 return result;
476}
477
478StartupData V8::WarmUpSnapshotDataBlob(StartupData cold_snapshot_blob,
479 const char* warmup_source) {
480 CHECK(cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != NULL);
481 CHECK(warmup_source != NULL);
482 // Use following steps to create a warmed up snapshot blob from a cold one:
483 // - Create a new isolate from the cold snapshot.
484 // - Create a new context to run the warmup script. This will trigger
485 // compilation of executed functions.
486 // - Create a new context. This context will be unpolluted.
487 // - Serialize the isolate and the second context into a new snapshot blob.
488 StartupData result = {NULL, 0};
489
490 base::ElapsedTimer timer;
491 timer.Start();
492
493 ArrayBufferAllocator allocator;
494 i::Isolate* internal_isolate = new i::Isolate(true);
495 internal_isolate->set_array_buffer_allocator(&allocator);
496 internal_isolate->set_snapshot_blob(&cold_snapshot_blob);
497 Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
498
499 {
500 Isolate::Scope isolate_scope(isolate);
501 i::Snapshot::Initialize(internal_isolate);
502 Persistent<Context> context;
503 bool success;
504 {
505 HandleScope handle_scope(isolate);
506 Local<Context> new_context = Context::New(isolate);
507 success = RunExtraCode(isolate, new_context, warmup_source, "<warm-up>");
508 }
509 if (success) {
510 HandleScope handle_scope(isolate);
511 isolate->ContextDisposedNotification(false);
512 Local<Context> new_context = Context::New(isolate);
513 context.Reset(isolate, new_context);
514 }
515
516 i::Snapshot::Metadata metadata;
517 metadata.set_embeds_script(i::Snapshot::EmbedsScript(internal_isolate));
518
519 result = SerializeIsolateAndContext(
520 isolate, &context, metadata, i::StartupSerializer::KEEP_FUNCTION_CODE);
521 DCHECK(context.IsEmpty());
522 }
523 isolate->Dispose();
524
525 if (i::FLAG_profile_deserialization) {
526 i::PrintF("Warming up snapshot took %0.3f ms\n",
527 timer.Elapsed().InMillisecondsF());
528 }
529 timer.Stop();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400530 return result;
Ben Murdoch257744e2011-11-30 15:57:28 +0000531}
532
533
Steve Blocka7e24c12009-10-30 11:49:00 +0000534void V8::SetFlagsFromString(const char* str, int length) {
535 i::FlagList::SetFlagsFromString(str, length);
536}
537
538
539void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) {
540 i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags);
541}
542
543
Steve Blocka7e24c12009-10-30 11:49:00 +0000544RegisteredExtension* RegisteredExtension::first_extension_ = NULL;
545
546
547RegisteredExtension::RegisteredExtension(Extension* extension)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100548 : extension_(extension) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000549
550
551void RegisteredExtension::Register(RegisteredExtension* that) {
Steve Block44f0eee2011-05-26 01:26:41 +0100552 that->next_ = first_extension_;
553 first_extension_ = that;
Steve Blocka7e24c12009-10-30 11:49:00 +0000554}
555
556
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000557void RegisteredExtension::UnregisterAll() {
558 RegisteredExtension* re = first_extension_;
559 while (re != NULL) {
560 RegisteredExtension* next = re->next();
561 delete re;
562 re = next;
563 }
564 first_extension_ = NULL;
565}
566
567
Steve Blocka7e24c12009-10-30 11:49:00 +0000568void RegisterExtension(Extension* that) {
569 RegisteredExtension* extension = new RegisteredExtension(that);
570 RegisteredExtension::Register(extension);
571}
572
573
574Extension::Extension(const char* name,
575 const char* source,
576 int dep_count,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100577 const char** deps,
578 int source_length)
Steve Blocka7e24c12009-10-30 11:49:00 +0000579 : name_(name),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100580 source_length_(source_length >= 0 ?
581 source_length :
582 (source ? static_cast<int>(strlen(source)) : 0)),
583 source_(source, source_length_),
Steve Blocka7e24c12009-10-30 11:49:00 +0000584 dep_count_(dep_count),
585 deps_(deps),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000586 auto_enable_(false) {
587 CHECK(source != NULL || source_length_ == 0);
Steve Blocka7e24c12009-10-30 11:49:00 +0000588}
589
590
591ResourceConstraints::ResourceConstraints()
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592 : max_semi_space_size_(0),
593 max_old_space_size_(0),
594 max_executable_size_(0),
595 stack_limit_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000596 code_range_size_(0) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000597
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000598void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000599 uint64_t virtual_memory_limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000600#if V8_OS_ANDROID
601 // Android has higher physical memory requirements before raising the maximum
602 // heap size limits since it has no swap space.
603 const uint64_t low_limit = 512ul * i::MB;
604 const uint64_t medium_limit = 1ul * i::GB;
605 const uint64_t high_limit = 2ul * i::GB;
606#else
607 const uint64_t low_limit = 512ul * i::MB;
608 const uint64_t medium_limit = 768ul * i::MB;
609 const uint64_t high_limit = 1ul * i::GB;
610#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000611
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000612 if (physical_memory <= low_limit) {
613 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeLowMemoryDevice);
614 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeLowMemoryDevice);
615 set_max_executable_size(i::Heap::kMaxExecutableSizeLowMemoryDevice);
616 } else if (physical_memory <= medium_limit) {
617 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeMediumMemoryDevice);
618 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeMediumMemoryDevice);
619 set_max_executable_size(i::Heap::kMaxExecutableSizeMediumMemoryDevice);
620 } else if (physical_memory <= high_limit) {
621 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHighMemoryDevice);
622 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHighMemoryDevice);
623 set_max_executable_size(i::Heap::kMaxExecutableSizeHighMemoryDevice);
624 } else {
625 set_max_semi_space_size(i::Heap::kMaxSemiSpaceSizeHugeMemoryDevice);
626 set_max_old_space_size(i::Heap::kMaxOldSpaceSizeHugeMemoryDevice);
627 set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
Steve Blocka7e24c12009-10-30 11:49:00 +0000628 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000629
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630 if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
631 // Reserve no more than 1/8 of the memory for the code range, but at most
632 // kMaximalCodeRangeSize.
633 set_code_range_size(
634 i::Min(i::kMaximalCodeRangeSize / i::MB,
635 static_cast<size_t>((virtual_memory_limit >> 3) / i::MB)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000636 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000637}
638
639
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000640void SetResourceConstraints(i::Isolate* isolate,
641 const ResourceConstraints& constraints) {
642 int semi_space_size = constraints.max_semi_space_size();
643 int old_space_size = constraints.max_old_space_size();
644 int max_executable_size = constraints.max_executable_size();
645 size_t code_range_size = constraints.code_range_size();
646 if (semi_space_size != 0 || old_space_size != 0 ||
647 max_executable_size != 0 || code_range_size != 0) {
648 isolate->heap()->ConfigureHeap(semi_space_size, old_space_size,
649 max_executable_size, code_range_size);
650 }
651 if (constraints.stack_limit() != NULL) {
652 uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
653 isolate->stack_guard()->SetStackLimit(limit);
654 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000655}
656
657
658i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) {
Steve Block44f0eee2011-05-26 01:26:41 +0100659 LOG_API(isolate, "Persistent::New");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000660 i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400661#ifdef VERIFY_HEAP
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000662 if (i::FLAG_verify_heap) {
663 (*obj)->ObjectVerify();
664 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400665#endif // VERIFY_HEAP
Steve Blocka7e24c12009-10-30 11:49:00 +0000666 return result.location();
667}
668
669
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000670i::Object** V8::CopyPersistent(i::Object** obj) {
671 i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400672#ifdef VERIFY_HEAP
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000673 if (i::FLAG_verify_heap) {
674 (*obj)->ObjectVerify();
675 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400676#endif // VERIFY_HEAP
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000677 return result.location();
Steve Blocka7e24c12009-10-30 11:49:00 +0000678}
679
Ben Murdochda12d292016-06-02 14:46:10 +0100680void V8::RegisterExternallyReferencedObject(i::Object** object,
681 i::Isolate* isolate) {
682 isolate->heap()->RegisterExternallyReferencedObject(object);
683}
Steve Blocka7e24c12009-10-30 11:49:00 +0000684
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400685void V8::MakeWeak(i::Object** object, void* parameter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000686 WeakCallback weak_callback) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400687 i::GlobalHandles::MakeWeak(object, parameter, weak_callback);
688}
689
690
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000691void V8::MakeWeak(i::Object** object, void* parameter,
692 int internal_field_index1, int internal_field_index2,
693 WeakCallbackInfo<void>::Callback weak_callback) {
694 WeakCallbackType type = WeakCallbackType::kParameter;
695 if (internal_field_index1 == 0) {
696 if (internal_field_index2 == 1) {
697 type = WeakCallbackType::kInternalFields;
698 } else {
699 DCHECK_EQ(internal_field_index2, -1);
700 type = WeakCallbackType::kInternalFields;
701 }
702 } else {
703 DCHECK_EQ(internal_field_index1, -1);
704 DCHECK_EQ(internal_field_index2, -1);
705 }
706 i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400707}
708
709
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000710void V8::MakeWeak(i::Object** object, void* parameter,
711 WeakCallbackInfo<void>::Callback weak_callback,
712 WeakCallbackType type) {
713 i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
Steve Blocka7e24c12009-10-30 11:49:00 +0000714}
715
716
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717void* V8::ClearWeak(i::Object** obj) {
718 return i::GlobalHandles::ClearWeakness(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000719}
720
721
722void V8::DisposeGlobal(i::Object** obj) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000723 i::GlobalHandles::Destroy(obj);
Steve Blocka7e24c12009-10-30 11:49:00 +0000724}
725
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000726
727void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) {
728 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
729 i::Object* object = *Utils::OpenHandle(value);
730 isolate->eternal_handles()->Create(isolate, object, index);
731}
732
733
734Local<Value> V8::GetEternal(Isolate* v8_isolate, int index) {
735 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
736 return Utils::ToLocal(isolate->eternal_handles()->Get(index));
737}
738
739
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000740void V8::FromJustIsNothing() {
741 Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
742}
743
744
745void V8::ToLocalEmpty() {
746 Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
747}
748
749
750void V8::InternalFieldOutOfBounds(int index) {
751 Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
752 "WeakCallbackInfo::GetInternalField",
753 "Internal field out of bounds.");
754}
755
756
Steve Blocka7e24c12009-10-30 11:49:00 +0000757// --- H a n d l e s ---
758
759
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000760HandleScope::HandleScope(Isolate* isolate) {
761 Initialize(isolate);
762}
763
764
765void HandleScope::Initialize(Isolate* isolate) {
766 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
767 // We do not want to check the correct usage of the Locker class all over the
768 // place, so we do it only here: Without a HandleScope, an embedder can do
769 // almost nothing, so it is enough to check in this central place.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000770 // We make an exception if the serializer is enabled, which means that the
771 // Isolate is exclusively used to create a snapshot.
772 Utils::ApiCheck(
773 !v8::Locker::IsActive() ||
774 internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
775 internal_isolate->serializer_enabled(),
776 "HandleScope::HandleScope",
777 "Entering the V8 API without proper locking in place");
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000778 i::HandleScopeData* current = internal_isolate->handle_scope_data();
779 isolate_ = internal_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +0100780 prev_next_ = current->next;
781 prev_limit_ = current->limit;
Steve Block44f0eee2011-05-26 01:26:41 +0100782 current->level++;
Steve Blocka7e24c12009-10-30 11:49:00 +0000783}
784
785
786HandleScope::~HandleScope() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000787 i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_);
788}
789
790
791int HandleScope::NumberOfHandles(Isolate* isolate) {
792 return i::HandleScope::NumberOfHandles(
793 reinterpret_cast<i::Isolate*>(isolate));
794}
795
796
797i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) {
798 return i::HandleScope::CreateHandle(isolate, value);
799}
800
801
802i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object,
803 i::Object* value) {
804 DCHECK(heap_object->IsHeapObject());
805 return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value);
806}
807
808
809EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) {
810 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
811 escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value());
812 Initialize(v8_isolate);
813}
814
815
816i::Object** EscapableHandleScope::Escape(i::Object** escape_value) {
817 i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap();
818 Utils::ApiCheck(*escape_slot_ == heap->the_hole_value(),
819 "EscapeableHandleScope::Escape",
820 "Escape value set twice");
821 if (escape_value == NULL) {
822 *escape_slot_ = heap->undefined_value();
823 return NULL;
Steve Blocka7e24c12009-10-30 11:49:00 +0000824 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825 *escape_slot_ = *escape_value;
826 return escape_slot_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000827}
828
829
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000830SealHandleScope::SealHandleScope(Isolate* isolate) {
831 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
832
833 isolate_ = internal_isolate;
834 i::HandleScopeData* current = internal_isolate->handle_scope_data();
835 prev_limit_ = current->limit;
836 current->limit = current->next;
837 prev_sealed_level_ = current->sealed_level;
838 current->sealed_level = current->level;
839}
840
841
842SealHandleScope::~SealHandleScope() {
843 i::HandleScopeData* current = isolate_->handle_scope_data();
844 DCHECK_EQ(current->next, current->limit);
845 current->limit = prev_limit_;
846 DCHECK_EQ(current->level, current->sealed_level);
847 current->sealed_level = prev_sealed_level_;
848}
849
850
Steve Blocka7e24c12009-10-30 11:49:00 +0000851void Context::Enter() {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000852 i::Handle<i::Context> env = Utils::OpenHandle(this);
853 i::Isolate* isolate = env->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +0100854 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000855 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
856 impl->EnterContext(env);
857 impl->SaveContext(isolate->context());
Steve Block44f0eee2011-05-26 01:26:41 +0100858 isolate->set_context(*env);
Steve Blocka7e24c12009-10-30 11:49:00 +0000859}
860
861
862void Context::Exit() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000863 i::Handle<i::Context> env = Utils::OpenHandle(this);
864 i::Isolate* isolate = env->GetIsolate();
865 ENTER_V8(isolate);
866 i::HandleScopeImplementer* impl = isolate->handle_scope_implementer();
867 if (!Utils::ApiCheck(impl->LastEnteredContextWas(env),
868 "v8::Context::Exit()",
869 "Cannot exit non-entered context")) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000870 return;
871 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000872 impl->LeaveContext();
873 isolate->set_context(impl->RestoreContext());
Steve Blocka7e24c12009-10-30 11:49:00 +0000874}
875
876
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000877static void* DecodeSmiToAligned(i::Object* value, const char* location) {
878 Utils::ApiCheck(value->IsSmi(), location, "Not a Smi");
879 return reinterpret_cast<void*>(value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000880}
881
882
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000883static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) {
884 i::Smi* smi = reinterpret_cast<i::Smi*>(value);
885 Utils::ApiCheck(smi->IsSmi(), location, "Pointer is not aligned");
886 return smi;
887}
888
889
890static i::Handle<i::FixedArray> EmbedderDataFor(Context* context,
891 int index,
892 bool can_grow,
893 const char* location) {
894 i::Handle<i::Context> env = Utils::OpenHandle(context);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000895 i::Isolate* isolate = env->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000896 bool ok =
897 Utils::ApiCheck(env->IsNativeContext(),
898 location,
899 "Not a native context") &&
900 Utils::ApiCheck(index >= 0, location, "Negative index");
901 if (!ok) return i::Handle<i::FixedArray>();
902 i::Handle<i::FixedArray> data(env->embedder_data());
903 if (index < data->length()) return data;
904 if (!Utils::ApiCheck(can_grow, location, "Index too large")) {
905 return i::Handle<i::FixedArray>();
Steve Block44f0eee2011-05-26 01:26:41 +0100906 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000907 int new_size = i::Max(index, data->length() << 1) + 1;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000908 int grow_by = new_size - data->length();
909 data = isolate->factory()->CopyFixedArrayAndGrow(data, grow_by);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000910 env->set_embedder_data(*data);
911 return data;
912}
913
914
915v8::Local<v8::Value> Context::SlowGetEmbedderData(int index) {
916 const char* location = "v8::Context::GetEmbedderData()";
917 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
918 if (data.is_null()) return Local<Value>();
919 i::Handle<i::Object> result(data->get(index), data->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +0000920 return Utils::ToLocal(result);
921}
922
923
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924void Context::SetEmbedderData(int index, v8::Local<Value> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000925 const char* location = "v8::Context::SetEmbedderData()";
926 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
927 if (data.is_null()) return;
928 i::Handle<i::Object> val = Utils::OpenHandle(*value);
929 data->set(index, *val);
930 DCHECK_EQ(*Utils::OpenHandle(*value),
931 *Utils::OpenHandle(*GetEmbedderData(index)));
932}
Steve Blocka7e24c12009-10-30 11:49:00 +0000933
Steve Blocka7e24c12009-10-30 11:49:00 +0000934
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000935void* Context::SlowGetAlignedPointerFromEmbedderData(int index) {
936 const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
937 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, false, location);
938 if (data.is_null()) return NULL;
939 return DecodeSmiToAligned(data->get(index), location);
940}
Steve Block6ded16b2010-05-10 14:33:55 +0100941
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942
943void Context::SetAlignedPointerInEmbedderData(int index, void* value) {
944 const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
945 i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
946 data->set(index, EncodeAlignedAsSmi(value, location));
947 DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index));
Steve Blocka7e24c12009-10-30 11:49:00 +0000948}
949
950
951// --- N e a n d e r ---
952
953
954// A constructor cannot easily return an error value, therefore it is necessary
955// to check for a dead VM with ON_BAILOUT before constructing any Neander
956// objects. To remind you about this there is no HandleScope in the
957// NeanderObject constructor. When you add one to the site calling the
958// constructor you should check that you ensured the VM was not dead first.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000959NeanderObject::NeanderObject(v8::internal::Isolate* isolate, int size) {
Steve Block44f0eee2011-05-26 01:26:41 +0100960 ENTER_V8(isolate);
961 value_ = isolate->factory()->NewNeanderObject();
962 i::Handle<i::FixedArray> elements = isolate->factory()->NewFixedArray(size);
Steve Blocka7e24c12009-10-30 11:49:00 +0000963 value_->set_elements(*elements);
964}
965
966
967int NeanderObject::size() {
968 return i::FixedArray::cast(value_->elements())->length();
969}
970
971
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000972NeanderArray::NeanderArray(v8::internal::Isolate* isolate) : obj_(isolate, 2) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000973 obj_.set(0, i::Smi::FromInt(0));
974}
975
976
977int NeanderArray::length() {
978 return i::Smi::cast(obj_.get(0))->value();
979}
980
981
982i::Object* NeanderArray::get(int offset) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000983 DCHECK_LE(0, offset);
984 DCHECK_LT(offset, length());
Steve Blocka7e24c12009-10-30 11:49:00 +0000985 return obj_.get(offset + 1);
986}
987
988
989// This method cannot easily return an error value, therefore it is necessary
990// to check for a dead VM with ON_BAILOUT before calling it. To remind you
991// about this there is no HandleScope in this method. When you add one to the
992// site calling this method you should check that you ensured the VM was not
993// dead first.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400994void NeanderArray::add(i::Isolate* isolate, i::Handle<i::Object> value) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000995 int length = this->length();
996 int size = obj_.size();
997 if (length == size - 1) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400998 i::Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999 i::Handle<i::FixedArray> new_elms = factory->NewFixedArray(2 * size);
Steve Blocka7e24c12009-10-30 11:49:00 +00001000 for (int i = 0; i < length; i++)
1001 new_elms->set(i + 1, get(i));
1002 obj_.value()->set_elements(*new_elms);
1003 }
1004 obj_.set(length + 1, *value);
1005 obj_.set(0, i::Smi::FromInt(length + 1));
1006}
1007
1008
1009void NeanderArray::set(int index, i::Object* value) {
1010 if (index < 0 || index >= this->length()) return;
1011 obj_.set(index + 1, value);
1012}
1013
1014
1015// --- T e m p l a t e ---
1016
1017
1018static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001019 that->set_number_of_properties(0);
Steve Blocka7e24c12009-10-30 11:49:00 +00001020 that->set_tag(i::Smi::FromInt(type));
1021}
1022
1023
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001024void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001025 v8::PropertyAttribute attribute) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001026 auto templ = Utils::OpenHandle(this);
1027 i::Isolate* isolate = templ->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001028 ENTER_V8(isolate);
1029 i::HandleScope scope(isolate);
Ben Murdochda12d292016-06-02 14:46:10 +01001030 auto value_obj = Utils::OpenHandle(*value);
1031 if (value_obj->IsObjectTemplateInfo()) {
1032 templ->set_serial_number(i::Smi::FromInt(0));
1033 if (templ->IsFunctionTemplateInfo()) {
1034 i::Handle<i::FunctionTemplateInfo>::cast(templ)->set_do_not_cache(true);
1035 }
1036 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001037 // TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo.
1038 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
Ben Murdochda12d292016-06-02 14:46:10 +01001039 value_obj,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001040 static_cast<i::PropertyAttributes>(attribute));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001041}
1042
1043
1044void Template::SetAccessorProperty(
1045 v8::Local<v8::Name> name,
1046 v8::Local<FunctionTemplate> getter,
1047 v8::Local<FunctionTemplate> setter,
1048 v8::PropertyAttribute attribute,
1049 v8::AccessControl access_control) {
1050 // TODO(verwaest): Remove |access_control|.
1051 DCHECK_EQ(v8::DEFAULT, access_control);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001052 auto templ = Utils::OpenHandle(this);
1053 auto isolate = templ->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001054 ENTER_V8(isolate);
1055 DCHECK(!name.IsEmpty());
1056 DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
1057 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001058 i::ApiNatives::AddAccessorProperty(
1059 isolate, templ, Utils::OpenHandle(*name),
1060 Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
1061 static_cast<i::PropertyAttributes>(attribute));
Steve Blocka7e24c12009-10-30 11:49:00 +00001062}
1063
1064
1065// --- F u n c t i o n T e m p l a t e ---
1066static void InitializeFunctionTemplate(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001067 i::Handle<i::FunctionTemplateInfo> info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001068 InitializeTemplate(info, Consts::FUNCTION_TEMPLATE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001069 info->set_flag(0);
1070}
1071
Ben Murdoch097c5b22016-05-18 11:27:45 +01001072static Local<ObjectTemplate> ObjectTemplateNew(
1073 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1074 bool do_not_cache);
Steve Blocka7e24c12009-10-30 11:49:00 +00001075
1076Local<ObjectTemplate> FunctionTemplate::PrototypeTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001077 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
1078 ENTER_V8(i_isolate);
1079 i::Handle<i::Object> result(Utils::OpenHandle(this)->prototype_template(),
1080 i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001081 if (result->IsUndefined()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001082 // Do not cache prototype objects.
1083 result = Utils::OpenHandle(
1084 *ObjectTemplateNew(i_isolate, Local<FunctionTemplate>(), true));
Steve Blocka7e24c12009-10-30 11:49:00 +00001085 Utils::OpenHandle(this)->set_prototype_template(*result);
1086 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001087 return ToApiHandle<ObjectTemplate>(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00001088}
1089
1090
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001091static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,
1092 const char* func) {
1093 Utils::ApiCheck(!info->instantiated(), func,
1094 "FunctionTemplate already instantiated");
1095}
1096
1097
1098void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
1099 auto info = Utils::OpenHandle(this);
1100 EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit");
1101 i::Isolate* isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001102 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001103 info->set_parent_template(*Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001104}
1105
1106
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107static Local<FunctionTemplate> FunctionTemplateNew(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001108 i::Isolate* isolate, FunctionCallback callback,
1109 experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
1110 v8::Local<Signature> signature, int length, bool do_not_cache) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001111 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001112 isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001113 i::Handle<i::FunctionTemplateInfo> obj =
1114 i::Handle<i::FunctionTemplateInfo>::cast(struct_obj);
1115 InitializeFunctionTemplate(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001116 obj->set_do_not_cache(do_not_cache);
1117 int next_serial_number = 0;
1118 if (!do_not_cache) {
1119 next_serial_number = isolate->next_serial_number() + 1;
1120 isolate->set_next_serial_number(next_serial_number);
1121 }
Steve Block44f0eee2011-05-26 01:26:41 +01001122 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00001123 if (callback != 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001124 if (data.IsEmpty()) {
1125 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1126 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001127 Utils::ToLocal(obj)->SetCallHandler(callback, data, fast_handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00001128 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001129 obj->set_length(length);
Steve Blocka7e24c12009-10-30 11:49:00 +00001130 obj->set_undetectable(false);
1131 obj->set_needs_access_check(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001132 obj->set_accept_any_receiver(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 if (!signature.IsEmpty())
1134 obj->set_signature(*Utils::OpenHandle(*signature));
1135 return Utils::ToLocal(obj);
1136}
1137
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001138
1139Local<FunctionTemplate> FunctionTemplate::New(Isolate* isolate,
1140 FunctionCallback callback,
1141 v8::Local<Value> data,
1142 v8::Local<Signature> signature,
1143 int length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001144 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001145 // Changes to the environment cannot be captured in the snapshot. Expect no
1146 // function templates when the isolate is created for serialization.
1147 DCHECK(!i_isolate->serializer_enabled());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001148 LOG_API(i_isolate, "FunctionTemplate::New");
1149 ENTER_V8(i_isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001150 return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature,
1151 length, false);
1152}
1153
1154
1155Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
1156 Isolate* isolate, FunctionCallback callback,
1157 experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
1158 v8::Local<Signature> signature, int length) {
1159 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
1160 DCHECK(!i_isolate->serializer_enabled());
1161 LOG_API(i_isolate, "FunctionTemplate::NewWithFastHandler");
1162 ENTER_V8(i_isolate);
1163 return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature,
1164 length, false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001165}
Steve Blocka7e24c12009-10-30 11:49:00 +00001166
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001167
1168Local<Signature> Signature::New(Isolate* isolate,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001169 Local<FunctionTemplate> receiver) {
1170 return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
Steve Blocka7e24c12009-10-30 11:49:00 +00001171}
1172
1173
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001174Local<AccessorSignature> AccessorSignature::New(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001175 Isolate* isolate, Local<FunctionTemplate> receiver) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001176 return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
1177}
1178
1179
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
1181 i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
1182 (obj)->setter(*foreign); \
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001183 } while (false)
1184
1185
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001186void FunctionTemplate::SetCallHandler(
1187 FunctionCallback callback, v8::Local<Value> data,
1188 experimental::FastAccessorBuilder* fast_handler) {
1189 auto info = Utils::OpenHandle(this);
1190 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler");
1191 i::Isolate* isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001192 ENTER_V8(isolate);
1193 i::HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001194 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001195 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001196 i::Handle<i::CallHandlerInfo> obj =
1197 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001198 SET_FIELD_WRAPPED(obj, set_callback, callback);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001199 i::MaybeHandle<i::Code> code =
1200 i::experimental::BuildCodeFromFastAccessorBuilder(fast_handler);
1201 if (!code.is_null()) {
1202 obj->set_fast_handler(*code.ToHandleChecked());
1203 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001204 if (data.IsEmpty()) {
1205 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1206 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001207 obj->set_data(*Utils::OpenHandle(*data));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001208 info->set_call_code(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001209}
1210
1211
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001212static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001213 i::Handle<i::AccessorInfo> obj, v8::Local<Name> name,
1214 v8::AccessControl settings, v8::PropertyAttribute attributes,
1215 v8::Local<AccessorSignature> signature) {
Leon Clarkef7060e22010-06-03 12:02:55 +01001216 obj->set_name(*Utils::OpenHandle(*name));
1217 if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
1218 if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001219 obj->set_property_attributes(static_cast<i::PropertyAttributes>(attributes));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001220 if (!signature.IsEmpty()) {
1221 obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
1222 }
Leon Clarkef7060e22010-06-03 12:02:55 +01001223 return obj;
1224}
1225
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001226template <typename Getter, typename Setter>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001227static i::Handle<i::AccessorInfo> MakeAccessorInfo(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001228 v8::Local<Name> name, Getter getter, Setter setter, v8::Local<Value> data,
1229 v8::AccessControl settings, v8::PropertyAttribute attributes,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001230 v8::Local<AccessorSignature> signature, bool is_special_data_property) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001231 i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001232 i::Handle<i::AccessorInfo> obj = isolate->factory()->NewAccessorInfo();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001233 SET_FIELD_WRAPPED(obj, set_getter, getter);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001234 if (is_special_data_property && setter == nullptr) {
1235 setter = reinterpret_cast<Setter>(&i::Accessors::ReconfigureToDataProperty);
1236 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001237 SET_FIELD_WRAPPED(obj, set_setter, setter);
1238 if (data.IsEmpty()) {
1239 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00001240 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001241 obj->set_data(*Utils::OpenHandle(*data));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001242 obj->set_is_special_data_property(is_special_data_property);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001243 return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
1244}
Steve Blocka7e24c12009-10-30 11:49:00 +00001245
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001246
Steve Blocka7e24c12009-10-30 11:49:00 +00001247Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001248 i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
1249 if (!Utils::ApiCheck(!handle.is_null(),
1250 "v8::FunctionTemplate::InstanceTemplate()",
1251 "Reading from empty handle")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001252 return Local<ObjectTemplate>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001253 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001254 i::Isolate* isolate = handle->GetIsolate();
1255 ENTER_V8(isolate);
1256 if (handle->instance_template()->IsUndefined()) {
1257 Local<ObjectTemplate> templ =
1258 ObjectTemplate::New(isolate, ToApiHandle<FunctionTemplate>(handle));
1259 handle->set_instance_template(*Utils::OpenHandle(*templ));
1260 }
1261 i::Handle<i::ObjectTemplateInfo> result(
1262 i::ObjectTemplateInfo::cast(handle->instance_template()));
Steve Blocka7e24c12009-10-30 11:49:00 +00001263 return Utils::ToLocal(result);
1264}
1265
1266
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001267void FunctionTemplate::SetLength(int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001268 auto info = Utils::OpenHandle(this);
1269 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetLength");
1270 auto isolate = info->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001271 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001272 info->set_length(length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001273}
1274
1275
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001276void FunctionTemplate::SetClassName(Local<String> name) {
1277 auto info = Utils::OpenHandle(this);
1278 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetClassName");
1279 auto isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001280 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001281 info->set_class_name(*Utils::OpenHandle(*name));
1282}
1283
1284
1285void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
1286 auto info = Utils::OpenHandle(this);
1287 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
1288 auto isolate = info->GetIsolate();
1289 ENTER_V8(isolate);
1290 info->set_accept_any_receiver(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001291}
1292
1293
1294void FunctionTemplate::SetHiddenPrototype(bool value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001295 auto info = Utils::OpenHandle(this);
1296 EnsureNotInstantiated(info, "v8::FunctionTemplate::SetHiddenPrototype");
1297 auto isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001298 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001299 info->set_hidden_prototype(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00001300}
1301
1302
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001303void FunctionTemplate::ReadOnlyPrototype() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001304 auto info = Utils::OpenHandle(this);
1305 EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype");
1306 auto isolate = info->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001307 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001308 info->set_read_only_prototype(true);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001309}
1310
1311
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001312void FunctionTemplate::RemovePrototype() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001313 auto info = Utils::OpenHandle(this);
1314 EnsureNotInstantiated(info, "v8::FunctionTemplate::RemovePrototype");
1315 auto isolate = info->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001316 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001317 info->set_remove_prototype(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001318}
1319
1320
1321// --- O b j e c t T e m p l a t e ---
1322
1323
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001324Local<ObjectTemplate> ObjectTemplate::New(
1325 Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1326 return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001327}
1328
1329
Steve Blocka7e24c12009-10-30 11:49:00 +00001330Local<ObjectTemplate> ObjectTemplate::New() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001331 return New(i::Isolate::Current(), Local<FunctionTemplate>());
Steve Blocka7e24c12009-10-30 11:49:00 +00001332}
1333
Ben Murdoch097c5b22016-05-18 11:27:45 +01001334static Local<ObjectTemplate> ObjectTemplateNew(
1335 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor,
1336 bool do_not_cache) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001337 // Changes to the environment cannot be captured in the snapshot. Expect no
1338 // object templates when the isolate is created for serialization.
1339 DCHECK(!isolate->serializer_enabled());
Steve Block44f0eee2011-05-26 01:26:41 +01001340 LOG_API(isolate, "ObjectTemplate::New");
1341 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001342 i::Handle<i::Struct> struct_obj =
Steve Block44f0eee2011-05-26 01:26:41 +01001343 isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001344 i::Handle<i::ObjectTemplateInfo> obj =
1345 i::Handle<i::ObjectTemplateInfo>::cast(struct_obj);
1346 InitializeTemplate(obj, Consts::OBJECT_TEMPLATE);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001347 int next_serial_number = 0;
1348 if (!do_not_cache) {
1349 next_serial_number = isolate->next_serial_number() + 1;
1350 isolate->set_next_serial_number(next_serial_number);
1351 }
1352 obj->set_serial_number(i::Smi::FromInt(next_serial_number));
Steve Blocka7e24c12009-10-30 11:49:00 +00001353 if (!constructor.IsEmpty())
1354 obj->set_constructor(*Utils::OpenHandle(*constructor));
1355 obj->set_internal_field_count(i::Smi::FromInt(0));
1356 return Utils::ToLocal(obj);
1357}
1358
Ben Murdoch097c5b22016-05-18 11:27:45 +01001359Local<ObjectTemplate> ObjectTemplate::New(
1360 i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
1361 return ObjectTemplateNew(isolate, constructor, false);
1362}
Steve Blocka7e24c12009-10-30 11:49:00 +00001363
1364// Ensure that the object template has a constructor. If no
1365// constructor is available we create one.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001366static i::Handle<i::FunctionTemplateInfo> EnsureConstructor(
1367 i::Isolate* isolate,
1368 ObjectTemplate* object_template) {
1369 i::Object* obj = Utils::OpenHandle(object_template)->constructor();
1370 if (!obj ->IsUndefined()) {
1371 i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj);
1372 return i::Handle<i::FunctionTemplateInfo>(info, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001373 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001374 Local<FunctionTemplate> templ =
1375 FunctionTemplate::New(reinterpret_cast<Isolate*>(isolate));
1376 i::Handle<i::FunctionTemplateInfo> constructor = Utils::OpenHandle(*templ);
1377 constructor->set_instance_template(*Utils::OpenHandle(object_template));
1378 Utils::OpenHandle(object_template)->set_constructor(*constructor);
1379 return constructor;
1380}
1381
1382
Ben Murdoch097c5b22016-05-18 11:27:45 +01001383template <typename Getter, typename Setter, typename Data, typename Template>
1384static bool TemplateSetAccessor(Template* template_obj, v8::Local<Name> name,
1385 Getter getter, Setter setter, Data data,
1386 AccessControl settings,
1387 PropertyAttribute attribute,
1388 v8::Local<AccessorSignature> signature,
1389 bool is_special_data_property) {
1390 auto info = Utils::OpenHandle(template_obj);
1391 auto isolate = info->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001392 ENTER_V8(isolate);
1393 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001394 auto obj = MakeAccessorInfo(name, getter, setter, data, settings, attribute,
Ben Murdoch097c5b22016-05-18 11:27:45 +01001395 signature, is_special_data_property);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001396 if (obj.is_null()) return false;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001397 i::ApiNatives::AddNativeDataProperty(isolate, info, obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001398 return true;
1399}
1400
1401
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001402void Template::SetNativeDataProperty(v8::Local<String> name,
1403 AccessorGetterCallback getter,
1404 AccessorSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001405 v8::Local<Value> data,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001406 PropertyAttribute attribute,
1407 v8::Local<AccessorSignature> signature,
1408 AccessControl settings) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001409 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1410 signature, true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001411}
1412
1413
1414void Template::SetNativeDataProperty(v8::Local<Name> name,
1415 AccessorNameGetterCallback getter,
1416 AccessorNameSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001417 v8::Local<Value> data,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001418 PropertyAttribute attribute,
1419 v8::Local<AccessorSignature> signature,
1420 AccessControl settings) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001421 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1422 signature, true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001423}
1424
1425
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001426void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
1427 PropertyAttribute attribute) {
1428 auto templ = Utils::OpenHandle(this);
1429 i::Isolate* isolate = templ->GetIsolate();
1430 ENTER_V8(isolate);
1431 i::HandleScope scope(isolate);
1432 i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
1433 intrinsic,
1434 static_cast<i::PropertyAttributes>(attribute));
1435}
1436
1437
1438void ObjectTemplate::SetAccessor(v8::Local<String> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001439 AccessorGetterCallback getter,
1440 AccessorSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001441 v8::Local<Value> data, AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001442 PropertyAttribute attribute,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001443 v8::Local<AccessorSignature> signature) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001444 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1445 signature, i::FLAG_disable_old_api_accessors);
Steve Blocka7e24c12009-10-30 11:49:00 +00001446}
1447
1448
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001449void ObjectTemplate::SetAccessor(v8::Local<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001450 AccessorNameGetterCallback getter,
1451 AccessorNameSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001452 v8::Local<Value> data, AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001453 PropertyAttribute attribute,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001454 v8::Local<AccessorSignature> signature) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001455 TemplateSetAccessor(this, name, getter, setter, data, settings, attribute,
1456 signature, i::FLAG_disable_old_api_accessors);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001457}
1458
1459
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001460template <typename Getter, typename Setter, typename Query, typename Deleter,
1461 typename Enumerator>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001462static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
1463 Getter getter, Setter setter,
1464 Query query, Deleter remover,
1465 Enumerator enumerator,
1466 Local<Value> data,
1467 PropertyHandlerFlags flags) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001468 i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001469 ENTER_V8(isolate);
1470 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001471 auto cons = EnsureConstructor(isolate, templ);
1472 EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001473 auto obj = i::Handle<i::InterceptorInfo>::cast(
1474 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001475 obj->set_flags(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001476
1477 if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
1478 if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
1479 if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
1480 if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
1481 if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001482 obj->set_can_intercept_symbols(
1483 !(static_cast<int>(flags) &
1484 static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001485 obj->set_all_can_read(static_cast<int>(flags) &
1486 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001487 obj->set_non_masking(static_cast<int>(flags) &
1488 static_cast<int>(PropertyHandlerFlags::kNonMasking));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001489
1490 if (data.IsEmpty()) {
1491 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1492 }
1493 obj->set_data(*Utils::OpenHandle(*data));
1494 cons->set_named_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001495}
1496
1497
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001498void ObjectTemplate::SetNamedPropertyHandler(
1499 NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
1500 NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001501 NamedPropertyEnumeratorCallback enumerator, Local<Value> data) {
1502 ObjectTemplateSetNamedPropertyHandler(
1503 this, getter, setter, query, remover, enumerator, data,
1504 PropertyHandlerFlags::kOnlyInterceptStrings);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001505}
1506
1507
1508void ObjectTemplate::SetHandler(
1509 const NamedPropertyHandlerConfiguration& config) {
1510 ObjectTemplateSetNamedPropertyHandler(
1511 this, config.getter, config.setter, config.query, config.deleter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001512 config.enumerator, config.data, config.flags);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001513}
1514
1515
Steve Blocka7e24c12009-10-30 11:49:00 +00001516void ObjectTemplate::MarkAsUndetectable() {
Steve Block44f0eee2011-05-26 01:26:41 +01001517 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001518 ENTER_V8(isolate);
1519 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001520 auto cons = EnsureConstructor(isolate, this);
1521 EnsureNotInstantiated(cons, "v8::ObjectTemplate::MarkAsUndetectable");
Steve Blocka7e24c12009-10-30 11:49:00 +00001522 cons->set_undetectable(true);
1523}
1524
1525
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001526void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
1527 Local<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001528 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001529 ENTER_V8(isolate);
1530 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001531 auto cons = EnsureConstructor(isolate, this);
1532 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
Steve Blocka7e24c12009-10-30 11:49:00 +00001533
1534 i::Handle<i::Struct> struct_info =
Steve Block44f0eee2011-05-26 01:26:41 +01001535 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
Steve Blocka7e24c12009-10-30 11:49:00 +00001536 i::Handle<i::AccessCheckInfo> info =
1537 i::Handle<i::AccessCheckInfo>::cast(struct_info);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001538
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001539 SET_FIELD_WRAPPED(info, set_callback, callback);
1540 SET_FIELD_WRAPPED(info, set_named_callback, nullptr);
1541 SET_FIELD_WRAPPED(info, set_indexed_callback, nullptr);
1542
1543 if (data.IsEmpty()) {
1544 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1545 }
1546 info->set_data(*Utils::OpenHandle(*data));
1547
1548 cons->set_access_check_info(*info);
1549 cons->set_needs_access_check(true);
1550}
1551
Ben Murdoch097c5b22016-05-18 11:27:45 +01001552void ObjectTemplate::SetAccessCheckCallback(
1553 DeprecatedAccessCheckCallback callback, Local<Value> data) {
1554 SetAccessCheckCallback(reinterpret_cast<AccessCheckCallback>(callback), data);
1555}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001556
1557void ObjectTemplate::SetAccessCheckCallbacks(
1558 NamedSecurityCallback named_callback,
1559 IndexedSecurityCallback indexed_callback, Local<Value> data) {
1560 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
1561 ENTER_V8(isolate);
1562 i::HandleScope scope(isolate);
1563 auto cons = EnsureConstructor(isolate, this);
1564 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallbacks");
1565
1566 i::Handle<i::Struct> struct_info =
1567 isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
1568 i::Handle<i::AccessCheckInfo> info =
1569 i::Handle<i::AccessCheckInfo>::cast(struct_info);
1570
1571 SET_FIELD_WRAPPED(info, set_callback, nullptr);
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001572 SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
1573 SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
1574
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001575 if (data.IsEmpty()) {
1576 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1577 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001578 info->set_data(*Utils::OpenHandle(*data));
1579
Steve Blocka7e24c12009-10-30 11:49:00 +00001580 cons->set_access_check_info(*info);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001581 cons->set_needs_access_check(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00001582}
1583
1584
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001585void ObjectTemplate::SetHandler(
1586 const IndexedPropertyHandlerConfiguration& config) {
Steve Block44f0eee2011-05-26 01:26:41 +01001587 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001588 ENTER_V8(isolate);
1589 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001590 auto cons = EnsureConstructor(isolate, this);
1591 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001592 auto obj = i::Handle<i::InterceptorInfo>::cast(
1593 isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001594 obj->set_flags(0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001595
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001596 if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
1597 if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
1598 if (config.query != 0) SET_FIELD_WRAPPED(obj, set_query, config.query);
1599 if (config.deleter != 0) SET_FIELD_WRAPPED(obj, set_deleter, config.deleter);
1600 if (config.enumerator != 0) {
1601 SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
1602 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001603 obj->set_all_can_read(static_cast<int>(config.flags) &
1604 static_cast<int>(PropertyHandlerFlags::kAllCanRead));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001605
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001606 v8::Local<v8::Value> data = config.data;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001607 if (data.IsEmpty()) {
1608 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1609 }
1610 obj->set_data(*Utils::OpenHandle(*data));
1611 cons->set_indexed_property_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001612}
1613
1614
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001615void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001616 Local<Value> data) {
Steve Block44f0eee2011-05-26 01:26:41 +01001617 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01001618 ENTER_V8(isolate);
1619 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001620 auto cons = EnsureConstructor(isolate, this);
1621 EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001622 i::Handle<i::Struct> struct_obj =
1623 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
1624 i::Handle<i::CallHandlerInfo> obj =
1625 i::Handle<i::CallHandlerInfo>::cast(struct_obj);
1626 SET_FIELD_WRAPPED(obj, set_callback, callback);
1627 if (data.IsEmpty()) {
1628 data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
1629 }
1630 obj->set_data(*Utils::OpenHandle(*data));
1631 cons->set_instance_call_handler(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00001632}
1633
1634
1635int ObjectTemplate::InternalFieldCount() {
Steve Blocka7e24c12009-10-30 11:49:00 +00001636 return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value();
1637}
1638
1639
1640void ObjectTemplate::SetInternalFieldCount(int value) {
Steve Block44f0eee2011-05-26 01:26:41 +01001641 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001642 if (!Utils::ApiCheck(i::Smi::IsValid(value),
1643 "v8::ObjectTemplate::SetInternalFieldCount()",
1644 "Invalid internal field count")) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001645 return;
1646 }
Steve Block44f0eee2011-05-26 01:26:41 +01001647 ENTER_V8(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001648 if (value > 0) {
1649 // The internal field count is set by the constructor function's
1650 // construct code, so we ensure that there is a constructor
1651 // function to do the setting.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001652 EnsureConstructor(isolate, this);
Steve Blocka7e24c12009-10-30 11:49:00 +00001653 }
1654 Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value));
1655}
1656
1657
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001658// --- S c r i p t s ---
Steve Blocka7e24c12009-10-30 11:49:00 +00001659
1660
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001661// Internally, UnboundScript is a SharedFunctionInfo, and Script is a
1662// JSFunction.
1663
1664ScriptCompiler::CachedData::CachedData(const uint8_t* data_, int length_,
1665 BufferPolicy buffer_policy_)
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001666 : data(data_),
1667 length(length_),
1668 rejected(false),
1669 buffer_policy(buffer_policy_) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001670
1671
1672ScriptCompiler::CachedData::~CachedData() {
1673 if (buffer_policy == BufferOwned) {
1674 delete[] data;
1675 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001676}
1677
1678
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001679bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; }
1680
1681
1682void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); }
1683
1684
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001685ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
1686 Encoding encoding)
1687 : impl_(new i::StreamedSource(stream, encoding)) {}
1688
1689
1690ScriptCompiler::StreamedSource::~StreamedSource() { delete impl_; }
1691
1692
1693const ScriptCompiler::CachedData*
1694ScriptCompiler::StreamedSource::GetCachedData() const {
1695 return impl_->cached_data.get();
1696}
1697
1698
1699Local<Script> UnboundScript::BindToCurrentContext() {
1700 i::Handle<i::HeapObject> obj =
1701 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1702 i::Handle<i::SharedFunctionInfo>
1703 function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001704 i::Isolate* isolate = obj->GetIsolate();
1705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001706 i::Handle<i::JSReceiver> global(isolate->native_context()->global_object());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001707 i::Handle<i::JSFunction> function =
1708 obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001709 function_info, isolate->native_context());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001710 return ToApiHandle<Script>(function);
1711}
1712
1713
1714int UnboundScript::GetId() {
1715 i::Handle<i::HeapObject> obj =
1716 i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
1717 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001718 LOG_API(isolate, "v8::UnboundScript::GetId");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001719 i::HandleScope scope(isolate);
1720 i::Handle<i::SharedFunctionInfo> function_info(
1721 i::SharedFunctionInfo::cast(*obj));
1722 i::Handle<i::Script> script(i::Script::cast(function_info->script()));
1723 return script->id();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001724}
1725
1726
1727int UnboundScript::GetLineNumber(int code_pos) {
1728 i::Handle<i::SharedFunctionInfo> obj =
1729 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1730 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001731 LOG_API(isolate, "UnboundScript::GetLineNumber");
1732 if (obj->script()->IsScript()) {
1733 i::Handle<i::Script> script(i::Script::cast(obj->script()));
1734 return i::Script::GetLineNumber(script, code_pos);
Ben Murdochb0fe1622011-05-05 13:52:32 +01001735 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001736 return -1;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001737 }
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01001738}
1739
1740
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001741Local<Value> UnboundScript::GetScriptName() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001742 i::Handle<i::SharedFunctionInfo> obj =
1743 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1744 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001745 LOG_API(isolate, "UnboundScript::GetName");
1746 if (obj->script()->IsScript()) {
1747 i::Object* name = i::Script::cast(obj->script())->name();
1748 return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
1749 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001750 return Local<String>();
Leon Clarkef7060e22010-06-03 12:02:55 +01001751 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001752}
Leon Clarkef7060e22010-06-03 12:02:55 +01001753
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001754
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001755Local<Value> UnboundScript::GetSourceURL() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001756 i::Handle<i::SharedFunctionInfo> obj =
1757 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1758 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001759 LOG_API(isolate, "UnboundScript::GetSourceURL");
1760 if (obj->script()->IsScript()) {
1761 i::Object* url = i::Script::cast(obj->script())->source_url();
1762 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1763 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001764 return Local<String>();
Iain Merrick9ac36c92010-09-13 15:29:50 +01001765 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001766}
1767
1768
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001769Local<Value> UnboundScript::GetSourceMappingURL() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001770 i::Handle<i::SharedFunctionInfo> obj =
1771 i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
1772 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001773 LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
1774 if (obj->script()->IsScript()) {
1775 i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
1776 return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
1777 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001778 return Local<String>();
Ben Murdoch692be652012-01-10 18:47:50 +00001779 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001780}
1781
1782
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001783MaybeLocal<Value> Script::Run(Local<Context> context) {
1784 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Script::Run()", Value)
1785 i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
1786 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001787 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001788 auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
1789 i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
1790 Local<Value> result;
1791 has_pending_exception =
1792 !ToLocal<Value>(i::Execution::Call(isolate, fun, receiver, 0, NULL),
1793 &result);
1794 RETURN_ON_FAILED_EXECUTION(Value);
1795 RETURN_ESCAPED(result);
1796}
1797
1798
Steve Blocka7e24c12009-10-30 11:49:00 +00001799Local<Value> Script::Run() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001800 auto self = Utils::OpenHandle(this, true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001801 // If execution is terminating, Compile(..)->Run() requires this
1802 // check.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001803 if (self.is_null()) return Local<Value>();
1804 auto context = ContextFromHeapObject(self);
1805 RETURN_TO_LOCAL_UNCHECKED(Run(context), Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001806}
1807
1808
1809Local<UnboundScript> Script::GetUnboundScript() {
1810 i::Handle<i::Object> obj = Utils::OpenHandle(this);
1811 return ToApiHandle<UnboundScript>(
1812 i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
1813}
1814
1815
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001816MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
1817 Isolate* v8_isolate, Source* source, CompileOptions options,
1818 bool is_module) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001819 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001820 PREPARE_FOR_EXECUTION_WITH_ISOLATE(
1821 isolate, "v8::ScriptCompiler::CompileUnbound()", UnboundScript);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001822
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001823 // Don't try to produce any kind of cache when the debugger is loaded.
1824 if (isolate->debug()->is_loaded() &&
1825 (options == kProduceParserCache || options == kProduceCodeCache)) {
1826 options = kNoCompileOptions;
1827 }
1828
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001829 i::ScriptData* script_data = NULL;
1830 if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1831 DCHECK(source->cached_data);
1832 // ScriptData takes care of pointer-aligning the data.
1833 script_data = new i::ScriptData(source->cached_data->data,
1834 source->cached_data->length);
1835 }
1836
1837 i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001838 i::Handle<i::SharedFunctionInfo> result;
1839 {
1840 i::HistogramTimerScope total(isolate->counters()->compile_script(), true);
Ben Murdoch097c5b22016-05-18 11:27:45 +01001841 TRACE_EVENT0("v8", "V8.CompileScript");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001842 i::Handle<i::Object> name_obj;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001843 i::Handle<i::Object> source_map_url;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001844 int line_offset = 0;
1845 int column_offset = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001846 if (!source->resource_name.IsEmpty()) {
1847 name_obj = Utils::OpenHandle(*(source->resource_name));
1848 }
1849 if (!source->resource_line_offset.IsEmpty()) {
1850 line_offset = static_cast<int>(source->resource_line_offset->Value());
1851 }
1852 if (!source->resource_column_offset.IsEmpty()) {
1853 column_offset =
1854 static_cast<int>(source->resource_column_offset->Value());
1855 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001856 if (!source->source_map_url.IsEmpty()) {
1857 source_map_url = Utils::OpenHandle(*(source->source_map_url));
Steve Blocka7e24c12009-10-30 11:49:00 +00001858 }
Ben Murdochda12d292016-06-02 14:46:10 +01001859 result = i::Compiler::GetSharedFunctionInfoForScript(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001860 str, name_obj, line_offset, column_offset, source->resource_options,
1861 source_map_url, isolate->native_context(), NULL, &script_data, options,
1862 i::NOT_NATIVES_CODE, is_module);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001863 has_pending_exception = result.is_null();
1864 if (has_pending_exception && script_data != NULL) {
1865 // This case won't happen during normal operation; we have compiled
1866 // successfully and produced cached data, and but the second compilation
1867 // of the same source code fails.
1868 delete script_data;
1869 script_data = NULL;
1870 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001871 RETURN_ON_FAILED_EXECUTION(UnboundScript);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001872
1873 if ((options == kProduceParserCache || options == kProduceCodeCache) &&
1874 script_data != NULL) {
1875 // script_data now contains the data that was generated. source will
1876 // take the ownership.
1877 source->cached_data = new CachedData(
1878 script_data->data(), script_data->length(), CachedData::BufferOwned);
1879 script_data->ReleaseDataOwnership();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001880 } else if (options == kConsumeParserCache || options == kConsumeCodeCache) {
1881 source->cached_data->rejected = script_data->rejected();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001882 }
1883 delete script_data;
Steve Blocka7e24c12009-10-30 11:49:00 +00001884 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001885 RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
1886}
1887
1888
1889MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
1890 Isolate* v8_isolate, Source* source, CompileOptions options) {
1891 return CompileUnboundInternal(v8_isolate, source, options, false);
1892}
1893
1894
1895Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate,
1896 Source* source,
1897 CompileOptions options) {
1898 RETURN_TO_LOCAL_UNCHECKED(
1899 CompileUnboundInternal(v8_isolate, source, options, false),
1900 UnboundScript);
1901}
1902
1903
1904MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
1905 Source* source,
1906 CompileOptions options) {
1907 auto isolate = context->GetIsolate();
1908 auto maybe = CompileUnboundInternal(isolate, source, options, false);
1909 Local<UnboundScript> result;
1910 if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
1911 v8::Context::Scope scope(context);
1912 return result->BindToCurrentContext();
Steve Blocka7e24c12009-10-30 11:49:00 +00001913}
1914
1915
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001916Local<Script> ScriptCompiler::Compile(
1917 Isolate* v8_isolate,
1918 Source* source,
1919 CompileOptions options) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001920 auto context = v8_isolate->GetCurrentContext();
1921 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, options), Script);
1922}
1923
1924
1925MaybeLocal<Script> ScriptCompiler::CompileModule(Local<Context> context,
1926 Source* source,
1927 CompileOptions options) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001928 auto isolate = context->GetIsolate();
1929 auto maybe = CompileUnboundInternal(isolate, source, options, true);
1930 Local<UnboundScript> generic;
1931 if (!maybe.ToLocal(&generic)) return MaybeLocal<Script>();
1932 v8::Context::Scope scope(context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001933 return generic->BindToCurrentContext();
Steve Block6ded16b2010-05-10 14:33:55 +01001934}
1935
1936
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001937class IsIdentifierHelper {
1938 public:
1939 IsIdentifierHelper() : is_identifier_(false), first_char_(true) {}
1940
1941 bool Check(i::String* string) {
1942 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
1943 if (cons_string == NULL) return is_identifier_;
1944 // We don't support cons strings here.
1945 return false;
1946 }
1947 void VisitOneByteString(const uint8_t* chars, int length) {
1948 for (int i = 0; i < length; ++i) {
1949 if (first_char_) {
1950 first_char_ = false;
1951 is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
1952 } else {
1953 is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
1954 }
1955 }
1956 }
1957 void VisitTwoByteString(const uint16_t* chars, int length) {
1958 for (int i = 0; i < length; ++i) {
1959 if (first_char_) {
1960 first_char_ = false;
1961 is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
1962 } else {
1963 is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
1964 }
1965 }
1966 }
1967
1968 private:
1969 bool is_identifier_;
1970 bool first_char_;
1971 i::UnicodeCache unicode_cache_;
1972 DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper);
1973};
1974
1975
1976MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
1977 Local<Context> v8_context, Source* source, size_t arguments_count,
1978 Local<String> arguments[], size_t context_extension_count,
1979 Local<Object> context_extensions[]) {
1980 PREPARE_FOR_EXECUTION(
1981 v8_context, "v8::ScriptCompiler::CompileFunctionInContext()", Function);
1982 i::Handle<i::String> source_string;
1983 auto factory = isolate->factory();
1984 if (arguments_count) {
1985 source_string = factory->NewStringFromStaticChars("(function(");
1986 for (size_t i = 0; i < arguments_count; ++i) {
1987 IsIdentifierHelper helper;
1988 if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) {
1989 return Local<Function>();
1990 }
1991 has_pending_exception =
1992 !factory->NewConsString(source_string,
1993 Utils::OpenHandle(*arguments[i]))
1994 .ToHandle(&source_string);
1995 RETURN_ON_FAILED_EXECUTION(Function);
1996 if (i + 1 == arguments_count) continue;
1997 has_pending_exception =
1998 !factory->NewConsString(source_string,
1999 factory->LookupSingleCharacterStringFromCode(
2000 ',')).ToHandle(&source_string);
2001 RETURN_ON_FAILED_EXECUTION(Function);
2002 }
2003 auto brackets = factory->NewStringFromStaticChars("){");
2004 has_pending_exception = !factory->NewConsString(source_string, brackets)
2005 .ToHandle(&source_string);
2006 RETURN_ON_FAILED_EXECUTION(Function);
2007 } else {
2008 source_string = factory->NewStringFromStaticChars("(function(){");
2009 }
2010
2011 int scope_position = source_string->length();
2012 has_pending_exception =
2013 !factory->NewConsString(source_string,
2014 Utils::OpenHandle(*source->source_string))
2015 .ToHandle(&source_string);
2016 RETURN_ON_FAILED_EXECUTION(Function);
2017 // Include \n in case the source contains a line end comment.
2018 auto brackets = factory->NewStringFromStaticChars("\n})");
2019 has_pending_exception =
2020 !factory->NewConsString(source_string, brackets).ToHandle(&source_string);
2021 RETURN_ON_FAILED_EXECUTION(Function);
2022
2023 i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
2024 i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(),
2025 isolate);
2026 for (size_t i = 0; i < context_extension_count; ++i) {
2027 i::Handle<i::JSReceiver> extension =
2028 Utils::OpenHandle(*context_extensions[i]);
2029 if (!extension->IsJSObject()) return Local<Function>();
2030 i::Handle<i::JSFunction> closure(context->closure(), isolate);
2031 context = factory->NewWithContext(closure, context, extension);
2032 }
2033
2034 i::Handle<i::Object> name_obj;
2035 int line_offset = 0;
2036 int column_offset = 0;
2037 if (!source->resource_name.IsEmpty()) {
2038 name_obj = Utils::OpenHandle(*(source->resource_name));
2039 }
2040 if (!source->resource_line_offset.IsEmpty()) {
2041 line_offset = static_cast<int>(source->resource_line_offset->Value());
2042 }
2043 if (!source->resource_column_offset.IsEmpty()) {
2044 column_offset = static_cast<int>(source->resource_column_offset->Value());
2045 }
2046 i::Handle<i::JSFunction> fun;
2047 has_pending_exception = !i::Compiler::GetFunctionFromEval(
2048 source_string, outer_info, context, i::SLOPPY,
2049 i::ONLY_SINGLE_FUNCTION_LITERAL, line_offset,
2050 column_offset - scope_position, name_obj,
2051 source->resource_options).ToHandle(&fun);
2052 if (has_pending_exception) {
2053 isolate->ReportPendingMessages();
2054 }
2055 RETURN_ON_FAILED_EXECUTION(Function);
2056
2057 i::Handle<i::Object> result;
2058 has_pending_exception =
2059 !i::Execution::Call(isolate, fun,
2060 Utils::OpenHandle(*v8_context->Global()), 0,
2061 nullptr).ToHandle(&result);
2062 RETURN_ON_FAILED_EXECUTION(Function);
2063 RETURN_ESCAPED(
2064 Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(result)));
2065}
2066
2067
2068Local<Function> ScriptCompiler::CompileFunctionInContext(
2069 Isolate* v8_isolate, Source* source, Local<Context> v8_context,
2070 size_t arguments_count, Local<String> arguments[],
2071 size_t context_extension_count, Local<Object> context_extensions[]) {
2072 RETURN_TO_LOCAL_UNCHECKED(
2073 CompileFunctionInContext(v8_context, source, arguments_count, arguments,
2074 context_extension_count, context_extensions),
2075 Function);
2076}
2077
2078
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002079ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
2080 Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
2081 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002082 return new i::BackgroundParsingTask(source->impl(), options,
2083 i::FLAG_stack_size, isolate);
2084}
2085
2086
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002087MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
2088 StreamedSource* v8_source,
2089 Local<String> full_source_string,
2090 const ScriptOrigin& origin) {
2091 PREPARE_FOR_EXECUTION(context, "v8::ScriptCompiler::Compile()", Script);
2092 i::StreamedSource* source = v8_source->impl();
2093 i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
2094 i::Handle<i::Script> script = isolate->factory()->NewScript(str);
2095 if (!origin.ResourceName().IsEmpty()) {
2096 script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
2097 }
2098 if (!origin.ResourceLineOffset().IsEmpty()) {
2099 script->set_line_offset(
2100 static_cast<int>(origin.ResourceLineOffset()->Value()));
2101 }
2102 if (!origin.ResourceColumnOffset().IsEmpty()) {
2103 script->set_column_offset(
2104 static_cast<int>(origin.ResourceColumnOffset()->Value()));
2105 }
2106 script->set_origin_options(origin.Options());
2107 if (!origin.SourceMapUrl().IsEmpty()) {
2108 script->set_source_mapping_url(
2109 *Utils::OpenHandle(*(origin.SourceMapUrl())));
2110 }
2111
2112 source->info->set_script(script);
2113 source->info->set_context(isolate->native_context());
2114
2115 // Do the parsing tasks which need to be done on the main thread. This will
2116 // also handle parse errors.
2117 source->parser->Internalize(isolate, script,
2118 source->info->literal() == nullptr);
2119 source->parser->HandleSourceURLComments(isolate, script);
2120
2121 i::Handle<i::SharedFunctionInfo> result;
2122 if (source->info->literal() != nullptr) {
2123 // Parsing has succeeded.
Ben Murdochda12d292016-06-02 14:46:10 +01002124 result = i::Compiler::GetSharedFunctionInfoForStreamedScript(
2125 script, source->info.get(), str->length());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002126 }
2127 has_pending_exception = result.is_null();
2128 if (has_pending_exception) isolate->ReportPendingMessages();
2129 RETURN_ON_FAILED_EXECUTION(Script);
2130
2131 source->info->clear_script(); // because script goes out of scope.
2132
2133 Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
2134 if (generic.IsEmpty()) return Local<Script>();
2135 Local<Script> bound = generic->BindToCurrentContext();
2136 if (bound.IsEmpty()) return Local<Script>();
2137 RETURN_ESCAPED(bound);
2138}
2139
2140
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002141Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
2142 StreamedSource* v8_source,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002143 Local<String> full_source_string,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002144 const ScriptOrigin& origin) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002145 auto context = v8_isolate->GetCurrentContext();
2146 RETURN_TO_LOCAL_UNCHECKED(
2147 Compile(context, v8_source, full_source_string, origin), Script);
Steve Blocka7e24c12009-10-30 11:49:00 +00002148}
2149
2150
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002151uint32_t ScriptCompiler::CachedDataVersionTag() {
2152 return static_cast<uint32_t>(base::hash_combine(
2153 internal::Version::Hash(), internal::FlagList::Hash(),
2154 static_cast<uint32_t>(internal::CpuFeatures::SupportedFeatures())));
2155}
2156
2157
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002158MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
2159 ScriptOrigin* origin) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002160 if (origin) {
2161 ScriptCompiler::Source script_source(source, *origin);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002162 return ScriptCompiler::Compile(context, &script_source);
Steve Blocka7e24c12009-10-30 11:49:00 +00002163 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002164 ScriptCompiler::Source script_source(source);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002165 return ScriptCompiler::Compile(context, &script_source);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002166}
2167
2168
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002169Local<Script> Script::Compile(v8::Local<String> source,
2170 v8::ScriptOrigin* origin) {
2171 auto str = Utils::OpenHandle(*source);
2172 auto context = ContextFromHeapObject(str);
2173 RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script);
2174}
2175
2176
2177Local<Script> Script::Compile(v8::Local<String> source,
2178 v8::Local<String> file_name) {
2179 auto str = Utils::OpenHandle(*source);
2180 auto context = ContextFromHeapObject(str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002181 ScriptOrigin origin(file_name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002182 return Compile(context, source, &origin).FromMaybe(Local<Script>());
Steve Blocka7e24c12009-10-30 11:49:00 +00002183}
2184
2185
2186// --- E x c e p t i o n s ---
2187
2188
2189v8::TryCatch::TryCatch()
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002190 : isolate_(i::Isolate::Current()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002191 next_(isolate_->try_catch_handler()),
Steve Blocka7e24c12009-10-30 11:49:00 +00002192 is_verbose_(false),
2193 can_continue_(true),
2194 capture_message_(true),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002195 rethrow_(false),
2196 has_terminated_(false) {
2197 ResetInternal();
2198 // Special handling for simulators which have a separate JS stack.
2199 js_stack_comparable_address_ =
2200 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002201 isolate_, v8::internal::GetCurrentStackPosition()));
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002202 isolate_->RegisterTryCatchHandler(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00002203}
2204
2205
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002206v8::TryCatch::TryCatch(v8::Isolate* isolate)
2207 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
2208 next_(isolate_->try_catch_handler()),
2209 is_verbose_(false),
2210 can_continue_(true),
2211 capture_message_(true),
2212 rethrow_(false),
2213 has_terminated_(false) {
2214 ResetInternal();
2215 // Special handling for simulators which have a separate JS stack.
2216 js_stack_comparable_address_ =
2217 reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002218 isolate_, v8::internal::GetCurrentStackPosition()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002219 isolate_->RegisterTryCatchHandler(this);
2220}
2221
2222
Steve Blocka7e24c12009-10-30 11:49:00 +00002223v8::TryCatch::~TryCatch() {
Steve Blockd0582a62009-12-15 09:54:21 +00002224 if (rethrow_) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002225 v8::Isolate* isolate = reinterpret_cast<Isolate*>(isolate_);
2226 v8::HandleScope scope(isolate);
2227 v8::Local<v8::Value> exc = v8::Local<v8::Value>::New(isolate, Exception());
2228 if (HasCaught() && capture_message_) {
2229 // If an exception was caught and rethrow_ is indicated, the saved
2230 // message, script, and location need to be restored to Isolate TLS
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002231 // for reuse. capture_message_ needs to be disabled so that Throw()
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002232 // does not create a new message.
2233 isolate_->thread_local_top()->rethrowing_message_ = true;
2234 isolate_->RestorePendingMessageFromTryCatch(this);
2235 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002236 isolate_->UnregisterTryCatchHandler(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002237 v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002238 reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
2239 DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
Steve Blockd0582a62009-12-15 09:54:21 +00002240 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002241 if (HasCaught() && isolate_->has_scheduled_exception()) {
2242 // If an exception was caught but is still scheduled because no API call
2243 // promoted it, then it is canceled to prevent it from being propagated.
2244 // Note that this will not cancel termination exceptions.
2245 isolate_->CancelScheduledExceptionFromTryCatch(this);
2246 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002247 isolate_->UnregisterTryCatchHandler(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002248 v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_);
Steve Blockd0582a62009-12-15 09:54:21 +00002249 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002250}
2251
2252
2253bool v8::TryCatch::HasCaught() const {
2254 return !reinterpret_cast<i::Object*>(exception_)->IsTheHole();
2255}
2256
2257
2258bool v8::TryCatch::CanContinue() const {
2259 return can_continue_;
2260}
2261
2262
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002263bool v8::TryCatch::HasTerminated() const {
2264 return has_terminated_;
2265}
2266
2267
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002268v8::Local<v8::Value> v8::TryCatch::ReThrow() {
Steve Blockd0582a62009-12-15 09:54:21 +00002269 if (!HasCaught()) return v8::Local<v8::Value>();
2270 rethrow_ = true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002271 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
Steve Blockd0582a62009-12-15 09:54:21 +00002272}
2273
2274
Steve Blocka7e24c12009-10-30 11:49:00 +00002275v8::Local<Value> v8::TryCatch::Exception() const {
2276 if (HasCaught()) {
2277 // Check for out of memory exception.
2278 i::Object* exception = reinterpret_cast<i::Object*>(exception_);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002279 return v8::Utils::ToLocal(i::Handle<i::Object>(exception, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00002280 } else {
2281 return v8::Local<Value>();
2282 }
2283}
2284
2285
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002286MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
2287 if (!HasCaught()) return v8::Local<Value>();
2288 i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
2289 if (!raw_obj->IsJSObject()) return v8::Local<Value>();
2290 PREPARE_FOR_EXECUTION(context, "v8::TryCatch::StackTrace", Value);
2291 i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
2292 i::Handle<i::String> name = isolate->factory()->stack_string();
2293 Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
2294 has_pending_exception = !maybe.IsJust();
2295 RETURN_ON_FAILED_EXECUTION(Value);
2296 if (!maybe.FromJust()) return v8::Local<Value>();
2297 Local<Value> result;
2298 has_pending_exception =
Ben Murdochda12d292016-06-02 14:46:10 +01002299 !ToLocal<Value>(i::JSReceiver::GetProperty(obj, name), &result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002300 RETURN_ON_FAILED_EXECUTION(Value);
2301 RETURN_ESCAPED(result);
2302}
2303
2304
Steve Blocka7e24c12009-10-30 11:49:00 +00002305v8::Local<Value> v8::TryCatch::StackTrace() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002306 auto context = reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext();
2307 RETURN_TO_LOCAL_UNCHECKED(StackTrace(context), Value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002308}
2309
2310
2311v8::Local<v8::Message> v8::TryCatch::Message() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002312 i::Object* message = reinterpret_cast<i::Object*>(message_obj_);
2313 DCHECK(message->IsJSMessageObject() || message->IsTheHole());
2314 if (HasCaught() && !message->IsTheHole()) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002315 return v8::Utils::MessageToLocal(i::Handle<i::Object>(message, isolate_));
Steve Blocka7e24c12009-10-30 11:49:00 +00002316 } else {
2317 return v8::Local<v8::Message>();
2318 }
2319}
2320
2321
2322void v8::TryCatch::Reset() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002323 if (!rethrow_ && HasCaught() && isolate_->has_scheduled_exception()) {
2324 // If an exception was caught but is still scheduled because no API call
2325 // promoted it, then it is canceled to prevent it from being propagated.
2326 // Note that this will not cancel termination exceptions.
2327 isolate_->CancelScheduledExceptionFromTryCatch(this);
2328 }
2329 ResetInternal();
2330}
2331
2332
2333void v8::TryCatch::ResetInternal() {
2334 i::Object* the_hole = isolate_->heap()->the_hole_value();
2335 exception_ = the_hole;
2336 message_obj_ = the_hole;
Steve Blocka7e24c12009-10-30 11:49:00 +00002337}
2338
2339
2340void v8::TryCatch::SetVerbose(bool value) {
2341 is_verbose_ = value;
2342}
2343
2344
2345void v8::TryCatch::SetCaptureMessage(bool value) {
2346 capture_message_ = value;
2347}
2348
2349
2350// --- M e s s a g e ---
2351
2352
2353Local<String> Message::Get() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002354 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002355 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002356 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00002357 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002358 i::Handle<i::String> raw_result = i::MessageHandler::GetMessage(isolate, obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00002359 Local<String> result = Utils::ToLocal(raw_result);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002360 return scope.Escape(result);
2361}
2362
2363
2364ScriptOrigin Message::GetScriptOrigin() const {
2365 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002366 auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
2367 auto script_wraper = i::Handle<i::Object>(message->script(), isolate);
2368 auto script_value = i::Handle<i::JSValue>::cast(script_wraper);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002369 i::Handle<i::Script> script(i::Script::cast(script_value->value()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002370 return GetScriptOriginForScript(isolate, script);
Steve Blocka7e24c12009-10-30 11:49:00 +00002371}
2372
2373
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002374v8::Local<Value> Message::GetScriptResourceName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002375 return GetScriptOrigin().ResourceName();
Steve Blocka7e24c12009-10-30 11:49:00 +00002376}
2377
2378
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002379v8::Local<v8::StackTrace> Message::GetStackTrace() const {
Steve Block44f0eee2011-05-26 01:26:41 +01002380 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002381 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002382 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002383 auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002384 i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002385 if (!stackFramesObj->IsJSArray()) return v8::Local<v8::StackTrace>();
2386 auto stackTrace = i::Handle<i::JSArray>::cast(stackFramesObj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002387 return scope.Escape(Utils::StackTraceToLocal(stackTrace));
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002388}
2389
2390
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002391Maybe<int> Message::GetLineNumber(Local<Context> context) const {
2392 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetLineNumber()", int);
2393 i::Handle<i::JSFunction> fun = isolate->message_get_line_number();
2394 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2395 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
2396 i::Handle<i::Object> result;
2397 has_pending_exception =
2398 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2399 .ToHandle(&result);
2400 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
2401 return Just(static_cast<int>(result->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002402}
2403
2404
2405int Message::GetLineNumber() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002406 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2407 return GetLineNumber(context).FromMaybe(0);
Steve Blocka7e24c12009-10-30 11:49:00 +00002408}
2409
2410
2411int Message::GetStartPosition() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002412 auto self = Utils::OpenHandle(this);
2413 return self->start_position();
Steve Blocka7e24c12009-10-30 11:49:00 +00002414}
2415
2416
2417int Message::GetEndPosition() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002418 auto self = Utils::OpenHandle(this);
2419 return self->end_position();
2420}
2421
2422
2423Maybe<int> Message::GetStartColumn(Local<Context> context) const {
2424 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetStartColumn()",
2425 int);
2426 i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
2427 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2428 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
2429 i::Handle<i::Object> result;
2430 has_pending_exception =
2431 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2432 .ToHandle(&result);
2433 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
2434 return Just(static_cast<int>(result->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00002435}
2436
2437
2438int Message::GetStartColumn() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002439 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2440 const int default_value = kNoColumnInfo;
2441 return GetStartColumn(context).FromMaybe(default_value);
2442}
2443
2444
2445Maybe<int> Message::GetEndColumn(Local<Context> context) const {
2446 auto self = Utils::OpenHandle(this);
2447 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetEndColumn()", int);
2448 i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
2449 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2450 i::Handle<i::Object> args[] = {self};
2451 i::Handle<i::Object> result;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002452 has_pending_exception =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002453 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2454 .ToHandle(&result);
2455 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
2456 int start = self->start_position();
2457 int end = self->end_position();
2458 return Just(static_cast<int>(result->Number()) + (end - start));
Steve Blocka7e24c12009-10-30 11:49:00 +00002459}
2460
2461
2462int Message::GetEndColumn() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002463 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2464 const int default_value = kNoColumnInfo;
2465 return GetEndColumn(context).FromMaybe(default_value);
Steve Blocka7e24c12009-10-30 11:49:00 +00002466}
2467
2468
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002469bool Message::IsSharedCrossOrigin() const {
2470 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2471 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002472 auto self = Utils::OpenHandle(this);
2473 auto script = i::Handle<i::JSValue>::cast(
2474 i::Handle<i::Object>(self->script(), isolate));
2475 return i::Script::cast(script->value())
2476 ->origin_options()
2477 .IsSharedCrossOrigin();
2478}
2479
2480bool Message::IsOpaque() const {
2481 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
2482 ENTER_V8(isolate);
2483 auto self = Utils::OpenHandle(this);
2484 auto script = i::Handle<i::JSValue>::cast(
2485 i::Handle<i::Object>(self->script(), isolate));
2486 return i::Script::cast(script->value())->origin_options().IsOpaque();
2487}
2488
2489
2490MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
2491 PREPARE_FOR_EXECUTION(context, "v8::Message::GetSourceLine()", String);
2492 i::Handle<i::JSFunction> fun = isolate->message_get_source_line();
2493 i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
2494 i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
2495 i::Handle<i::Object> result;
2496 has_pending_exception =
2497 !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
2498 .ToHandle(&result);
2499 RETURN_ON_FAILED_EXECUTION(String);
2500 Local<String> str;
2501 if (result->IsString()) {
2502 str = Utils::ToLocal(i::Handle<i::String>::cast(result));
2503 }
2504 RETURN_ESCAPED(str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002505}
2506
2507
Steve Blocka7e24c12009-10-30 11:49:00 +00002508Local<String> Message::GetSourceLine() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002509 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
2510 RETURN_TO_LOCAL_UNCHECKED(GetSourceLine(context), String)
Steve Blocka7e24c12009-10-30 11:49:00 +00002511}
2512
2513
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002514void Message::PrintCurrentStackTrace(Isolate* isolate, FILE* out) {
2515 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2516 ENTER_V8(i_isolate);
2517 i_isolate->PrintCurrentStackTrace(out);
Steve Blocka7e24c12009-10-30 11:49:00 +00002518}
2519
2520
Kristian Monsen25f61362010-05-21 11:50:48 +01002521// --- S t a c k T r a c e ---
2522
2523Local<StackFrame> StackTrace::GetFrame(uint32_t index) const {
Steve Block44f0eee2011-05-26 01:26:41 +01002524 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002525 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002526 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002527 auto self = Utils::OpenHandle(this);
Ben Murdochda12d292016-06-02 14:46:10 +01002528 auto obj = i::JSReceiver::GetElement(isolate, self, index).ToHandleChecked();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002529 auto jsobj = i::Handle<i::JSObject>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002530 return scope.Escape(Utils::StackFrameToLocal(jsobj));
Kristian Monsen25f61362010-05-21 11:50:48 +01002531}
2532
2533
2534int StackTrace::GetFrameCount() const {
Kristian Monsen25f61362010-05-21 11:50:48 +01002535 return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
2536}
2537
2538
2539Local<Array> StackTrace::AsArray() {
Kristian Monsen25f61362010-05-21 11:50:48 +01002540 return Utils::ToLocal(Utils::OpenHandle(this));
2541}
2542
2543
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002544Local<StackTrace> StackTrace::CurrentStackTrace(
2545 Isolate* isolate,
2546 int frame_limit,
Kristian Monsen25f61362010-05-21 11:50:48 +01002547 StackTraceOptions options) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002548 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
2549 ENTER_V8(i_isolate);
2550 // TODO(dcarney): remove when ScriptDebugServer is fixed.
2551 options = static_cast<StackTraceOptions>(
2552 static_cast<int>(options) | kExposeFramesAcrossSecurityOrigins);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002553 i::Handle<i::JSArray> stackTrace =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002554 i_isolate->CaptureCurrentStackTrace(frame_limit, options);
Ben Murdoch3bec4d22010-07-22 14:51:16 +01002555 return Utils::StackTraceToLocal(stackTrace);
Kristian Monsen25f61362010-05-21 11:50:48 +01002556}
2557
2558
2559// --- S t a c k F r a m e ---
2560
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002561static int getIntProperty(const StackFrame* f, const char* propertyName,
2562 int defaultValue) {
2563 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002564 ENTER_V8(isolate);
2565 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002566 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2567 i::Handle<i::Object> obj =
Ben Murdochda12d292016-06-02 14:46:10 +01002568 i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002569 return obj->IsSmi() ? i::Smi::cast(*obj)->value() : defaultValue;
2570}
2571
2572
2573int StackFrame::GetLineNumber() const {
2574 return getIntProperty(this, "lineNumber", Message::kNoLineNumberInfo);
Kristian Monsen25f61362010-05-21 11:50:48 +01002575}
2576
2577
2578int StackFrame::GetColumn() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002579 return getIntProperty(this, "column", Message::kNoColumnInfo);
2580}
2581
2582
2583int StackFrame::GetScriptId() const {
2584 return getIntProperty(this, "scriptId", Message::kNoScriptIdInfo);
2585}
2586
2587
2588static Local<String> getStringProperty(const StackFrame* f,
2589 const char* propertyName) {
2590 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002591 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002592 EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
2593 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2594 i::Handle<i::Object> obj =
Ben Murdochda12d292016-06-02 14:46:10 +01002595 i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002596 return obj->IsString()
2597 ? scope.Escape(Local<String>::Cast(Utils::ToLocal(obj)))
2598 : Local<String>();
Kristian Monsen25f61362010-05-21 11:50:48 +01002599}
2600
2601
2602Local<String> StackFrame::GetScriptName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002603 return getStringProperty(this, "scriptName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002604}
2605
2606
Ben Murdochf87a2032010-10-22 12:50:53 +01002607Local<String> StackFrame::GetScriptNameOrSourceURL() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002608 return getStringProperty(this, "scriptNameOrSourceURL");
Ben Murdochf87a2032010-10-22 12:50:53 +01002609}
2610
2611
Kristian Monsen25f61362010-05-21 11:50:48 +01002612Local<String> StackFrame::GetFunctionName() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002613 return getStringProperty(this, "functionName");
Kristian Monsen25f61362010-05-21 11:50:48 +01002614}
2615
2616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002617static bool getBoolProperty(const StackFrame* f, const char* propertyName) {
2618 i::Isolate* isolate = Utils::OpenHandle(f)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002619 ENTER_V8(isolate);
2620 i::HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002621 i::Handle<i::JSObject> self = Utils::OpenHandle(f);
2622 i::Handle<i::Object> obj =
Ben Murdochda12d292016-06-02 14:46:10 +01002623 i::JSReceiver::GetProperty(isolate, self, propertyName).ToHandleChecked();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002624 return obj->IsTrue();
Kristian Monsen25f61362010-05-21 11:50:48 +01002625}
2626
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002627bool StackFrame::IsEval() const { return getBoolProperty(this, "isEval"); }
2628
Kristian Monsen25f61362010-05-21 11:50:48 +01002629
2630bool StackFrame::IsConstructor() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002631 return getBoolProperty(this, "isConstructor");
2632}
2633
2634
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002635// --- N a t i v e W e a k M a p ---
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002636
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002637Local<NativeWeakMap> NativeWeakMap::New(Isolate* v8_isolate) {
2638 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2639 ENTER_V8(isolate);
2640 i::Handle<i::JSWeakMap> weakmap = isolate->factory()->NewJSWeakMap();
2641 i::JSWeakCollection::Initialize(weakmap, isolate);
2642 return Utils::NativeWeakMapToLocal(weakmap);
2643}
2644
2645
2646void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) {
2647 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2648 i::Isolate* isolate = weak_collection->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01002649 ENTER_V8(isolate);
2650 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002651 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2652 i::Handle<i::Object> value = Utils::OpenHandle(*v8_value);
2653 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2654 DCHECK(false);
2655 return;
2656 }
2657 i::Handle<i::ObjectHashTable> table(
2658 i::ObjectHashTable::cast(weak_collection->table()));
2659 if (!table->IsKey(*key)) {
2660 DCHECK(false);
2661 return;
2662 }
2663 int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
2664 i::JSWeakCollection::Set(weak_collection, key, value, hash);
2665}
2666
2667
2668Local<Value> NativeWeakMap::Get(Local<Value> v8_key) {
2669 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2670 i::Isolate* isolate = weak_collection->GetIsolate();
2671 ENTER_V8(isolate);
2672 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2673 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2674 DCHECK(false);
2675 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
2676 }
2677 i::Handle<i::ObjectHashTable> table(
2678 i::ObjectHashTable::cast(weak_collection->table()));
2679 if (!table->IsKey(*key)) {
2680 DCHECK(false);
2681 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
2682 }
2683 i::Handle<i::Object> lookup(table->Lookup(key), isolate);
2684 if (lookup->IsTheHole())
2685 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
2686 return Utils::ToLocal(lookup);
2687}
2688
2689
2690bool NativeWeakMap::Has(Local<Value> v8_key) {
2691 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2692 i::Isolate* isolate = weak_collection->GetIsolate();
2693 ENTER_V8(isolate);
2694 i::HandleScope scope(isolate);
2695 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2696 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2697 DCHECK(false);
2698 return false;
2699 }
2700 i::Handle<i::ObjectHashTable> table(
2701 i::ObjectHashTable::cast(weak_collection->table()));
2702 if (!table->IsKey(*key)) {
2703 DCHECK(false);
2704 return false;
2705 }
2706 i::Handle<i::Object> lookup(table->Lookup(key), isolate);
2707 return !lookup->IsTheHole();
2708}
2709
2710
2711bool NativeWeakMap::Delete(Local<Value> v8_key) {
2712 i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
2713 i::Isolate* isolate = weak_collection->GetIsolate();
2714 ENTER_V8(isolate);
2715 i::HandleScope scope(isolate);
2716 i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
2717 if (!key->IsJSReceiver() && !key->IsSymbol()) {
2718 DCHECK(false);
2719 return false;
2720 }
2721 i::Handle<i::ObjectHashTable> table(
2722 i::ObjectHashTable::cast(weak_collection->table()));
2723 if (!table->IsKey(*key)) {
2724 DCHECK(false);
2725 return false;
2726 }
2727 int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
2728 return i::JSWeakCollection::Delete(weak_collection, key, hash);
2729}
2730
2731
2732// --- J S O N ---
2733
2734MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
2735 auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2736 PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, "JSON::Parse", Value);
2737 i::Handle<i::String> string = Utils::OpenHandle(*json_string);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002738 i::Handle<i::String> source = i::String::Flatten(string);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002739 auto maybe = source->IsSeqOneByteString()
2740 ? i::JsonParser<true>::Parse(source)
2741 : i::JsonParser<false>::Parse(source);
2742 Local<Value> result;
2743 has_pending_exception = !ToLocal<Value>(maybe, &result);
2744 RETURN_ON_FAILED_EXECUTION(Value);
2745 RETURN_ESCAPED(result);
2746}
2747
2748
2749Local<Value> JSON::Parse(Local<String> json_string) {
2750 auto isolate = reinterpret_cast<v8::Isolate*>(
2751 Utils::OpenHandle(*json_string)->GetIsolate());
2752 RETURN_TO_LOCAL_UNCHECKED(Parse(isolate, json_string), Value);
Kristian Monsen25f61362010-05-21 11:50:48 +01002753}
2754
2755
Steve Blocka7e24c12009-10-30 11:49:00 +00002756// --- D a t a ---
2757
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002758bool Value::FullIsUndefined() const {
2759 bool result = Utils::OpenHandle(this)->IsUndefined();
2760 DCHECK_EQ(result, QuickIsUndefined());
2761 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002762}
2763
2764
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002765bool Value::FullIsNull() const {
2766 bool result = Utils::OpenHandle(this)->IsNull();
2767 DCHECK_EQ(result, QuickIsNull());
2768 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00002769}
2770
2771
2772bool Value::IsTrue() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002773 return Utils::OpenHandle(this)->IsTrue();
2774}
2775
2776
2777bool Value::IsFalse() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002778 return Utils::OpenHandle(this)->IsFalse();
2779}
2780
2781
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002782bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002783
2784
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002785bool Value::IsName() const {
2786 return Utils::OpenHandle(this)->IsName();
2787}
2788
2789
Steve Blocka7e24c12009-10-30 11:49:00 +00002790bool Value::FullIsString() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002791 bool result = Utils::OpenHandle(this)->IsString();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002792 DCHECK_EQ(result, QuickIsString());
Steve Blocka7e24c12009-10-30 11:49:00 +00002793 return result;
2794}
2795
2796
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002797bool Value::IsSymbol() const {
2798 return Utils::OpenHandle(this)->IsSymbol();
2799}
2800
2801
Steve Blocka7e24c12009-10-30 11:49:00 +00002802bool Value::IsArray() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002803 return Utils::OpenHandle(this)->IsJSArray();
2804}
2805
2806
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002807bool Value::IsArrayBuffer() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002808 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2809 return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002810}
2811
2812
2813bool Value::IsArrayBufferView() const {
2814 return Utils::OpenHandle(this)->IsJSArrayBufferView();
2815}
2816
2817
2818bool Value::IsTypedArray() const {
2819 return Utils::OpenHandle(this)->IsJSTypedArray();
2820}
2821
2822
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002823#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
2824 bool Value::Is##Type##Array() const { \
2825 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2826 return obj->IsJSTypedArray() && \
2827 i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002828 }
2829
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002830
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002831TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
2832
2833#undef VALUE_IS_TYPED_ARRAY
2834
2835
2836bool Value::IsDataView() const {
2837 return Utils::OpenHandle(this)->IsJSDataView();
2838}
2839
2840
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002841bool Value::IsSharedArrayBuffer() const {
2842 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2843 return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared();
Steve Blocka7e24c12009-10-30 11:49:00 +00002844}
2845
2846
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002847bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
2848
2849
Steve Blocka7e24c12009-10-30 11:49:00 +00002850bool Value::IsNumber() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002851 return Utils::OpenHandle(this)->IsNumber();
2852}
2853
2854
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002855bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
2856
2857
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002858#define VALUE_IS_SPECIFIC_TYPE(Type, Class) \
2859 bool Value::Is##Type() const { \
2860 i::Handle<i::Object> obj = Utils::OpenHandle(this); \
2861 if (!obj->IsHeapObject()) return false; \
2862 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate(); \
2863 return obj->HasSpecificClassOf(isolate->heap()->Class##_string()); \
Steve Block44f0eee2011-05-26 01:26:41 +01002864 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002865
2866VALUE_IS_SPECIFIC_TYPE(ArgumentsObject, Arguments)
2867VALUE_IS_SPECIFIC_TYPE(BooleanObject, Boolean)
2868VALUE_IS_SPECIFIC_TYPE(NumberObject, Number)
2869VALUE_IS_SPECIFIC_TYPE(StringObject, String)
2870VALUE_IS_SPECIFIC_TYPE(SymbolObject, Symbol)
2871VALUE_IS_SPECIFIC_TYPE(Date, Date)
2872VALUE_IS_SPECIFIC_TYPE(Map, Map)
2873VALUE_IS_SPECIFIC_TYPE(Set, Set)
2874VALUE_IS_SPECIFIC_TYPE(WeakMap, WeakMap)
2875VALUE_IS_SPECIFIC_TYPE(WeakSet, WeakSet)
2876
2877#undef VALUE_IS_SPECIFIC_TYPE
2878
2879
2880bool Value::IsBoolean() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002881 return Utils::OpenHandle(this)->IsBoolean();
2882}
2883
2884
2885bool Value::IsExternal() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002886 return Utils::OpenHandle(this)->IsExternal();
Steve Blocka7e24c12009-10-30 11:49:00 +00002887}
2888
2889
2890bool Value::IsInt32() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002891 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2892 if (obj->IsSmi()) return true;
2893 if (obj->IsNumber()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002894 return i::IsInt32Double(obj->Number());
Steve Blocka7e24c12009-10-30 11:49:00 +00002895 }
2896 return false;
2897}
2898
2899
Steve Block6ded16b2010-05-10 14:33:55 +01002900bool Value::IsUint32() const {
Steve Block6ded16b2010-05-10 14:33:55 +01002901 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2902 if (obj->IsSmi()) return i::Smi::cast(*obj)->value() >= 0;
2903 if (obj->IsNumber()) {
2904 double value = obj->Number();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002905 return !i::IsMinusZero(value) &&
2906 value >= 0 &&
2907 value <= i::kMaxUInt32 &&
2908 value == i::FastUI2D(i::FastD2UI(value));
Steve Block6ded16b2010-05-10 14:33:55 +01002909 }
2910 return false;
2911}
2912
2913
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002914bool Value::IsNativeError() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002915 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002916 if (!obj->IsJSObject()) return false;
2917 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
2918 i::Isolate* isolate = js_obj->GetIsolate();
2919 i::Handle<i::Object> constructor(js_obj->map()->GetConstructor(), isolate);
2920 if (!constructor->IsJSFunction()) return false;
2921 i::Handle<i::JSFunction> function =
2922 i::Handle<i::JSFunction>::cast(constructor);
2923 if (!function->shared()->native()) return false;
2924 return function.is_identical_to(isolate->error_function()) ||
2925 function.is_identical_to(isolate->eval_error_function()) ||
2926 function.is_identical_to(isolate->range_error_function()) ||
2927 function.is_identical_to(isolate->reference_error_function()) ||
2928 function.is_identical_to(isolate->syntax_error_function()) ||
2929 function.is_identical_to(isolate->type_error_function()) ||
2930 function.is_identical_to(isolate->uri_error_function());
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002931}
2932
2933
Iain Merrick75681382010-08-19 15:07:18 +01002934bool Value::IsRegExp() const {
Iain Merrick75681382010-08-19 15:07:18 +01002935 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2936 return obj->IsJSRegExp();
2937}
2938
2939
Emily Bernierd0a1eb72015-03-24 16:35:39 -04002940bool Value::IsGeneratorFunction() const {
2941 i::Handle<i::Object> obj = Utils::OpenHandle(this);
2942 if (!obj->IsJSFunction()) return false;
2943 i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(obj);
2944 return func->shared()->is_generator();
2945}
2946
2947
2948bool Value::IsGeneratorObject() const {
2949 return Utils::OpenHandle(this)->IsJSGeneratorObject();
2950}
2951
2952
2953bool Value::IsMapIterator() const {
2954 return Utils::OpenHandle(this)->IsJSMapIterator();
2955}
2956
2957
2958bool Value::IsSetIterator() const {
2959 return Utils::OpenHandle(this)->IsJSSetIterator();
2960}
2961
2962
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002963bool Value::IsPromise() const {
2964 auto self = Utils::OpenHandle(this);
2965 return i::Object::IsPromise(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00002966}
2967
2968
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002969MaybeLocal<String> Value::ToString(Local<Context> context) const {
2970 auto obj = Utils::OpenHandle(this);
2971 if (obj->IsString()) return ToApiHandle<String>(obj);
2972 PREPARE_FOR_EXECUTION(context, "ToString", String);
2973 Local<String> result;
2974 has_pending_exception =
2975 !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
2976 RETURN_ON_FAILED_EXECUTION(String);
2977 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00002978}
2979
2980
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002981Local<String> Value::ToString(Isolate* isolate) const {
2982 RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String);
2983}
2984
2985
2986MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00002987 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002988 if (obj->IsString()) return ToApiHandle<String>(obj);
2989 PREPARE_FOR_EXECUTION(context, "ToDetailString", String);
2990 Local<String> result;
2991 i::Handle<i::Object> args[] = {obj};
2992 has_pending_exception = !ToLocal<String>(
2993 i::Execution::TryCall(isolate, isolate->no_side_effects_to_string_fun(),
2994 isolate->factory()->undefined_value(),
2995 arraysize(args), args),
2996 &result);
2997 RETURN_ON_FAILED_EXECUTION(String);
2998 RETURN_ESCAPED(result);
2999}
3000
3001
3002Local<String> Value::ToDetailString(Isolate* isolate) const {
3003 RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()),
3004 String);
3005}
3006
3007
3008MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
3009 auto obj = Utils::OpenHandle(this);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003010 if (obj->IsJSReceiver()) return ToApiHandle<Object>(obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003011 PREPARE_FOR_EXECUTION(context, "ToObject", Object);
3012 Local<Object> result;
3013 has_pending_exception =
Ben Murdoch097c5b22016-05-18 11:27:45 +01003014 !ToLocal<Object>(i::Object::ToObject(isolate, obj), &result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003015 RETURN_ON_FAILED_EXECUTION(Object);
3016 RETURN_ESCAPED(result);
3017}
3018
3019
3020Local<v8::Object> Value::ToObject(Isolate* isolate) const {
3021 RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object);
3022}
3023
3024
3025MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const {
3026 auto obj = Utils::OpenHandle(this);
3027 if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj);
3028 auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
3029 auto val = isolate->factory()->ToBoolean(obj->BooleanValue());
3030 return ToApiHandle<Boolean>(val);
Steve Blocka7e24c12009-10-30 11:49:00 +00003031}
3032
3033
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003034Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003035 return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00003036}
3037
3038
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003039MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
3040 auto obj = Utils::OpenHandle(this);
3041 if (obj->IsNumber()) return ToApiHandle<Number>(obj);
3042 PREPARE_FOR_EXECUTION(context, "ToNumber", Number);
3043 Local<Number> result;
3044 has_pending_exception = !ToLocal<Number>(i::Object::ToNumber(obj), &result);
3045 RETURN_ON_FAILED_EXECUTION(Number);
3046 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00003047}
3048
3049
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003050Local<Number> Value::ToNumber(Isolate* isolate) const {
3051 RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number);
3052}
3053
3054
3055MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
3056 auto obj = Utils::OpenHandle(this);
3057 if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
3058 PREPARE_FOR_EXECUTION(context, "ToInteger", Integer);
3059 Local<Integer> result;
3060 has_pending_exception =
3061 !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
3062 RETURN_ON_FAILED_EXECUTION(Integer);
3063 RETURN_ESCAPED(result);
3064}
3065
3066
3067Local<Integer> Value::ToInteger(Isolate* isolate) const {
3068 RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer);
3069}
3070
3071
3072MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
3073 auto obj = Utils::OpenHandle(this);
3074 if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
3075 Local<Int32> result;
3076 PREPARE_FOR_EXECUTION(context, "ToInt32", Int32);
3077 has_pending_exception =
3078 !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
3079 RETURN_ON_FAILED_EXECUTION(Int32);
3080 RETURN_ESCAPED(result);
3081}
3082
3083
3084Local<Int32> Value::ToInt32(Isolate* isolate) const {
3085 RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32);
3086}
3087
3088
3089MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
3090 auto obj = Utils::OpenHandle(this);
3091 if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
3092 Local<Uint32> result;
3093 PREPARE_FOR_EXECUTION(context, "ToUint32", Uint32);
3094 has_pending_exception =
3095 !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
3096 RETURN_ON_FAILED_EXECUTION(Uint32);
3097 RETURN_ESCAPED(result);
3098}
3099
3100
3101Local<Uint32> Value::ToUint32(Isolate* isolate) const {
3102 RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003103}
3104
3105
3106void i::Internals::CheckInitializedImpl(v8::Isolate* external_isolate) {
3107 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
3108 Utils::ApiCheck(isolate != NULL &&
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003109 !isolate->IsDead(),
3110 "v8::internal::Internals::CheckInitialized()",
3111 "Isolate is not initialized or V8 has died");
Steve Blocka7e24c12009-10-30 11:49:00 +00003112}
3113
3114
3115void External::CheckCast(v8::Value* that) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003116 Utils::ApiCheck(Utils::OpenHandle(that)->IsExternal(),
3117 "v8::External::Cast()",
3118 "Could not convert to external");
Steve Blocka7e24c12009-10-30 11:49:00 +00003119}
3120
3121
3122void v8::Object::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003123 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003124 Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast()",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003125 "Could not convert to object");
Steve Blocka7e24c12009-10-30 11:49:00 +00003126}
3127
3128
3129void v8::Function::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003130 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003131 Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast()",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003132 "Could not convert to function");
3133}
3134
3135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003136void v8::Boolean::CheckCast(v8::Value* that) {
3137 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3138 Utils::ApiCheck(obj->IsBoolean(),
3139 "v8::Boolean::Cast()",
3140 "Could not convert to boolean");
3141}
3142
3143
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003144void v8::Name::CheckCast(v8::Value* that) {
3145 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3146 Utils::ApiCheck(obj->IsName(),
3147 "v8::Name::Cast()",
3148 "Could not convert to name");
Steve Blocka7e24c12009-10-30 11:49:00 +00003149}
3150
3151
3152void v8::String::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003153 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003154 Utils::ApiCheck(obj->IsString(),
3155 "v8::String::Cast()",
3156 "Could not convert to string");
3157}
3158
3159
3160void v8::Symbol::CheckCast(v8::Value* that) {
3161 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3162 Utils::ApiCheck(obj->IsSymbol(),
3163 "v8::Symbol::Cast()",
3164 "Could not convert to symbol");
Steve Blocka7e24c12009-10-30 11:49:00 +00003165}
3166
3167
3168void v8::Number::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003169 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003170 Utils::ApiCheck(obj->IsNumber(),
3171 "v8::Number::Cast()",
3172 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00003173}
3174
3175
3176void v8::Integer::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003177 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003178 Utils::ApiCheck(obj->IsNumber(),
3179 "v8::Integer::Cast()",
3180 "Could not convert to number");
Steve Blocka7e24c12009-10-30 11:49:00 +00003181}
3182
3183
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003184void v8::Int32::CheckCast(v8::Value* that) {
3185 Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast()",
3186 "Could not convert to 32-bit signed integer");
3187}
3188
3189
3190void v8::Uint32::CheckCast(v8::Value* that) {
3191 Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast()",
3192 "Could not convert to 32-bit unsigned integer");
3193}
3194
3195
Steve Blocka7e24c12009-10-30 11:49:00 +00003196void v8::Array::CheckCast(Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003197 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003198 Utils::ApiCheck(obj->IsJSArray(),
3199 "v8::Array::Cast()",
3200 "Could not convert to array");
3201}
3202
3203
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003204void v8::Map::CheckCast(Value* that) {
3205 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3206 Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast()",
3207 "Could not convert to Map");
3208}
3209
3210
3211void v8::Set::CheckCast(Value* that) {
3212 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3213 Utils::ApiCheck(obj->IsJSSet(), "v8::Set::Cast()",
3214 "Could not convert to Set");
3215}
3216
3217
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003218void v8::Promise::CheckCast(Value* that) {
3219 Utils::ApiCheck(that->IsPromise(),
3220 "v8::Promise::Cast()",
3221 "Could not convert to promise");
3222}
3223
3224
3225void v8::Promise::Resolver::CheckCast(Value* that) {
3226 Utils::ApiCheck(that->IsPromise(),
3227 "v8::Promise::Resolver::Cast()",
3228 "Could not convert to promise resolver");
3229}
3230
3231
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003232void v8::Proxy::CheckCast(Value* that) {
3233 Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast()",
3234 "Could not convert to proxy");
3235}
3236
3237
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003238void v8::ArrayBuffer::CheckCast(Value* that) {
3239 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003240 Utils::ApiCheck(
3241 obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared(),
3242 "v8::ArrayBuffer::Cast()", "Could not convert to ArrayBuffer");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003243}
3244
3245
3246void v8::ArrayBufferView::CheckCast(Value* that) {
3247 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3248 Utils::ApiCheck(obj->IsJSArrayBufferView(),
3249 "v8::ArrayBufferView::Cast()",
3250 "Could not convert to ArrayBufferView");
3251}
3252
3253
3254void v8::TypedArray::CheckCast(Value* that) {
3255 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3256 Utils::ApiCheck(obj->IsJSTypedArray(),
3257 "v8::TypedArray::Cast()",
3258 "Could not convert to TypedArray");
3259}
3260
3261
3262#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \
3263 void v8::Type##Array::CheckCast(Value* that) { \
3264 i::Handle<i::Object> obj = Utils::OpenHandle(that); \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003265 Utils::ApiCheck( \
3266 obj->IsJSTypedArray() && \
3267 i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array, \
3268 "v8::" #Type "Array::Cast()", "Could not convert to " #Type "Array"); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003269 }
3270
3271
3272TYPED_ARRAYS(CHECK_TYPED_ARRAY_CAST)
3273
3274#undef CHECK_TYPED_ARRAY_CAST
3275
3276
3277void v8::DataView::CheckCast(Value* that) {
3278 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3279 Utils::ApiCheck(obj->IsJSDataView(),
3280 "v8::DataView::Cast()",
3281 "Could not convert to DataView");
Steve Blocka7e24c12009-10-30 11:49:00 +00003282}
3283
3284
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003285void v8::SharedArrayBuffer::CheckCast(Value* that) {
3286 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3287 Utils::ApiCheck(
3288 obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared(),
3289 "v8::SharedArrayBuffer::Cast()",
3290 "Could not convert to SharedArrayBuffer");
3291}
3292
3293
Steve Blocka7e24c12009-10-30 11:49:00 +00003294void v8::Date::CheckCast(v8::Value* that) {
Steve Blocka7e24c12009-10-30 11:49:00 +00003295 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003296 i::Isolate* isolate = NULL;
3297 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3298 Utils::ApiCheck(isolate != NULL &&
3299 obj->HasSpecificClassOf(isolate->heap()->Date_string()),
3300 "v8::Date::Cast()",
3301 "Could not convert to date");
Steve Blocka7e24c12009-10-30 11:49:00 +00003302}
3303
3304
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003305void v8::StringObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003306 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003307 i::Isolate* isolate = NULL;
3308 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3309 Utils::ApiCheck(isolate != NULL &&
3310 obj->HasSpecificClassOf(isolate->heap()->String_string()),
3311 "v8::StringObject::Cast()",
3312 "Could not convert to StringObject");
3313}
3314
3315
3316void v8::SymbolObject::CheckCast(v8::Value* that) {
3317 i::Handle<i::Object> obj = Utils::OpenHandle(that);
3318 i::Isolate* isolate = NULL;
3319 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3320 Utils::ApiCheck(isolate != NULL &&
3321 obj->HasSpecificClassOf(isolate->heap()->Symbol_string()),
3322 "v8::SymbolObject::Cast()",
3323 "Could not convert to SymbolObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003324}
3325
3326
3327void v8::NumberObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003328 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003329 i::Isolate* isolate = NULL;
3330 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3331 Utils::ApiCheck(isolate != NULL &&
3332 obj->HasSpecificClassOf(isolate->heap()->Number_string()),
3333 "v8::NumberObject::Cast()",
3334 "Could not convert to NumberObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003335}
3336
3337
3338void v8::BooleanObject::CheckCast(v8::Value* that) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003339 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003340 i::Isolate* isolate = NULL;
3341 if (obj->IsHeapObject()) isolate = i::HeapObject::cast(*obj)->GetIsolate();
3342 Utils::ApiCheck(isolate != NULL &&
3343 obj->HasSpecificClassOf(isolate->heap()->Boolean_string()),
3344 "v8::BooleanObject::Cast()",
3345 "Could not convert to BooleanObject");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003346}
3347
3348
Ben Murdochf87a2032010-10-22 12:50:53 +01003349void v8::RegExp::CheckCast(v8::Value* that) {
Ben Murdochf87a2032010-10-22 12:50:53 +01003350 i::Handle<i::Object> obj = Utils::OpenHandle(that);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003351 Utils::ApiCheck(obj->IsJSRegExp(),
3352 "v8::RegExp::Cast()",
3353 "Could not convert to regular expression");
Ben Murdochf87a2032010-10-22 12:50:53 +01003354}
3355
3356
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003357Maybe<bool> Value::BooleanValue(Local<Context> context) const {
3358 return Just(Utils::OpenHandle(this)->BooleanValue());
3359}
3360
3361
Steve Blocka7e24c12009-10-30 11:49:00 +00003362bool Value::BooleanValue() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003363 return Utils::OpenHandle(this)->BooleanValue();
Steve Blocka7e24c12009-10-30 11:49:00 +00003364}
3365
3366
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003367Maybe<double> Value::NumberValue(Local<Context> context) const {
3368 auto obj = Utils::OpenHandle(this);
3369 if (obj->IsNumber()) return Just(obj->Number());
3370 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "NumberValue", double);
3371 i::Handle<i::Object> num;
3372 has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num);
3373 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
3374 return Just(num->Number());
3375}
3376
3377
Steve Blocka7e24c12009-10-30 11:49:00 +00003378double Value::NumberValue() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003379 auto obj = Utils::OpenHandle(this);
3380 if (obj->IsNumber()) return obj->Number();
3381 return NumberValue(ContextFromHeapObject(obj))
3382 .FromMaybe(std::numeric_limits<double>::quiet_NaN());
3383}
3384
3385
3386Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
3387 auto obj = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003388 if (obj->IsNumber()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003389 return Just(NumberToInt64(*obj));
Steve Blocka7e24c12009-10-30 11:49:00 +00003390 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01003391 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "IntegerValue", int64_t);
3392 i::Handle<i::Object> num;
3393 has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
3394 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
3395 return Just(NumberToInt64(*num));
Steve Blocka7e24c12009-10-30 11:49:00 +00003396}
3397
3398
3399int64_t Value::IntegerValue() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003400 auto obj = Utils::OpenHandle(this);
Steve Blocka7e24c12009-10-30 11:49:00 +00003401 if (obj->IsNumber()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003402 if (obj->IsSmi()) {
3403 return i::Smi::cast(*obj)->value();
3404 } else {
3405 return static_cast<int64_t>(obj->Number());
3406 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003407 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003408 return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0);
Steve Blocka7e24c12009-10-30 11:49:00 +00003409}
3410
3411
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003412Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
3413 auto obj = Utils::OpenHandle(this);
3414 if (obj->IsNumber()) return Just(NumberToInt32(*obj));
3415 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Int32Value", int32_t);
Steve Blocka7e24c12009-10-30 11:49:00 +00003416 i::Handle<i::Object> num;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003417 has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
3418 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
3419 return Just(num->IsSmi() ? i::Smi::cast(*num)->value()
3420 : static_cast<int32_t>(num->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003421}
3422
3423
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003424int32_t Value::Int32Value() const {
3425 auto obj = Utils::OpenHandle(this);
3426 if (obj->IsNumber()) return NumberToInt32(*obj);
3427 return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0);
3428}
3429
3430
3431Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
3432 auto obj = Utils::OpenHandle(this);
3433 if (obj->IsNumber()) return Just(NumberToUint32(*obj));
3434 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Uint32Value", uint32_t);
Steve Blocka7e24c12009-10-30 11:49:00 +00003435 i::Handle<i::Object> num;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003436 has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
3437 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
3438 return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value())
3439 : static_cast<uint32_t>(num->Number()));
Steve Blocka7e24c12009-10-30 11:49:00 +00003440}
3441
3442
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003443uint32_t Value::Uint32Value() const {
3444 auto obj = Utils::OpenHandle(this);
3445 if (obj->IsNumber()) return NumberToUint32(*obj);
3446 return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0);
3447}
3448
3449
3450MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
3451 auto self = Utils::OpenHandle(this);
3452 if (self->IsSmi()) {
3453 if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00003454 return Local<Uint32>();
3455 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003456 PREPARE_FOR_EXECUTION(context, "ToArrayIndex", Uint32);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003457 i::Handle<i::Object> string_obj;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003458 has_pending_exception =
3459 !i::Object::ToString(isolate, self).ToHandle(&string_obj);
3460 RETURN_ON_FAILED_EXECUTION(Uint32);
Steve Blocka7e24c12009-10-30 11:49:00 +00003461 i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
3462 uint32_t index;
3463 if (str->AsArrayIndex(&index)) {
3464 i::Handle<i::Object> value;
3465 if (index <= static_cast<uint32_t>(i::Smi::kMaxValue)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003466 value = i::Handle<i::Object>(i::Smi::FromInt(index), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00003467 } else {
Steve Block44f0eee2011-05-26 01:26:41 +01003468 value = isolate->factory()->NewNumber(index);
Steve Blocka7e24c12009-10-30 11:49:00 +00003469 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003470 RETURN_ESCAPED(Utils::Uint32ToLocal(value));
Steve Blocka7e24c12009-10-30 11:49:00 +00003471 }
3472 return Local<Uint32>();
3473}
3474
3475
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003476Local<Uint32> Value::ToArrayIndex() const {
3477 auto self = Utils::OpenHandle(this);
3478 if (self->IsSmi()) {
3479 if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
3480 return Local<Uint32>();
Steve Blocka7e24c12009-10-30 11:49:00 +00003481 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003482 auto context = ContextFromHeapObject(self);
3483 RETURN_TO_LOCAL_UNCHECKED(ToArrayIndex(context), Uint32);
Steve Blocka7e24c12009-10-30 11:49:00 +00003484}
3485
3486
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003487Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
3488 auto self = Utils::OpenHandle(this);
3489 auto other = Utils::OpenHandle(*that);
3490 return i::Object::Equals(self, other);
Steve Blocka7e24c12009-10-30 11:49:00 +00003491}
3492
3493
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003494bool Value::Equals(Local<Value> that) const {
3495 auto self = Utils::OpenHandle(this);
3496 auto other = Utils::OpenHandle(*that);
3497 if (self->IsSmi() && other->IsSmi()) {
3498 return self->Number() == other->Number();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003499 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003500 if (self->IsJSObject() && other->IsJSObject()) {
3501 return *self == *other;
Steve Blocka7e24c12009-10-30 11:49:00 +00003502 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003503 auto heap_object = self->IsSmi() ? other : self;
3504 auto context = ContextFromHeapObject(heap_object);
3505 return Equals(context, that).FromMaybe(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003506}
3507
3508
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003509bool Value::StrictEquals(Local<Value> that) const {
3510 auto self = Utils::OpenHandle(this);
3511 auto other = Utils::OpenHandle(*that);
3512 return self->StrictEquals(*other);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003513}
3514
3515
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003516bool Value::SameValue(Local<Value> that) const {
3517 auto self = Utils::OpenHandle(this);
3518 auto other = Utils::OpenHandle(*that);
3519 return self->SameValue(*other);
Steve Blocka7e24c12009-10-30 11:49:00 +00003520}
3521
3522
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003523Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
3524 v8::Local<Value> key, v8::Local<Value> value) {
3525 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
3526 auto self = Utils::OpenHandle(this);
3527 auto key_obj = Utils::OpenHandle(*key);
3528 auto value_obj = Utils::OpenHandle(*value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003529 has_pending_exception =
3530 i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
3531 i::SLOPPY).is_null();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003532 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3533 return Just(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00003534}
3535
3536
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003537bool v8::Object::Set(v8::Local<Value> key, v8::Local<Value> value) {
3538 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3539 return Set(context, key, value).FromMaybe(false);
3540}
3541
3542
3543Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
3544 v8::Local<Value> value) {
3545 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
3546 auto self = Utils::OpenHandle(this);
3547 auto value_obj = Utils::OpenHandle(*value);
3548 has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
3549 i::SLOPPY).is_null();
3550 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3551 return Just(true);
3552}
3553
3554
3555bool v8::Object::Set(uint32_t index, v8::Local<Value> value) {
3556 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3557 return Set(context, index, value).FromMaybe(false);
3558}
3559
3560
3561Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
3562 v8::Local<Name> key,
3563 v8::Local<Value> value) {
3564 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
3565 bool);
3566 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3567 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
Steve Block6ded16b2010-05-10 14:33:55 +01003568 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003569
3570 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
Ben Murdochda12d292016-06-02 14:46:10 +01003571 isolate, self, key_obj, self, i::LookupIterator::OWN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003572 Maybe<bool> result =
3573 i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
3574 has_pending_exception = result.IsNothing();
3575 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3576 return result;
Steve Block6ded16b2010-05-10 14:33:55 +01003577}
3578
3579
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003580Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
3581 uint32_t index,
3582 v8::Local<Value> value) {
3583 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
3584 bool);
3585 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3586 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
3587
Ben Murdochda12d292016-06-02 14:46:10 +01003588 i::LookupIterator it(isolate, self, index, self, i::LookupIterator::OWN);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003589 Maybe<bool> result =
3590 i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
3591 has_pending_exception = result.IsNothing();
3592 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3593 return result;
3594}
3595
3596
3597Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
3598 v8::Local<Name> key,
3599 v8::Local<Value> value,
3600 v8::PropertyAttribute attributes) {
3601 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DefineOwnProperty()",
3602 bool);
3603 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
3604 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
3605 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
3606
3607 if (self->IsAccessCheckNeeded() &&
3608 !isolate->MayAccess(handle(isolate->context()),
3609 i::Handle<i::JSObject>::cast(self))) {
3610 isolate->ReportFailedAccessCheck(i::Handle<i::JSObject>::cast(self));
3611 return Nothing<bool>();
3612 }
3613
3614 i::PropertyDescriptor desc;
3615 desc.set_writable(!(attributes & v8::ReadOnly));
3616 desc.set_enumerable(!(attributes & v8::DontEnum));
3617 desc.set_configurable(!(attributes & v8::DontDelete));
3618 desc.set_value(value_obj);
3619 Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
3620 isolate, self, key_obj, &desc, i::Object::DONT_THROW);
3621 // Even though we said DONT_THROW, there might be accessors that do throw.
3622 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3623 return success;
3624}
3625
3626
3627MUST_USE_RESULT
3628static i::MaybeHandle<i::Object> DefineObjectProperty(
3629 i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
3630 i::Handle<i::Object> value, i::PropertyAttributes attrs) {
3631 i::Isolate* isolate = js_object->GetIsolate();
3632 bool success = false;
3633 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
3634 isolate, js_object, key, &success, i::LookupIterator::OWN);
3635 if (!success) return i::MaybeHandle<i::Object>();
3636
Ben Murdoch097c5b22016-05-18 11:27:45 +01003637 return i::JSObject::DefineOwnPropertyIgnoreAttributes(
3638 &it, value, attrs, i::JSObject::FORCE_FIELD);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003639}
3640
3641
3642Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
3643 v8::Local<Value> key, v8::Local<Value> value,
3644 v8::PropertyAttribute attribs) {
3645 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::ForceSet()", bool);
3646 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
3647 auto key_obj = Utils::OpenHandle(*key);
3648 auto value_obj = Utils::OpenHandle(*value);
3649 has_pending_exception =
3650 DefineObjectProperty(self, key_obj, value_obj,
3651 static_cast<i::PropertyAttributes>(attribs))
3652 .is_null();
3653 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3654 return Just(true);
3655}
3656
3657
3658bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value,
Steve Blocka7e24c12009-10-30 11:49:00 +00003659 v8::PropertyAttribute attribs) {
Steve Block44f0eee2011-05-26 01:26:41 +01003660 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003661 PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(),
3662 "v8::Object::ForceSet", false, i::HandleScope,
3663 false);
3664 i::Handle<i::JSObject> self =
3665 i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00003666 i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
3667 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003668 has_pending_exception =
3669 DefineObjectProperty(self, key_obj, value_obj,
3670 static_cast<i::PropertyAttributes>(attribs))
3671 .is_null();
3672 EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false);
Steve Blocka7e24c12009-10-30 11:49:00 +00003673 return true;
3674}
3675
3676
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003677Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
3678 Local<Value> value) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01003679 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrivate()", bool);
3680 auto self = Utils::OpenHandle(this);
3681 auto key_obj = Utils::OpenHandle(reinterpret_cast<Name*>(*key));
3682 auto value_obj = Utils::OpenHandle(*value);
3683 if (self->IsJSProxy()) {
3684 i::PropertyDescriptor desc;
3685 desc.set_writable(true);
3686 desc.set_enumerable(false);
3687 desc.set_configurable(true);
3688 desc.set_value(value_obj);
3689 return i::JSProxy::SetPrivateProperty(
3690 isolate, i::Handle<i::JSProxy>::cast(self),
3691 i::Handle<i::Symbol>::cast(key_obj), &desc, i::Object::DONT_THROW);
3692 }
3693 auto js_object = i::Handle<i::JSObject>::cast(self);
Ben Murdochda12d292016-06-02 14:46:10 +01003694 i::LookupIterator it(js_object, key_obj, js_object);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003695 has_pending_exception = i::JSObject::DefineOwnPropertyIgnoreAttributes(
3696 &it, value_obj, i::DONT_ENUM)
3697 .is_null();
3698 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3699 return Just(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003700}
3701
3702
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003703MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
3704 Local<Value> key) {
3705 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
3706 auto self = Utils::OpenHandle(this);
3707 auto key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003708 i::Handle<i::Object> result;
3709 has_pending_exception =
3710 !i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003711 RETURN_ON_FAILED_EXECUTION(Value);
3712 RETURN_ESCAPED(Utils::ToLocal(result));
3713}
3714
3715
3716Local<Value> v8::Object::Get(v8::Local<Value> key) {
3717 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3718 RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value);
3719}
3720
3721
3722MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
3723 PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
3724 auto self = Utils::OpenHandle(this);
3725 i::Handle<i::Object> result;
3726 has_pending_exception =
Ben Murdochda12d292016-06-02 14:46:10 +01003727 !i::JSReceiver::GetElement(isolate, self, index).ToHandle(&result);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003728 RETURN_ON_FAILED_EXECUTION(Value);
3729 RETURN_ESCAPED(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003730}
3731
3732
Steve Block6ded16b2010-05-10 14:33:55 +01003733Local<Value> v8::Object::Get(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003734 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3735 RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value);
Steve Block6ded16b2010-05-10 14:33:55 +01003736}
3737
3738
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003739MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
3740 Local<Private> key) {
3741 return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003742}
3743
3744
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003745Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
3746 Local<Context> context, Local<Value> key) {
3747 PREPARE_FOR_EXECUTION_PRIMITIVE(
3748 context, "v8::Object::GetPropertyAttributes()", PropertyAttribute);
3749 auto self = Utils::OpenHandle(this);
3750 auto key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003751 if (!key_obj->IsName()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003752 has_pending_exception =
3753 !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
3754 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003755 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003756 auto key_name = i::Handle<i::Name>::cast(key_obj);
3757 auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
3758 has_pending_exception = result.IsNothing();
3759 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
3760 if (result.FromJust() == i::ABSENT) {
3761 return Just(static_cast<PropertyAttribute>(i::NONE));
3762 }
3763 return Just(static_cast<PropertyAttribute>(result.FromJust()));
3764}
3765
3766
3767PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) {
3768 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3769 return GetPropertyAttributes(context, key)
3770 .FromMaybe(static_cast<PropertyAttribute>(i::NONE));
3771}
3772
3773
3774MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
3775 Local<String> key) {
3776 PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyDescriptor()",
3777 Value);
3778 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
3779 i::Handle<i::String> key_name = Utils::OpenHandle(*key);
3780
3781 i::PropertyDescriptor desc;
3782 Maybe<bool> found =
3783 i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
3784 has_pending_exception = found.IsNothing();
3785 RETURN_ON_FAILED_EXECUTION(Value);
3786 if (!found.FromJust()) {
3787 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
3788 }
3789 RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003790}
3791
3792
3793Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003794 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3795 RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyDescriptor(context, key), Value);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003796}
3797
3798
Steve Blocka7e24c12009-10-30 11:49:00 +00003799Local<Value> v8::Object::GetPrototype() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003800 auto isolate = Utils::OpenHandle(this)->GetIsolate();
3801 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003802 i::PrototypeIterator iter(isolate, self);
3803 return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
Steve Blocka7e24c12009-10-30 11:49:00 +00003804}
3805
3806
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003807Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
3808 Local<Value> value) {
3809 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrototype()", bool);
3810 auto self = Utils::OpenHandle(this);
3811 auto value_obj = Utils::OpenHandle(*value);
Ben Murdoch8b112d22011-06-08 16:22:53 +01003812 // We do not allow exceptions thrown while setting the prototype
3813 // to propagate outside.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003814 TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
3815 auto result = i::JSReceiver::SetPrototype(self, value_obj, false,
3816 i::Object::THROW_ON_ERROR);
3817 has_pending_exception = result.IsNothing();
3818 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3819 return Just(true);
3820}
3821
3822
3823bool v8::Object::SetPrototype(Local<Value> value) {
3824 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3825 return SetPrototype(context, value).FromMaybe(false);
Andrei Popescu402d9372010-02-26 13:31:12 +00003826}
3827
3828
Steve Blocka7e24c12009-10-30 11:49:00 +00003829Local<Object> v8::Object::FindInstanceInPrototypeChain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003830 v8::Local<FunctionTemplate> tmpl) {
3831 auto isolate = Utils::OpenHandle(this)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003832 i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this),
3833 i::PrototypeIterator::START_AT_RECEIVER);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003834 auto tmpl_info = *Utils::OpenHandle(*tmpl);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003835 while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) {
3836 iter.Advance();
3837 if (iter.IsAtEnd()) {
3838 return Local<Object>();
3839 }
Steve Blocka7e24c12009-10-30 11:49:00 +00003840 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003841 // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
3842 return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
3843}
3844
3845
3846MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
3847 PREPARE_FOR_EXECUTION(context, "v8::Object::GetPropertyNames()", Array);
3848 auto self = Utils::OpenHandle(this);
3849 i::Handle<i::FixedArray> value;
3850 has_pending_exception =
Ben Murdoch097c5b22016-05-18 11:27:45 +01003851 !i::JSReceiver::GetKeys(self, i::INCLUDE_PROTOS, i::ENUMERABLE_STRINGS)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003852 .ToHandle(&value);
3853 RETURN_ON_FAILED_EXECUTION(Array);
Ben Murdochda12d292016-06-02 14:46:10 +01003854 DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
3855 self->map()->EnumLength() == 0 ||
3856 self->map()->instance_descriptors()->GetEnumCache() != *value);
3857 auto result = isolate->factory()->NewJSArrayWithElements(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003858 RETURN_ESCAPED(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003859}
3860
3861
3862Local<Array> v8::Object::GetPropertyNames() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003863 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3864 RETURN_TO_LOCAL_UNCHECKED(GetPropertyNames(context), Array);
3865}
3866
3867
3868MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
3869 PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyNames()", Array);
3870 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003871 i::Handle<i::FixedArray> value;
Ben Murdoch097c5b22016-05-18 11:27:45 +01003872 has_pending_exception =
3873 !i::JSReceiver::GetKeys(self, i::OWN_ONLY, i::ENUMERABLE_STRINGS)
3874 .ToHandle(&value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003875 RETURN_ON_FAILED_EXECUTION(Array);
Ben Murdochda12d292016-06-02 14:46:10 +01003876 DCHECK(self->map()->EnumLength() == i::kInvalidEnumCacheSentinel ||
3877 self->map()->EnumLength() == 0 ||
3878 self->map()->instance_descriptors()->GetEnumCache() != *value);
3879 auto result = isolate->factory()->NewJSArrayWithElements(value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003880 RETURN_ESCAPED(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00003881}
3882
3883
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003884Local<Array> v8::Object::GetOwnPropertyNames() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003885 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3886 RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyNames(context), Array);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00003887}
3888
3889
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003890MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
3891 PREPARE_FOR_EXECUTION(context, "v8::Object::ObjectProtoToString", String);
3892 auto obj = Utils::OpenHandle(this);
3893 Local<String> result;
3894 has_pending_exception =
3895 !ToLocal<String>(i::JSObject::ObjectProtoToString(isolate, obj), &result);
3896 RETURN_ON_FAILED_EXECUTION(String);
3897 RETURN_ESCAPED(result);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003898}
3899
3900
Steve Blocka7e24c12009-10-30 11:49:00 +00003901Local<String> v8::Object::ObjectProtoToString() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003902 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3903 RETURN_TO_LOCAL_UNCHECKED(ObjectProtoToString(context), String);
Steve Blocka7e24c12009-10-30 11:49:00 +00003904}
3905
3906
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003907Local<String> v8::Object::GetConstructorName() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003908 auto self = Utils::OpenHandle(this);
3909 i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003910 return Utils::ToLocal(name);
3911}
3912
Ben Murdochda12d292016-06-02 14:46:10 +01003913Maybe<bool> v8::Object::SetIntegrityLevel(Local<Context> context,
3914 IntegrityLevel level) {
3915 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetIntegrityLevel()",
3916 bool);
3917 auto self = Utils::OpenHandle(this);
3918 i::JSReceiver::IntegrityLevel i_level =
3919 level == IntegrityLevel::kFrozen ? i::FROZEN : i::SEALED;
3920 Maybe<bool> result =
3921 i::JSReceiver::SetIntegrityLevel(self, i_level, i::Object::DONT_THROW);
3922 has_pending_exception = result.IsNothing();
3923 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3924 return result;
3925}
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08003926
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003927Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
3928 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Delete()", bool);
3929 auto self = Utils::OpenHandle(this);
3930 auto key_obj = Utils::OpenHandle(*key);
3931 Maybe<bool> result =
3932 i::Runtime::DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY);
3933 has_pending_exception = result.IsNothing();
3934 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3935 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003936}
3937
3938
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003939bool v8::Object::Delete(v8::Local<Value> key) {
3940 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3941 return Delete(context, key).FromMaybe(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003942}
3943
3944
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003945Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
3946 Local<Private> key) {
3947 return Delete(context, Local<Value>(reinterpret_cast<Value*>(*key)));
3948}
3949
3950
3951Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
3952 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
3953 auto self = Utils::OpenHandle(this);
3954 auto key_obj = Utils::OpenHandle(*key);
3955 Maybe<bool> maybe = Nothing<bool>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003956 // Check if the given key is an array index.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003957 uint32_t index = 0;
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003958 if (key_obj->ToArrayIndex(&index)) {
3959 maybe = i::JSReceiver::HasElement(self, index);
3960 } else {
3961 // Convert the key to a name - possibly by calling back into JavaScript.
3962 i::Handle<i::Name> name;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003963 if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04003964 maybe = i::JSReceiver::HasProperty(self, name);
3965 }
3966 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003967 has_pending_exception = maybe.IsNothing();
3968 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3969 return maybe;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003970}
3971
3972
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003973bool v8::Object::Has(v8::Local<Value> key) {
3974 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3975 return Has(context, key).FromMaybe(false);
3976}
3977
3978
3979Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
3980 return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
3981}
3982
3983
3984Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
3985 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DeleteProperty()",
3986 bool);
3987 auto self = Utils::OpenHandle(this);
3988 Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
3989 has_pending_exception = result.IsNothing();
3990 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
3991 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00003992}
3993
3994
3995bool v8::Object::Delete(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003996 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
3997 return Delete(context, index).FromMaybe(false);
3998}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003999
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004000
4001Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
4002 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
4003 auto self = Utils::OpenHandle(this);
4004 auto maybe = i::JSReceiver::HasElement(self, index);
4005 has_pending_exception = maybe.IsNothing();
4006 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4007 return maybe;
Steve Blocka7e24c12009-10-30 11:49:00 +00004008}
4009
4010
4011bool v8::Object::Has(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004012 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4013 return Has(context, index).FromMaybe(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004014}
4015
4016
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004017template <typename Getter, typename Setter, typename Data>
4018static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
4019 Local<Name> name, Getter getter,
4020 Setter setter, Data data,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004021 AccessControl settings,
4022 PropertyAttribute attributes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004023 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetAccessor()", bool);
4024 if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
4025 i::Handle<i::JSObject> obj =
4026 i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
4027 v8::Local<AccessorSignature> signature;
4028 auto info = MakeAccessorInfo(name, getter, setter, data, settings, attributes,
Ben Murdoch097c5b22016-05-18 11:27:45 +01004029 signature, i::FLAG_disable_old_api_accessors);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004030 if (info.is_null()) return Nothing<bool>();
4031 bool fast = obj->HasFastProperties();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004032 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004033 has_pending_exception =
4034 !i::JSObject::SetAccessor(obj, info).ToHandle(&result);
4035 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4036 if (result->IsUndefined()) return Nothing<bool>();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004037 if (fast) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004038 i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004039 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004040 return Just(true);
Steve Blocka7e24c12009-10-30 11:49:00 +00004041}
4042
4043
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004044Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
4045 AccessorNameGetterCallback getter,
4046 AccessorNameSetterCallback setter,
4047 MaybeLocal<Value> data, AccessControl settings,
4048 PropertyAttribute attribute) {
4049 return ObjectSetAccessor(context, this, name, getter, setter,
4050 data.FromMaybe(Local<Value>()), settings, attribute);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004051}
4052
4053
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004054bool Object::SetAccessor(Local<String> name, AccessorGetterCallback getter,
4055 AccessorSetterCallback setter, v8::Local<Value> data,
4056 AccessControl settings, PropertyAttribute attributes) {
4057 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4058 return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
4059 attributes).FromMaybe(false);
4060}
4061
4062
4063bool Object::SetAccessor(Local<Name> name, AccessorNameGetterCallback getter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004064 AccessorNameSetterCallback setter,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004065 v8::Local<Value> data, AccessControl settings,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004066 PropertyAttribute attributes) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004067 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4068 return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
4069 attributes).FromMaybe(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004070}
4071
4072
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004073void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
4074 Local<Function> setter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004075 PropertyAttribute attribute,
4076 AccessControl settings) {
4077 // TODO(verwaest): Remove |settings|.
4078 DCHECK_EQ(v8::DEFAULT, settings);
Steve Block44f0eee2011-05-26 01:26:41 +01004079 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004080 ENTER_V8(isolate);
4081 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004082 auto self = Utils::OpenHandle(this);
4083 if (!self->IsJSObject()) return;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004084 i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
4085 i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
4086 if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004087 i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
4088 v8::Utils::OpenHandle(*name), getter_i, setter_i,
4089 static_cast<i::PropertyAttributes>(attribute));
Leon Clarkef7060e22010-06-03 12:02:55 +01004090}
4091
4092
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004093Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
4094 Local<Name> key) {
4095 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasOwnProperty()",
4096 bool);
4097 auto self = Utils::OpenHandle(this);
4098 auto key_val = Utils::OpenHandle(*key);
4099 auto result = i::JSReceiver::HasOwnProperty(self, key_val);
4100 has_pending_exception = result.IsNothing();
4101 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4102 return result;
Ben Murdoch257744e2011-11-30 15:57:28 +00004103}
4104
4105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004106bool v8::Object::HasOwnProperty(Local<String> key) {
4107 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4108 return HasOwnProperty(context, key).FromMaybe(false);
4109}
4110
4111
4112Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
4113 Local<Name> key) {
4114 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasRealNamedProperty()",
4115 bool);
4116 auto self = Utils::OpenHandle(this);
4117 if (!self->IsJSObject()) return Just(false);
4118 auto key_val = Utils::OpenHandle(*key);
4119 auto result = i::JSObject::HasRealNamedProperty(
4120 i::Handle<i::JSObject>::cast(self), key_val);
4121 has_pending_exception = result.IsNothing();
4122 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4123 return result;
4124}
4125
4126
4127bool v8::Object::HasRealNamedProperty(Local<String> key) {
4128 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4129 return HasRealNamedProperty(context, key).FromMaybe(false);
4130}
4131
4132
4133Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
4134 uint32_t index) {
4135 PREPARE_FOR_EXECUTION_PRIMITIVE(context,
4136 "v8::Object::HasRealIndexedProperty()", bool);
4137 auto self = Utils::OpenHandle(this);
4138 if (!self->IsJSObject()) return Just(false);
4139 auto result = i::JSObject::HasRealElementProperty(
4140 i::Handle<i::JSObject>::cast(self), index);
4141 has_pending_exception = result.IsNothing();
4142 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4143 return result;
Steve Blocka7e24c12009-10-30 11:49:00 +00004144}
4145
4146
4147bool v8::Object::HasRealIndexedProperty(uint32_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004148 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4149 return HasRealIndexedProperty(context, index).FromMaybe(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004150}
4151
4152
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004153Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
4154 Local<Name> key) {
4155 PREPARE_FOR_EXECUTION_PRIMITIVE(
4156 context, "v8::Object::HasRealNamedCallbackProperty()", bool);
4157 auto self = Utils::OpenHandle(this);
4158 if (!self->IsJSObject()) return Just(false);
4159 auto key_val = Utils::OpenHandle(*key);
4160 auto result = i::JSObject::HasRealNamedCallbackProperty(
4161 i::Handle<i::JSObject>::cast(self), key_val);
4162 has_pending_exception = result.IsNothing();
4163 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
4164 return result;
4165}
4166
4167
4168bool v8::Object::HasRealNamedCallbackProperty(Local<String> key) {
4169 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4170 return HasRealNamedCallbackProperty(context, key).FromMaybe(false);
Steve Blocka7e24c12009-10-30 11:49:00 +00004171}
4172
4173
4174bool v8::Object::HasNamedLookupInterceptor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004175 auto self = Utils::OpenHandle(this);
4176 return self->IsJSObject() &&
4177 i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00004178}
4179
4180
4181bool v8::Object::HasIndexedLookupInterceptor() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004182 auto self = Utils::OpenHandle(this);
4183 return self->IsJSObject() &&
4184 i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor();
Steve Blocka7e24c12009-10-30 11:49:00 +00004185}
4186
4187
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004188MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
4189 Local<Context> context, Local<Name> key) {
4190 PREPARE_FOR_EXECUTION(
4191 context, "v8::Object::GetRealNamedPropertyInPrototypeChain()", Value);
4192 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4193 if (!self->IsJSObject()) return MaybeLocal<Value>();
4194 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4195 i::PrototypeIterator iter(isolate, self);
4196 if (iter.IsAtEnd()) return MaybeLocal<Value>();
4197 i::Handle<i::JSReceiver> proto =
4198 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4199 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4200 isolate, self, key_obj, proto,
4201 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4202 Local<Value> result;
4203 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4204 RETURN_ON_FAILED_EXECUTION(Value);
4205 if (!it.IsFound()) return MaybeLocal<Value>();
4206 RETURN_ESCAPED(result);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004207}
4208
4209
Steve Blocka7e24c12009-10-30 11:49:00 +00004210Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004211 Local<String> key) {
4212 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4213 RETURN_TO_LOCAL_UNCHECKED(GetRealNamedPropertyInPrototypeChain(context, key),
4214 Value);
Steve Blocka7e24c12009-10-30 11:49:00 +00004215}
4216
4217
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004218Maybe<PropertyAttribute>
4219v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
4220 Local<Context> context, Local<Name> key) {
4221 PREPARE_FOR_EXECUTION_PRIMITIVE(
4222 context, "v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()",
4223 PropertyAttribute);
4224 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4225 if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
4226 i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
4227 i::PrototypeIterator iter(isolate, self);
4228 if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
4229 i::Handle<i::JSReceiver> proto =
4230 i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
4231 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
4232 isolate, self, key_obj, proto,
4233 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4234 Maybe<i::PropertyAttributes> result =
4235 i::JSReceiver::GetPropertyAttributes(&it);
4236 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4237 if (!it.IsFound()) return Nothing<PropertyAttribute>();
4238 if (result.FromJust() == i::ABSENT) return Just(None);
4239 return Just(static_cast<PropertyAttribute>(result.FromJust()));
Steve Blocka7e24c12009-10-30 11:49:00 +00004240}
4241
4242
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004243Maybe<PropertyAttribute>
4244v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key) {
4245 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4246 return GetRealNamedPropertyAttributesInPrototypeChain(context, key);
4247}
Steve Blocka7e24c12009-10-30 11:49:00 +00004248
Ben Murdochb0fe1622011-05-05 13:52:32 +01004249
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004250MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
4251 Local<Name> key) {
4252 PREPARE_FOR_EXECUTION(context, "v8::Object::GetRealNamedProperty()", Value);
4253 auto self = Utils::OpenHandle(this);
4254 auto key_obj = Utils::OpenHandle(*key);
4255 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
Ben Murdochda12d292016-06-02 14:46:10 +01004256 isolate, self, key_obj, self,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004257 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4258 Local<Value> result;
4259 has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
4260 RETURN_ON_FAILED_EXECUTION(Value);
4261 if (!it.IsFound()) return MaybeLocal<Value>();
4262 RETURN_ESCAPED(result);
4263}
4264
4265
4266Local<Value> v8::Object::GetRealNamedProperty(Local<String> key) {
4267 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4268 RETURN_TO_LOCAL_UNCHECKED(GetRealNamedProperty(context, key), Value);
4269}
4270
4271
4272Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4273 Local<Context> context, Local<Name> key) {
4274 PREPARE_FOR_EXECUTION_PRIMITIVE(
4275 context, "v8::Object::GetRealNamedPropertyAttributes()",
4276 PropertyAttribute);
4277 auto self = Utils::OpenHandle(this);
4278 auto key_obj = Utils::OpenHandle(*key);
4279 i::LookupIterator it = i::LookupIterator::PropertyOrElement(
Ben Murdochda12d292016-06-02 14:46:10 +01004280 isolate, self, key_obj, self,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004281 i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
4282 auto result = i::JSReceiver::GetPropertyAttributes(&it);
4283 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
4284 if (!it.IsFound()) return Nothing<PropertyAttribute>();
4285 if (result.FromJust() == i::ABSENT) {
4286 return Just(static_cast<PropertyAttribute>(i::NONE));
4287 }
4288 return Just<PropertyAttribute>(
4289 static_cast<PropertyAttribute>(result.FromJust()));
4290}
4291
4292
4293Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
4294 Local<String> key) {
4295 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4296 return GetRealNamedPropertyAttributes(context, key);
Steve Blocka7e24c12009-10-30 11:49:00 +00004297}
4298
4299
Steve Blocka7e24c12009-10-30 11:49:00 +00004300Local<v8::Object> v8::Object::Clone() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004301 auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
4302 auto isolate = self->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004303 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004304 auto result = isolate->factory()->CopyJSObject(self);
4305 CHECK(!result.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00004306 return Utils::ToLocal(result);
4307}
4308
4309
Ben Murdoch8b112d22011-06-08 16:22:53 +01004310Local<v8::Context> v8::Object::CreationContext() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004311 auto self = Utils::OpenHandle(this);
4312 auto context = handle(self->GetCreationContext());
4313 return Utils::ToLocal(context);
Ben Murdoch8b112d22011-06-08 16:22:53 +01004314}
4315
4316
Steve Blocka7e24c12009-10-30 11:49:00 +00004317int v8::Object::GetIdentityHash() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004318 auto isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004319 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004320 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004321 return i::JSReceiver::GetOrCreateIdentityHash(self)->value();
Steve Blocka7e24c12009-10-30 11:49:00 +00004322}
4323
4324
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004325bool v8::Object::SetHiddenValue(v8::Local<v8::String> key,
4326 v8::Local<v8::Value> value) {
Steve Block44f0eee2011-05-26 01:26:41 +01004327 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004328 ENTER_V8(isolate);
4329 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004330 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4331 if (!self->IsJSObject()) return false;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004332 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004333 i::Handle<i::String> key_string =
4334 isolate->factory()->InternalizeString(key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004335 if (value.IsEmpty()) {
4336 i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
4337 key_string);
4338 return true;
4339 }
Steve Blocka7e24c12009-10-30 11:49:00 +00004340 i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004341 i::Handle<i::Object> result = i::JSObject::SetHiddenProperty(
4342 i::Handle<i::JSObject>::cast(self), key_string, value_obj);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004343 return *result == *self;
Steve Blocka7e24c12009-10-30 11:49:00 +00004344}
4345
4346
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004347v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Local<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01004348 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004349 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004350 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4351 if (!self->IsJSObject()) return v8::Local<v8::Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +00004352 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004353 i::Handle<i::String> key_string =
4354 isolate->factory()->InternalizeString(key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004355 i::Handle<i::Object> result(
4356 i::Handle<i::JSObject>::cast(self)->GetHiddenProperty(key_string),
4357 isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004358 if (result->IsTheHole()) return v8::Local<v8::Value>();
Steve Blocka7e24c12009-10-30 11:49:00 +00004359 return Utils::ToLocal(result);
4360}
4361
4362
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004363bool v8::Object::DeleteHiddenValue(v8::Local<v8::String> key) {
Steve Block44f0eee2011-05-26 01:26:41 +01004364 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01004365 ENTER_V8(isolate);
4366 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004367 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
4368 if (!self->IsJSObject()) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00004369 i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004370 i::Handle<i::String> key_string =
4371 isolate->factory()->InternalizeString(key_obj);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004372 i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
4373 key_string);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004374 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00004375}
4376
4377
Ben Murdoch257744e2011-11-30 15:57:28 +00004378bool v8::Object::IsCallable() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004379 auto self = Utils::OpenHandle(this);
4380 return self->IsCallable();
Ben Murdoch257744e2011-11-30 15:57:28 +00004381}
4382
4383
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004384MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
4385 Local<Value> recv, int argc,
4386 Local<Value> argv[]) {
4387 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Object::CallAsFunction()",
4388 Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004389 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004390 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004391 auto self = Utils::OpenHandle(this);
4392 auto recv_obj = Utils::OpenHandle(*recv);
4393 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004394 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004395 Local<Value> result;
4396 has_pending_exception = !ToLocal<Value>(
4397 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
4398 RETURN_ON_FAILED_EXECUTION(Value);
4399 RETURN_ESCAPED(result);
4400}
4401
4402
4403Local<v8::Value> Object::CallAsFunction(v8::Local<v8::Value> recv, int argc,
4404 v8::Local<v8::Value> argv[]) {
4405 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4406 Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
4407 RETURN_TO_LOCAL_UNCHECKED(CallAsFunction(context, recv, argc, argv_cast),
4408 Value);
4409}
4410
4411
4412MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
4413 Local<Value> argv[]) {
4414 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context,
4415 "v8::Object::CallAsConstructor()", Value);
4416 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004417 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004418 auto self = Utils::OpenHandle(this);
4419 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
4420 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4421 Local<Value> result;
4422 has_pending_exception = !ToLocal<Value>(
4423 i::Execution::New(isolate, self, self, argc, args), &result);
4424 RETURN_ON_FAILED_EXECUTION(Value);
4425 RETURN_ESCAPED(result);
Ben Murdoch257744e2011-11-30 15:57:28 +00004426}
4427
4428
4429Local<v8::Value> Object::CallAsConstructor(int argc,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004430 v8::Local<v8::Value> argv[]) {
4431 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4432 Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
4433 RETURN_TO_LOCAL_UNCHECKED(CallAsConstructor(context, argc, argv_cast), Value);
Ben Murdoch257744e2011-11-30 15:57:28 +00004434}
4435
4436
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004437MaybeLocal<Function> Function::New(Local<Context> context,
4438 FunctionCallback callback, Local<Value> data,
4439 int length) {
4440 i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004441 LOG_API(isolate, "Function::New");
4442 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004443 return FunctionTemplateNew(isolate, callback, nullptr, data,
4444 Local<Signature>(), length, true)
4445 ->GetFunction(context);
4446}
4447
4448
4449Local<Function> Function::New(Isolate* v8_isolate, FunctionCallback callback,
4450 Local<Value> data, int length) {
4451 return Function::New(v8_isolate->GetCurrentContext(), callback, data, length)
4452 .FromMaybe(Local<Function>());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004453}
4454
4455
Steve Blocka7e24c12009-10-30 11:49:00 +00004456Local<v8::Object> Function::NewInstance() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004457 return NewInstance(Isolate::GetCurrent()->GetCurrentContext(), 0, NULL)
4458 .FromMaybe(Local<Object>());
4459}
4460
4461
4462MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
4463 v8::Local<v8::Value> argv[]) const {
4464 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::NewInstance()",
4465 Object);
4466 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004467 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004468 auto self = Utils::OpenHandle(this);
4469 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
4470 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
4471 Local<Object> result;
4472 has_pending_exception = !ToLocal<Object>(
4473 i::Execution::New(isolate, self, self, argc, args), &result);
4474 RETURN_ON_FAILED_EXECUTION(Object);
4475 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004476}
4477
4478
4479Local<v8::Object> Function::NewInstance(int argc,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004480 v8::Local<v8::Value> argv[]) const {
4481 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4482 RETURN_TO_LOCAL_UNCHECKED(NewInstance(context, argc, argv), Object);
Steve Blocka7e24c12009-10-30 11:49:00 +00004483}
4484
4485
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004486MaybeLocal<v8::Value> Function::Call(Local<Context> context,
4487 v8::Local<v8::Value> recv, int argc,
4488 v8::Local<v8::Value> argv[]) {
4489 PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::Call()", Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004490 i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +01004491 TRACE_EVENT0("v8", "V8.Execute");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004492 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004493 i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004494 STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004495 i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004496 Local<Value> result;
4497 has_pending_exception = !ToLocal<Value>(
4498 i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
4499 RETURN_ON_FAILED_EXECUTION(Value);
4500 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00004501}
4502
4503
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004504Local<v8::Value> Function::Call(v8::Local<v8::Value> recv, int argc,
4505 v8::Local<v8::Value> argv[]) {
4506 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
4507 RETURN_TO_LOCAL_UNCHECKED(Call(context, recv, argc, argv), Value);
4508}
4509
4510
4511void Function::SetName(v8::Local<v8::String> name) {
4512 auto self = Utils::OpenHandle(this);
4513 if (!self->IsJSFunction()) return;
4514 auto func = i::Handle<i::JSFunction>::cast(self);
Steve Blocka7e24c12009-10-30 11:49:00 +00004515 func->shared()->set_name(*Utils::OpenHandle(*name));
4516}
4517
4518
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004519Local<Value> Function::GetName() const {
4520 auto self = Utils::OpenHandle(this);
4521 if (self->IsJSBoundFunction()) {
4522 auto func = i::Handle<i::JSBoundFunction>::cast(self);
4523 return Utils::ToLocal(handle(func->name(), func->GetIsolate()));
4524 }
4525 if (self->IsJSFunction()) {
4526 auto func = i::Handle<i::JSFunction>::cast(self);
4527 return Utils::ToLocal(handle(func->shared()->name(), func->GetIsolate()));
4528 }
4529 return ToApiHandle<Primitive>(
4530 self->GetIsolate()->factory()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00004531}
4532
4533
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004534Local<Value> Function::GetInferredName() const {
4535 auto self = Utils::OpenHandle(this);
4536 if (!self->IsJSFunction()) {
4537 return ToApiHandle<Primitive>(
4538 self->GetIsolate()->factory()->undefined_value());
4539 }
4540 auto func = i::Handle<i::JSFunction>::cast(self);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004541 return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
4542 func->GetIsolate()));
4543}
4544
4545
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004546Local<Value> Function::GetDebugName() const {
4547 auto self = Utils::OpenHandle(this);
4548 if (!self->IsJSFunction()) {
4549 return ToApiHandle<Primitive>(
4550 self->GetIsolate()->factory()->undefined_value());
4551 }
4552 auto func = i::Handle<i::JSFunction>::cast(self);
4553 i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
4554 return Utils::ToLocal(i::Handle<i::Object>(*name, name->GetIsolate()));
4555}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004556
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004557
4558Local<Value> Function::GetDisplayName() const {
4559 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
4560 ENTER_V8(isolate);
4561 auto self = Utils::OpenHandle(this);
4562 if (!self->IsJSFunction()) {
4563 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
4564 }
4565 auto func = i::Handle<i::JSFunction>::cast(self);
4566 i::Handle<i::String> property_name =
4567 isolate->factory()->NewStringFromStaticChars("displayName");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004568 i::Handle<i::Object> value =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004569 i::JSReceiver::GetDataProperty(func, property_name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004570 if (value->IsString()) {
4571 i::Handle<i::String> name = i::Handle<i::String>::cast(value);
4572 if (name->length() > 0) return Utils::ToLocal(name);
4573 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004574 return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004575}
4576
4577
Andrei Popescu402d9372010-02-26 13:31:12 +00004578ScriptOrigin Function::GetScriptOrigin() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004579 auto self = Utils::OpenHandle(this);
4580 if (!self->IsJSFunction()) {
4581 return v8::ScriptOrigin(Local<Value>());
4582 }
4583 auto func = i::Handle<i::JSFunction>::cast(self);
Andrei Popescu402d9372010-02-26 13:31:12 +00004584 if (func->shared()->script()->IsScript()) {
4585 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004586 return GetScriptOriginForScript(func->GetIsolate(), script);
Andrei Popescu402d9372010-02-26 13:31:12 +00004587 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004588 return v8::ScriptOrigin(Local<Value>());
Andrei Popescu402d9372010-02-26 13:31:12 +00004589}
4590
4591
4592const int Function::kLineOffsetNotFound = -1;
4593
4594
4595int Function::GetScriptLineNumber() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004596 auto self = Utils::OpenHandle(this);
4597 if (!self->IsJSFunction()) {
4598 return kLineOffsetNotFound;
4599 }
4600 auto func = i::Handle<i::JSFunction>::cast(self);
Andrei Popescu402d9372010-02-26 13:31:12 +00004601 if (func->shared()->script()->IsScript()) {
4602 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004603 return i::Script::GetLineNumber(script, func->shared()->start_position());
Andrei Popescu402d9372010-02-26 13:31:12 +00004604 }
4605 return kLineOffsetNotFound;
4606}
4607
4608
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004609int Function::GetScriptColumnNumber() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004610 auto self = Utils::OpenHandle(this);
4611 if (!self->IsJSFunction()) {
4612 return kLineOffsetNotFound;
4613 }
4614 auto func = i::Handle<i::JSFunction>::cast(self);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004615 if (func->shared()->script()->IsScript()) {
4616 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004617 return i::Script::GetColumnNumber(script, func->shared()->start_position());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004618 }
4619 return kLineOffsetNotFound;
4620}
4621
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004622
4623bool Function::IsBuiltin() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004624 auto self = Utils::OpenHandle(this);
4625 if (!self->IsJSFunction()) {
4626 return false;
4627 }
4628 auto func = i::Handle<i::JSFunction>::cast(self);
4629 return func->shared()->IsBuiltin();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004630}
4631
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004632
4633int Function::ScriptId() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004634 auto self = Utils::OpenHandle(this);
4635 if (!self->IsJSFunction()) {
4636 return v8::UnboundScript::kNoScriptId;
4637 }
4638 auto func = i::Handle<i::JSFunction>::cast(self);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004639 if (!func->shared()->script()->IsScript()) {
4640 return v8::UnboundScript::kNoScriptId;
4641 }
4642 i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004643 return script->id();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004644}
4645
4646
4647Local<v8::Value> Function::GetBoundFunction() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004648 auto self = Utils::OpenHandle(this);
4649 if (self->IsJSBoundFunction()) {
4650 auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
4651 auto bound_target_function = i::handle(
4652 bound_function->bound_target_function(), bound_function->GetIsolate());
4653 return Utils::CallableToLocal(bound_target_function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004654 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004655 return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004656}
4657
4658
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004659int Name::GetIdentityHash() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004660 auto self = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04004661 return static_cast<int>(self->Hash());
4662}
4663
4664
Steve Blocka7e24c12009-10-30 11:49:00 +00004665int String::Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004666 i::Handle<i::String> str = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01004667 return str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00004668}
4669
4670
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004671bool String::IsOneByte() const {
4672 i::Handle<i::String> str = Utils::OpenHandle(this);
4673 return str->HasOnlyOneByteChars();
4674}
4675
4676
4677// Helpers for ContainsOnlyOneByteHelper
4678template<size_t size> struct OneByteMask;
4679template<> struct OneByteMask<4> {
4680 static const uint32_t value = 0xFF00FF00;
4681};
4682template<> struct OneByteMask<8> {
4683 static const uint64_t value = V8_2PART_UINT64_C(0xFF00FF00, FF00FF00);
4684};
4685static const uintptr_t kOneByteMask = OneByteMask<sizeof(uintptr_t)>::value;
4686static const uintptr_t kAlignmentMask = sizeof(uintptr_t) - 1;
4687static inline bool Unaligned(const uint16_t* chars) {
4688 return reinterpret_cast<const uintptr_t>(chars) & kAlignmentMask;
4689}
4690
4691
4692static inline const uint16_t* Align(const uint16_t* chars) {
4693 return reinterpret_cast<uint16_t*>(
4694 reinterpret_cast<uintptr_t>(chars) & ~kAlignmentMask);
4695}
4696
4697class ContainsOnlyOneByteHelper {
4698 public:
4699 ContainsOnlyOneByteHelper() : is_one_byte_(true) {}
4700 bool Check(i::String* string) {
4701 i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
4702 if (cons_string == NULL) return is_one_byte_;
4703 return CheckCons(cons_string);
4704 }
4705 void VisitOneByteString(const uint8_t* chars, int length) {
4706 // Nothing to do.
4707 }
4708 void VisitTwoByteString(const uint16_t* chars, int length) {
4709 // Accumulated bits.
4710 uintptr_t acc = 0;
4711 // Align to uintptr_t.
4712 const uint16_t* end = chars + length;
4713 while (Unaligned(chars) && chars != end) {
4714 acc |= *chars++;
4715 }
4716 // Read word aligned in blocks,
4717 // checking the return value at the end of each block.
4718 const uint16_t* aligned_end = Align(end);
4719 const int increment = sizeof(uintptr_t)/sizeof(uint16_t);
4720 const int inner_loops = 16;
4721 while (chars + inner_loops*increment < aligned_end) {
4722 for (int i = 0; i < inner_loops; i++) {
4723 acc |= *reinterpret_cast<const uintptr_t*>(chars);
4724 chars += increment;
4725 }
4726 // Check for early return.
4727 if ((acc & kOneByteMask) != 0) {
4728 is_one_byte_ = false;
4729 return;
4730 }
4731 }
4732 // Read the rest.
4733 while (chars != end) {
4734 acc |= *chars++;
4735 }
4736 // Check result.
4737 if ((acc & kOneByteMask) != 0) is_one_byte_ = false;
4738 }
4739
4740 private:
4741 bool CheckCons(i::ConsString* cons_string) {
4742 while (true) {
4743 // Check left side if flat.
4744 i::String* left = cons_string->first();
4745 i::ConsString* left_as_cons =
4746 i::String::VisitFlat(this, left, 0);
4747 if (!is_one_byte_) return false;
4748 // Check right side if flat.
4749 i::String* right = cons_string->second();
4750 i::ConsString* right_as_cons =
4751 i::String::VisitFlat(this, right, 0);
4752 if (!is_one_byte_) return false;
4753 // Standard recurse/iterate trick.
4754 if (left_as_cons != NULL && right_as_cons != NULL) {
4755 if (left->length() < right->length()) {
4756 CheckCons(left_as_cons);
4757 cons_string = right_as_cons;
4758 } else {
4759 CheckCons(right_as_cons);
4760 cons_string = left_as_cons;
4761 }
4762 // Check fast return.
4763 if (!is_one_byte_) return false;
4764 continue;
4765 }
4766 // Descend left in place.
4767 if (left_as_cons != NULL) {
4768 cons_string = left_as_cons;
4769 continue;
4770 }
4771 // Descend right in place.
4772 if (right_as_cons != NULL) {
4773 cons_string = right_as_cons;
4774 continue;
4775 }
4776 // Terminate.
4777 break;
4778 }
4779 return is_one_byte_;
4780 }
4781 bool is_one_byte_;
4782 DISALLOW_COPY_AND_ASSIGN(ContainsOnlyOneByteHelper);
4783};
4784
4785
4786bool String::ContainsOnlyOneByte() const {
4787 i::Handle<i::String> str = Utils::OpenHandle(this);
4788 if (str->HasOnlyOneByteChars()) return true;
4789 ContainsOnlyOneByteHelper helper;
4790 return helper.Check(*str);
4791}
4792
4793
4794class Utf8LengthHelper : public i::AllStatic {
4795 public:
4796 enum State {
4797 kEndsWithLeadingSurrogate = 1 << 0,
4798 kStartsWithTrailingSurrogate = 1 << 1,
4799 kLeftmostEdgeIsCalculated = 1 << 2,
4800 kRightmostEdgeIsCalculated = 1 << 3,
4801 kLeftmostEdgeIsSurrogate = 1 << 4,
4802 kRightmostEdgeIsSurrogate = 1 << 5
4803 };
4804
4805 static const uint8_t kInitialState = 0;
4806
4807 static inline bool EndsWithSurrogate(uint8_t state) {
4808 return state & kEndsWithLeadingSurrogate;
4809 }
4810
4811 static inline bool StartsWithSurrogate(uint8_t state) {
4812 return state & kStartsWithTrailingSurrogate;
4813 }
4814
4815 class Visitor {
4816 public:
4817 Visitor() : utf8_length_(0), state_(kInitialState) {}
4818
4819 void VisitOneByteString(const uint8_t* chars, int length) {
4820 int utf8_length = 0;
4821 // Add in length 1 for each non-Latin1 character.
4822 for (int i = 0; i < length; i++) {
4823 utf8_length += *chars++ >> 7;
4824 }
4825 // Add in length 1 for each character.
4826 utf8_length_ = utf8_length + length;
4827 state_ = kInitialState;
4828 }
4829
4830 void VisitTwoByteString(const uint16_t* chars, int length) {
4831 int utf8_length = 0;
4832 int last_character = unibrow::Utf16::kNoPreviousCharacter;
4833 for (int i = 0; i < length; i++) {
4834 uint16_t c = chars[i];
4835 utf8_length += unibrow::Utf8::Length(c, last_character);
4836 last_character = c;
4837 }
4838 utf8_length_ = utf8_length;
4839 uint8_t state = 0;
4840 if (unibrow::Utf16::IsTrailSurrogate(chars[0])) {
4841 state |= kStartsWithTrailingSurrogate;
4842 }
4843 if (unibrow::Utf16::IsLeadSurrogate(chars[length-1])) {
4844 state |= kEndsWithLeadingSurrogate;
4845 }
4846 state_ = state;
4847 }
4848
4849 static i::ConsString* VisitFlat(i::String* string,
4850 int* length,
4851 uint8_t* state) {
4852 Visitor visitor;
4853 i::ConsString* cons_string = i::String::VisitFlat(&visitor, string);
4854 *length = visitor.utf8_length_;
4855 *state = visitor.state_;
4856 return cons_string;
4857 }
4858
4859 private:
4860 int utf8_length_;
4861 uint8_t state_;
4862 DISALLOW_COPY_AND_ASSIGN(Visitor);
4863 };
4864
4865 static inline void MergeLeafLeft(int* length,
4866 uint8_t* state,
4867 uint8_t leaf_state) {
4868 bool edge_surrogate = StartsWithSurrogate(leaf_state);
4869 if (!(*state & kLeftmostEdgeIsCalculated)) {
4870 DCHECK(!(*state & kLeftmostEdgeIsSurrogate));
4871 *state |= kLeftmostEdgeIsCalculated
4872 | (edge_surrogate ? kLeftmostEdgeIsSurrogate : 0);
4873 } else if (EndsWithSurrogate(*state) && edge_surrogate) {
4874 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4875 }
4876 if (EndsWithSurrogate(leaf_state)) {
4877 *state |= kEndsWithLeadingSurrogate;
4878 } else {
4879 *state &= ~kEndsWithLeadingSurrogate;
4880 }
4881 }
4882
4883 static inline void MergeLeafRight(int* length,
4884 uint8_t* state,
4885 uint8_t leaf_state) {
4886 bool edge_surrogate = EndsWithSurrogate(leaf_state);
4887 if (!(*state & kRightmostEdgeIsCalculated)) {
4888 DCHECK(!(*state & kRightmostEdgeIsSurrogate));
4889 *state |= (kRightmostEdgeIsCalculated
4890 | (edge_surrogate ? kRightmostEdgeIsSurrogate : 0));
4891 } else if (edge_surrogate && StartsWithSurrogate(*state)) {
4892 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4893 }
4894 if (StartsWithSurrogate(leaf_state)) {
4895 *state |= kStartsWithTrailingSurrogate;
4896 } else {
4897 *state &= ~kStartsWithTrailingSurrogate;
4898 }
4899 }
4900
4901 static inline void MergeTerminal(int* length,
4902 uint8_t state,
4903 uint8_t* state_out) {
4904 DCHECK((state & kLeftmostEdgeIsCalculated) &&
4905 (state & kRightmostEdgeIsCalculated));
4906 if (EndsWithSurrogate(state) && StartsWithSurrogate(state)) {
4907 *length -= unibrow::Utf8::kBytesSavedByCombiningSurrogates;
4908 }
4909 *state_out = kInitialState |
4910 (state & kLeftmostEdgeIsSurrogate ? kStartsWithTrailingSurrogate : 0) |
4911 (state & kRightmostEdgeIsSurrogate ? kEndsWithLeadingSurrogate : 0);
4912 }
4913
4914 static int Calculate(i::ConsString* current, uint8_t* state_out) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00004915 using internal::ConsString;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004916 int total_length = 0;
4917 uint8_t state = kInitialState;
4918 while (true) {
4919 i::String* left = current->first();
4920 i::String* right = current->second();
4921 uint8_t right_leaf_state;
4922 uint8_t left_leaf_state;
4923 int leaf_length;
4924 ConsString* left_as_cons =
4925 Visitor::VisitFlat(left, &leaf_length, &left_leaf_state);
4926 if (left_as_cons == NULL) {
4927 total_length += leaf_length;
4928 MergeLeafLeft(&total_length, &state, left_leaf_state);
4929 }
4930 ConsString* right_as_cons =
4931 Visitor::VisitFlat(right, &leaf_length, &right_leaf_state);
4932 if (right_as_cons == NULL) {
4933 total_length += leaf_length;
4934 MergeLeafRight(&total_length, &state, right_leaf_state);
4935 if (left_as_cons != NULL) {
4936 // 1 Leaf node. Descend in place.
4937 current = left_as_cons;
4938 continue;
4939 } else {
4940 // Terminal node.
4941 MergeTerminal(&total_length, state, state_out);
4942 return total_length;
4943 }
4944 } else if (left_as_cons == NULL) {
4945 // 1 Leaf node. Descend in place.
4946 current = right_as_cons;
4947 continue;
4948 }
4949 // Both strings are ConsStrings.
4950 // Recurse on smallest.
4951 if (left->length() < right->length()) {
4952 total_length += Calculate(left_as_cons, &left_leaf_state);
4953 MergeLeafLeft(&total_length, &state, left_leaf_state);
4954 current = right_as_cons;
4955 } else {
4956 total_length += Calculate(right_as_cons, &right_leaf_state);
4957 MergeLeafRight(&total_length, &state, right_leaf_state);
4958 current = left_as_cons;
4959 }
4960 }
4961 UNREACHABLE();
4962 return 0;
4963 }
4964
4965 static inline int Calculate(i::ConsString* current) {
4966 uint8_t state = kInitialState;
4967 return Calculate(current, &state);
4968 }
4969
4970 private:
4971 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8LengthHelper);
4972};
4973
4974
4975static int Utf8Length(i::String* str, i::Isolate* isolate) {
4976 int length = str->length();
4977 if (length == 0) return 0;
4978 uint8_t state;
4979 i::ConsString* cons_string =
4980 Utf8LengthHelper::Visitor::VisitFlat(str, &length, &state);
4981 if (cons_string == NULL) return length;
4982 return Utf8LengthHelper::Calculate(cons_string);
4983}
4984
4985
Steve Blocka7e24c12009-10-30 11:49:00 +00004986int String::Utf8Length() const {
Steve Block44f0eee2011-05-26 01:26:41 +01004987 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004988 i::Isolate* isolate = str->GetIsolate();
4989 return v8::Utf8Length(*str, isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01004990}
4991
4992
Ben Murdochb8a8cc12014-11-26 15:28:44 +00004993class Utf8WriterVisitor {
4994 public:
4995 Utf8WriterVisitor(
4996 char* buffer,
4997 int capacity,
4998 bool skip_capacity_check,
4999 bool replace_invalid_utf8)
5000 : early_termination_(false),
5001 last_character_(unibrow::Utf16::kNoPreviousCharacter),
5002 buffer_(buffer),
5003 start_(buffer),
5004 capacity_(capacity),
5005 skip_capacity_check_(capacity == -1 || skip_capacity_check),
5006 replace_invalid_utf8_(replace_invalid_utf8),
5007 utf16_chars_read_(0) {
5008 }
5009
5010 static int WriteEndCharacter(uint16_t character,
5011 int last_character,
5012 int remaining,
5013 char* const buffer,
5014 bool replace_invalid_utf8) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005015 DCHECK_GT(remaining, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005016 // We can't use a local buffer here because Encode needs to modify
5017 // previous characters in the stream. We know, however, that
5018 // exactly one character will be advanced.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005019 if (unibrow::Utf16::IsSurrogatePair(last_character, character)) {
5020 int written = unibrow::Utf8::Encode(buffer, character, last_character,
5021 replace_invalid_utf8);
5022 DCHECK_EQ(written, 1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005023 return written;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005024 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005025 // Use a scratch buffer to check the required characters.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005026 char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005027 // Can't encode using last_character as gcc has array bounds issues.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005028 int written = unibrow::Utf8::Encode(temp_buffer, character,
5029 unibrow::Utf16::kNoPreviousCharacter,
5030 replace_invalid_utf8);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005031 // Won't fit.
5032 if (written > remaining) return 0;
5033 // Copy over the character from temp_buffer.
5034 for (int j = 0; j < written; j++) {
5035 buffer[j] = temp_buffer[j];
5036 }
5037 return written;
5038 }
5039
5040 // Visit writes out a group of code units (chars) of a v8::String to the
5041 // internal buffer_. This is done in two phases. The first phase calculates a
5042 // pesimistic estimate (writable_length) on how many code units can be safely
5043 // written without exceeding the buffer capacity and without writing the last
5044 // code unit (it could be a lead surrogate). The estimated number of code
5045 // units is then written out in one go, and the reported byte usage is used
5046 // to correct the estimate. This is repeated until the estimate becomes <= 0
5047 // or all code units have been written out. The second phase writes out code
5048 // units until the buffer capacity is reached, would be exceeded by the next
5049 // unit, or all units have been written out.
5050 template<typename Char>
5051 void Visit(const Char* chars, const int length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005052 DCHECK(!early_termination_);
5053 if (length == 0) return;
5054 // Copy state to stack.
5055 char* buffer = buffer_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005056 int last_character = sizeof(Char) == 1
5057 ? unibrow::Utf16::kNoPreviousCharacter
5058 : last_character_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005059 int i = 0;
5060 // Do a fast loop where there is no exit capacity check.
5061 while (true) {
5062 int fast_length;
5063 if (skip_capacity_check_) {
5064 fast_length = length;
5065 } else {
5066 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
5067 // Need enough space to write everything but one character.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005068 STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit ==
5069 3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005070 int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
5071 int writable_length =
5072 (remaining_capacity - max_size_per_char)/max_size_per_char;
5073 // Need to drop into slow loop.
5074 if (writable_length <= 0) break;
5075 fast_length = i + writable_length;
5076 if (fast_length > length) fast_length = length;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005077 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005078 // Write the characters to the stream.
5079 if (sizeof(Char) == 1) {
5080 for (; i < fast_length; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005081 buffer += unibrow::Utf8::EncodeOneByte(
5082 buffer, static_cast<uint8_t>(*chars++));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005083 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005084 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005085 } else {
5086 for (; i < fast_length; i++) {
5087 uint16_t character = *chars++;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005088 buffer += unibrow::Utf8::Encode(buffer, character, last_character,
5089 replace_invalid_utf8_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005090 last_character = character;
5091 DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005092 }
5093 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005094 // Array is fully written. Exit.
5095 if (fast_length == length) {
5096 // Write state back out to object.
5097 last_character_ = last_character;
5098 buffer_ = buffer;
5099 utf16_chars_read_ += length;
5100 return;
5101 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005102 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005103 DCHECK(!skip_capacity_check_);
5104 // Slow loop. Must check capacity on each iteration.
5105 int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005106 DCHECK_GE(remaining_capacity, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005107 for (; i < length && remaining_capacity > 0; i++) {
5108 uint16_t character = *chars++;
5109 // remaining_capacity is <= 3 bytes at this point, so we do not write out
5110 // an umatched lead surrogate.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005111 if (replace_invalid_utf8_ && unibrow::Utf16::IsLeadSurrogate(character)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005112 early_termination_ = true;
5113 break;
5114 }
5115 int written = WriteEndCharacter(character,
5116 last_character,
5117 remaining_capacity,
5118 buffer,
5119 replace_invalid_utf8_);
5120 if (written == 0) {
5121 early_termination_ = true;
5122 break;
5123 }
5124 buffer += written;
5125 remaining_capacity -= written;
5126 last_character = character;
5127 }
5128 // Write state back out to object.
5129 last_character_ = last_character;
5130 buffer_ = buffer;
5131 utf16_chars_read_ += i;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005132 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005133
5134 inline bool IsDone() {
5135 return early_termination_;
5136 }
5137
5138 inline void VisitOneByteString(const uint8_t* chars, int length) {
5139 Visit(chars, length);
5140 }
5141
5142 inline void VisitTwoByteString(const uint16_t* chars, int length) {
5143 Visit(chars, length);
5144 }
5145
5146 int CompleteWrite(bool write_null, int* utf16_chars_read_out) {
5147 // Write out number of utf16 characters written to the stream.
5148 if (utf16_chars_read_out != NULL) {
5149 *utf16_chars_read_out = utf16_chars_read_;
5150 }
5151 // Only null terminate if all of the string was written and there's space.
5152 if (write_null &&
5153 !early_termination_ &&
5154 (capacity_ == -1 || (buffer_ - start_) < capacity_)) {
5155 *buffer_++ = '\0';
5156 }
5157 return static_cast<int>(buffer_ - start_);
5158 }
5159
5160 private:
5161 bool early_termination_;
5162 int last_character_;
5163 char* buffer_;
5164 char* const start_;
5165 int capacity_;
5166 bool const skip_capacity_check_;
5167 bool const replace_invalid_utf8_;
5168 int utf16_chars_read_;
5169 DISALLOW_IMPLICIT_CONSTRUCTORS(Utf8WriterVisitor);
5170};
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005171
5172
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005173static bool RecursivelySerializeToUtf8(i::String* current,
5174 Utf8WriterVisitor* writer,
5175 int recursion_budget) {
5176 while (!writer->IsDone()) {
5177 i::ConsString* cons_string = i::String::VisitFlat(writer, current);
5178 if (cons_string == NULL) return true; // Leaf node.
5179 if (recursion_budget <= 0) return false;
5180 // Must write the left branch first.
5181 i::String* first = cons_string->first();
5182 bool success = RecursivelySerializeToUtf8(first,
5183 writer,
5184 recursion_budget - 1);
5185 if (!success) return false;
5186 // Inline tail recurse for right branch.
5187 current = cons_string->second();
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005188 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005189 return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00005190}
5191
5192
Steve Block6ded16b2010-05-10 14:33:55 +01005193int String::WriteUtf8(char* buffer,
5194 int capacity,
5195 int* nchars_ref,
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005196 int options) const {
Steve Block44f0eee2011-05-26 01:26:41 +01005197 i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005198 LOG_API(isolate, "String::WriteUtf8");
5199 ENTER_V8(isolate);
Ben Murdoch85b71792012-04-11 18:30:58 +01005200 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005201 if (options & HINT_MANY_WRITES_EXPECTED) {
5202 str = i::String::Flatten(str); // Flatten the string for efficiency.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005203 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005204 const int string_length = str->length();
5205 bool write_null = !(options & NO_NULL_TERMINATION);
5206 bool replace_invalid_utf8 = (options & REPLACE_INVALID_UTF8);
5207 int max16BitCodeUnitSize = unibrow::Utf8::kMax16BitCodeUnitSize;
5208 // First check if we can just write the string without checking capacity.
5209 if (capacity == -1 || capacity / max16BitCodeUnitSize >= string_length) {
5210 Utf8WriterVisitor writer(buffer, capacity, true, replace_invalid_utf8);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005211 const int kMaxRecursion = 100;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005212 bool success = RecursivelySerializeToUtf8(*str, &writer, kMaxRecursion);
5213 if (success) return writer.CompleteWrite(write_null, nchars_ref);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005214 } else if (capacity >= string_length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005215 // First check that the buffer is large enough.
5216 int utf8_bytes = v8::Utf8Length(*str, str->GetIsolate());
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005217 if (utf8_bytes <= capacity) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005218 // one-byte fast path.
5219 if (utf8_bytes == string_length) {
5220 WriteOneByte(reinterpret_cast<uint8_t*>(buffer), 0, capacity, options);
5221 if (nchars_ref != NULL) *nchars_ref = string_length;
5222 if (write_null && (utf8_bytes+1 <= capacity)) {
5223 return string_length + 1;
5224 }
5225 return string_length;
5226 }
5227 if (write_null && (utf8_bytes+1 > capacity)) {
5228 options |= NO_NULL_TERMINATION;
5229 }
5230 // Recurse once without a capacity limit.
5231 // This will get into the first branch above.
5232 // TODO(dcarney) Check max left rec. in Utf8Length and fall through.
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005233 return WriteUtf8(buffer, -1, nchars_ref, options);
5234 }
5235 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005236 // Recursive slow path can potentially be unreasonable slow. Flatten.
5237 str = i::String::Flatten(str);
5238 Utf8WriterVisitor writer(buffer, capacity, false, replace_invalid_utf8);
5239 i::String::VisitFlat(&writer, *str);
5240 return writer.CompleteWrite(write_null, nchars_ref);
Steve Blocka7e24c12009-10-30 11:49:00 +00005241}
5242
5243
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005244template<typename CharType>
5245static inline int WriteHelper(const String* string,
5246 CharType* buffer,
5247 int start,
5248 int length,
5249 int options) {
5250 i::Isolate* isolate = Utils::OpenHandle(string)->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005251 LOG_API(isolate, "String::Write");
5252 ENTER_V8(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005253 DCHECK(start >= 0 && length >= -1);
5254 i::Handle<i::String> str = Utils::OpenHandle(string);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005255 if (options & String::HINT_MANY_WRITES_EXPECTED) {
Steve Block6ded16b2010-05-10 14:33:55 +01005256 // Flatten the string for efficiency. This applies whether we are
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005257 // using StringCharacterStream or Get(i) to access the characters.
5258 str = i::String::Flatten(str);
Steve Block6ded16b2010-05-10 14:33:55 +01005259 }
Ben Murdochb0fe1622011-05-05 13:52:32 +01005260 int end = start + length;
5261 if ((length == -1) || (length > str->length() - start) )
5262 end = str->length();
Steve Blocka7e24c12009-10-30 11:49:00 +00005263 if (end < 0) return 0;
5264 i::String::WriteToFlat(*str, buffer, start, end);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005265 if (!(options & String::NO_NULL_TERMINATION) &&
Ben Murdoch69a99ed2011-11-30 16:03:39 +00005266 (length == -1 || end - start < length)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01005267 buffer[end - start] = '\0';
5268 }
5269 return end - start;
Steve Blocka7e24c12009-10-30 11:49:00 +00005270}
5271
5272
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005273int String::WriteOneByte(uint8_t* buffer,
5274 int start,
5275 int length,
5276 int options) const {
5277 return WriteHelper(this, buffer, start, length, options);
5278}
5279
5280
5281int String::Write(uint16_t* buffer,
5282 int start,
5283 int length,
5284 int options) const {
5285 return WriteHelper(this, buffer, start, length, options);
5286}
5287
5288
Steve Blocka7e24c12009-10-30 11:49:00 +00005289bool v8::String::IsExternal() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005290 i::Handle<i::String> str = Utils::OpenHandle(this);
5291 return i::StringShape(*str).IsExternalTwoByte();
5292}
5293
5294
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005295bool v8::String::IsExternalOneByte() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005296 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005297 return i::StringShape(*str).IsExternalOneByte();
Steve Blocka7e24c12009-10-30 11:49:00 +00005298}
5299
5300
5301void v8::String::VerifyExternalStringResource(
5302 v8::String::ExternalStringResource* value) const {
5303 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005304 const v8::String::ExternalStringResource* expected;
Steve Blocka7e24c12009-10-30 11:49:00 +00005305 if (i::StringShape(*str).IsExternalTwoByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005306 const void* resource =
5307 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
5308 expected = reinterpret_cast<const ExternalStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00005309 } else {
5310 expected = NULL;
5311 }
5312 CHECK_EQ(expected, value);
5313}
5314
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005315void v8::String::VerifyExternalStringResourceBase(
5316 v8::String::ExternalStringResourceBase* value, Encoding encoding) const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005317 i::Handle<i::String> str = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005318 const v8::String::ExternalStringResourceBase* expected;
5319 Encoding expectedEncoding;
5320 if (i::StringShape(*str).IsExternalOneByte()) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005321 const void* resource =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005322 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5323 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5324 expectedEncoding = ONE_BYTE_ENCODING;
5325 } else if (i::StringShape(*str).IsExternalTwoByte()) {
5326 const void* resource =
5327 i::Handle<i::ExternalTwoByteString>::cast(str)->resource();
5328 expected = reinterpret_cast<const ExternalStringResourceBase*>(resource);
5329 expectedEncoding = TWO_BYTE_ENCODING;
5330 } else {
5331 expected = NULL;
5332 expectedEncoding =
5333 str->IsOneByteRepresentation() ? ONE_BYTE_ENCODING : TWO_BYTE_ENCODING;
5334 }
5335 CHECK_EQ(expected, value);
5336 CHECK_EQ(expectedEncoding, encoding);
5337}
5338
5339const v8::String::ExternalOneByteStringResource*
5340v8::String::GetExternalOneByteStringResource() const {
5341 i::Handle<i::String> str = Utils::OpenHandle(this);
5342 if (i::StringShape(*str).IsExternalOneByte()) {
5343 const void* resource =
5344 i::Handle<i::ExternalOneByteString>::cast(str)->resource();
5345 return reinterpret_cast<const ExternalOneByteStringResource*>(resource);
Steve Blocka7e24c12009-10-30 11:49:00 +00005346 } else {
5347 return NULL;
5348 }
5349}
5350
5351
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005352Local<Value> Symbol::Name() const {
5353 i::Handle<i::Symbol> sym = Utils::OpenHandle(this);
5354 i::Handle<i::Object> name(sym->name(), sym->GetIsolate());
5355 return Utils::ToLocal(name);
5356}
5357
5358
5359Local<Value> Private::Name() const {
5360 return reinterpret_cast<const Symbol*>(this)->Name();
5361}
5362
5363
Steve Blocka7e24c12009-10-30 11:49:00 +00005364double Number::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005365 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5366 return obj->Number();
5367}
5368
5369
5370bool Boolean::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005371 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5372 return obj->IsTrue();
5373}
5374
5375
5376int64_t Integer::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005377 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5378 if (obj->IsSmi()) {
5379 return i::Smi::cast(*obj)->value();
5380 } else {
5381 return static_cast<int64_t>(obj->Number());
5382 }
5383}
5384
5385
5386int32_t Int32::Value() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00005387 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5388 if (obj->IsSmi()) {
5389 return i::Smi::cast(*obj)->value();
5390 } else {
5391 return static_cast<int32_t>(obj->Number());
5392 }
5393}
5394
5395
Steve Block6ded16b2010-05-10 14:33:55 +01005396uint32_t Uint32::Value() const {
Steve Block6ded16b2010-05-10 14:33:55 +01005397 i::Handle<i::Object> obj = Utils::OpenHandle(this);
5398 if (obj->IsSmi()) {
5399 return i::Smi::cast(*obj)->value();
5400 } else {
5401 return static_cast<uint32_t>(obj->Number());
5402 }
5403}
5404
5405
Steve Blocka7e24c12009-10-30 11:49:00 +00005406int v8::Object::InternalFieldCount() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005407 i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
5408 if (!self->IsJSObject()) return 0;
5409 return i::Handle<i::JSObject>::cast(self)->GetInternalFieldCount();
Steve Blocka7e24c12009-10-30 11:49:00 +00005410}
5411
5412
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005413static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005414 const char* location) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005415 return Utils::ApiCheck(
5416 obj->IsJSObject() &&
5417 (index < i::Handle<i::JSObject>::cast(obj)->GetInternalFieldCount()),
5418 location, "Internal field out of bounds");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005419}
5420
5421
5422Local<Value> v8::Object::SlowGetInternalField(int index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005423 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005424 const char* location = "v8::Object::GetInternalField()";
5425 if (!InternalFieldOK(obj, index, location)) return Local<Value>();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005426 i::Handle<i::Object> value(
5427 i::Handle<i::JSObject>::cast(obj)->GetInternalField(index),
5428 obj->GetIsolate());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005429 return Utils::ToLocal(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00005430}
5431
5432
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005433void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
5434 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005435 const char* location = "v8::Object::SetInternalField()";
5436 if (!InternalFieldOK(obj, index, location)) return;
Steve Blocka7e24c12009-10-30 11:49:00 +00005437 i::Handle<i::Object> val = Utils::OpenHandle(*value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005438 i::Handle<i::JSObject>::cast(obj)->SetInternalField(index, *val);
Steve Blocka7e24c12009-10-30 11:49:00 +00005439}
5440
5441
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005442void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005443 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005444 const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
5445 if (!InternalFieldOK(obj, index, location)) return NULL;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005446 return DecodeSmiToAligned(
5447 i::Handle<i::JSObject>::cast(obj)->GetInternalField(index), location);
Ben Murdochb8e0da22011-05-16 14:20:40 +01005448}
5449
5450
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005451void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005452 i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005453 const char* location = "v8::Object::SetAlignedPointerInInternalField()";
5454 if (!InternalFieldOK(obj, index, location)) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005455 i::Handle<i::JSObject>::cast(obj)
5456 ->SetInternalField(index, EncodeAlignedAsSmi(value, location));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005457 DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
Ben Murdochb8e0da22011-05-16 14:20:40 +01005458}
5459
5460
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005461static void* ExternalValue(i::Object* obj) {
5462 // Obscure semantics for undefined, but somehow checked in our unit tests...
5463 if (obj->IsUndefined()) return NULL;
5464 i::Object* foreign = i::JSObject::cast(obj)->GetInternalField(0);
5465 return i::Foreign::cast(foreign)->foreign_address();
Steve Blocka7e24c12009-10-30 11:49:00 +00005466}
5467
5468
5469// --- E n v i r o n m e n t ---
5470
Steve Block44f0eee2011-05-26 01:26:41 +01005471
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005472void v8::V8::InitializePlatform(Platform* platform) {
5473 i::V8::InitializePlatform(platform);
Steve Blocka7e24c12009-10-30 11:49:00 +00005474}
5475
5476
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005477void v8::V8::ShutdownPlatform() {
5478 i::V8::ShutdownPlatform();
5479}
5480
5481
5482bool v8::V8::Initialize() {
5483 i::V8::Initialize();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005484#ifdef V8_USE_EXTERNAL_STARTUP_DATA
5485 i::ReadNatives();
5486#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005487 return true;
5488}
5489
5490
5491void v8::V8::SetEntropySource(EntropySource entropy_source) {
5492 base::RandomNumberGenerator::SetEntropySource(entropy_source);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005493}
5494
5495
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005496void v8::V8::SetReturnAddressLocationResolver(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005497 ReturnAddressLocationResolver return_address_resolver) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005498 i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005499}
5500
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005501
Steve Blocka7e24c12009-10-30 11:49:00 +00005502bool v8::V8::Dispose() {
5503 i::V8::TearDown();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005504#ifdef V8_USE_EXTERNAL_STARTUP_DATA
5505 i::DisposeNatives();
5506#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00005507 return true;
5508}
5509
Ben Murdochda12d292016-06-02 14:46:10 +01005510HeapStatistics::HeapStatistics()
5511 : total_heap_size_(0),
5512 total_heap_size_executable_(0),
5513 total_physical_size_(0),
5514 total_available_size_(0),
5515 used_heap_size_(0),
5516 heap_size_limit_(0),
5517 malloced_memory_(0),
5518 does_zap_garbage_(0) {}
Steve Block3ce2e202009-11-05 08:53:23 +00005519
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005520HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
5521 space_size_(0),
5522 space_used_size_(0),
5523 space_available_size_(0),
5524 physical_space_size_(0) { }
5525
5526
5527HeapObjectStatistics::HeapObjectStatistics()
5528 : object_type_(nullptr),
5529 object_sub_type_(nullptr),
5530 object_count_(0),
5531 object_size_(0) {}
5532
5533
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005534bool v8::V8::InitializeICU(const char* icu_data_file) {
5535 return i::InitializeICU(icu_data_file);
Steve Block6ded16b2010-05-10 14:33:55 +01005536}
5537
5538
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005539void v8::V8::InitializeExternalStartupData(const char* directory_path) {
5540 i::InitializeExternalStartupData(directory_path);
5541}
5542
5543
5544void v8::V8::InitializeExternalStartupData(const char* natives_blob,
5545 const char* snapshot_blob) {
5546 i::InitializeExternalStartupData(natives_blob, snapshot_blob);
5547}
5548
5549
Steve Blocka7e24c12009-10-30 11:49:00 +00005550const char* v8::V8::GetVersion() {
Steve Block44f0eee2011-05-26 01:26:41 +01005551 return i::Version::GetVersion();
Steve Blocka7e24c12009-10-30 11:49:00 +00005552}
5553
5554
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005555static i::Handle<i::Context> CreateEnvironment(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005556 i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
5557 v8::Local<ObjectTemplate> global_template,
5558 v8::Local<Value> maybe_global_proxy) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005559 i::Handle<i::Context> env;
Steve Blocka7e24c12009-10-30 11:49:00 +00005560
5561 // Enter V8 via an ENTER_V8 scope.
Steve Blocka7e24c12009-10-30 11:49:00 +00005562 {
Steve Block44f0eee2011-05-26 01:26:41 +01005563 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005564 v8::Local<ObjectTemplate> proxy_template = global_template;
Steve Blocka7e24c12009-10-30 11:49:00 +00005565 i::Handle<i::FunctionTemplateInfo> proxy_constructor;
5566 i::Handle<i::FunctionTemplateInfo> global_constructor;
5567
5568 if (!global_template.IsEmpty()) {
5569 // Make sure that the global_template has a constructor.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005570 global_constructor = EnsureConstructor(isolate, *global_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005571
5572 // Create a fresh template for the global proxy object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005573 proxy_template = ObjectTemplate::New(
5574 reinterpret_cast<v8::Isolate*>(isolate));
5575 proxy_constructor = EnsureConstructor(isolate, *proxy_template);
Steve Blocka7e24c12009-10-30 11:49:00 +00005576
5577 // Set the global template to be the prototype template of
5578 // global proxy template.
5579 proxy_constructor->set_prototype_template(
5580 *Utils::OpenHandle(*global_template));
5581
5582 // Migrate security handlers from global_template to
5583 // proxy_template. Temporarily removing access check
5584 // information from the global template.
5585 if (!global_constructor->access_check_info()->IsUndefined()) {
5586 proxy_constructor->set_access_check_info(
5587 global_constructor->access_check_info());
5588 proxy_constructor->set_needs_access_check(
5589 global_constructor->needs_access_check());
5590 global_constructor->set_needs_access_check(false);
Steve Block44f0eee2011-05-26 01:26:41 +01005591 global_constructor->set_access_check_info(
5592 isolate->heap()->undefined_value());
Steve Blocka7e24c12009-10-30 11:49:00 +00005593 }
5594 }
5595
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005596 i::Handle<i::Object> proxy = Utils::OpenHandle(*maybe_global_proxy, true);
5597 i::MaybeHandle<i::JSGlobalProxy> maybe_proxy;
5598 if (!proxy.is_null()) {
5599 maybe_proxy = i::Handle<i::JSGlobalProxy>::cast(proxy);
5600 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005601 // Create the environment.
Steve Block44f0eee2011-05-26 01:26:41 +01005602 env = isolate->bootstrapper()->CreateEnvironment(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005603 maybe_proxy, proxy_template, extensions);
Steve Blocka7e24c12009-10-30 11:49:00 +00005604
5605 // Restore the access check info on the global template.
5606 if (!global_template.IsEmpty()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005607 DCHECK(!global_constructor.is_null());
5608 DCHECK(!proxy_constructor.is_null());
Steve Blocka7e24c12009-10-30 11:49:00 +00005609 global_constructor->set_access_check_info(
5610 proxy_constructor->access_check_info());
5611 global_constructor->set_needs_access_check(
5612 proxy_constructor->needs_access_check());
5613 }
5614 }
5615 // Leave V8.
5616
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005617 return env;
5618}
5619
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005620Local<Context> v8::Context::New(v8::Isolate* external_isolate,
5621 v8::ExtensionConfiguration* extensions,
5622 v8::Local<ObjectTemplate> global_template,
5623 v8::Local<Value> global_object) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005624 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
5625 LOG_API(isolate, "Context::New");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005626 i::HandleScope scope(isolate);
5627 ExtensionConfiguration no_extensions;
5628 if (extensions == NULL) extensions = &no_extensions;
5629 i::Handle<i::Context> env =
5630 CreateEnvironment(isolate, extensions, global_template, global_object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005631 if (env.is_null()) {
5632 if (isolate->has_pending_exception()) {
5633 isolate->OptionalRescheduleException(true);
5634 }
5635 return Local<Context>();
5636 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005637 return Utils::ToLocal(scope.CloseAndEscape(env));
Steve Blocka7e24c12009-10-30 11:49:00 +00005638}
5639
5640
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005641void v8::Context::SetSecurityToken(Local<Value> token) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005642 i::Handle<i::Context> env = Utils::OpenHandle(this);
5643 i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
5644 env->set_security_token(*token_handle);
5645}
5646
5647
5648void v8::Context::UseDefaultSecurityToken() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005649 i::Handle<i::Context> env = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005650 env->set_security_token(env->global_object());
Steve Blocka7e24c12009-10-30 11:49:00 +00005651}
5652
5653
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005654Local<Value> v8::Context::GetSecurityToken() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005655 i::Handle<i::Context> env = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005656 i::Isolate* isolate = env->GetIsolate();
Steve Blocka7e24c12009-10-30 11:49:00 +00005657 i::Object* security_token = env->security_token();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005658 i::Handle<i::Object> token_handle(security_token, isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00005659 return Utils::ToLocal(token_handle);
5660}
5661
5662
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005663v8::Isolate* Context::GetIsolate() {
Steve Blocka7e24c12009-10-30 11:49:00 +00005664 i::Handle<i::Context> env = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005665 return reinterpret_cast<Isolate*>(env->GetIsolate());
Steve Blocka7e24c12009-10-30 11:49:00 +00005666}
5667
5668
5669v8::Local<v8::Object> Context::Global() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005670 i::Handle<i::Context> context = Utils::OpenHandle(this);
5671 i::Isolate* isolate = context->GetIsolate();
5672 i::Handle<i::Object> global(context->global_proxy(), isolate);
5673 // TODO(dcarney): This should always return the global proxy
5674 // but can't presently as calls to GetProtoype will return the wrong result.
5675 if (i::Handle<i::JSGlobalProxy>::cast(
5676 global)->IsDetachedFrom(context->global_object())) {
5677 global = i::Handle<i::Object>(context->global_object(), isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005678 }
Steve Blocka7e24c12009-10-30 11:49:00 +00005679 return Utils::ToLocal(i::Handle<i::JSObject>::cast(global));
5680}
5681
5682
5683void Context::DetachGlobal() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005684 i::Handle<i::Context> context = Utils::OpenHandle(this);
5685 i::Isolate* isolate = context->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005686 ENTER_V8(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01005687 isolate->bootstrapper()->DetachGlobal(context);
Steve Blocka7e24c12009-10-30 11:49:00 +00005688}
5689
5690
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005691Local<v8::Object> Context::GetExtrasBindingObject() {
5692 i::Handle<i::Context> context = Utils::OpenHandle(this);
5693 i::Isolate* isolate = context->GetIsolate();
5694 i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
5695 return Utils::ToLocal(binding);
5696}
5697
5698
Ben Murdoch257744e2011-11-30 15:57:28 +00005699void Context::AllowCodeGenerationFromStrings(bool allow) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005700 i::Handle<i::Context> context = Utils::OpenHandle(this);
5701 i::Isolate* isolate = context->GetIsolate();
Ben Murdoch257744e2011-11-30 15:57:28 +00005702 ENTER_V8(isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00005703 context->set_allow_code_gen_from_strings(
5704 allow ? isolate->heap()->true_value() : isolate->heap()->false_value());
5705}
5706
5707
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005708bool Context::IsCodeGenerationFromStringsAllowed() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005709 i::Handle<i::Context> context = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01005710 return !context->allow_code_gen_from_strings()->IsFalse();
5711}
5712
5713
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005714void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005715 i::Handle<i::Context> context = Utils::OpenHandle(this);
5716 i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
5717 context->set_error_message_for_code_gen_from_strings(*error_handle);
Andrei Popescu74b3c142010-03-29 12:03:09 +01005718}
5719
5720
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005721size_t Context::EstimatedSize() {
5722 return static_cast<size_t>(
5723 i::ContextMeasure(*Utils::OpenHandle(this)).Size());
5724}
5725
5726
5727MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
5728 PREPARE_FOR_EXECUTION(context, "v8::ObjectTemplate::NewInstance()", Object);
5729 auto self = Utils::OpenHandle(this);
5730 Local<Object> result;
5731 has_pending_exception =
5732 !ToLocal<Object>(i::ApiNatives::InstantiateObject(self), &result);
5733 RETURN_ON_FAILED_EXECUTION(Object);
5734 RETURN_ESCAPED(result);
5735}
5736
5737
Steve Blocka7e24c12009-10-30 11:49:00 +00005738Local<v8::Object> ObjectTemplate::NewInstance() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005739 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5740 RETURN_TO_LOCAL_UNCHECKED(NewInstance(context), Object);
5741}
5742
5743
5744MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
5745 PREPARE_FOR_EXECUTION(context, "v8::FunctionTemplate::GetFunction()",
5746 Function);
5747 auto self = Utils::OpenHandle(this);
5748 Local<Function> result;
5749 has_pending_exception =
5750 !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
5751 RETURN_ON_FAILED_EXECUTION(Function);
5752 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00005753}
5754
5755
5756Local<v8::Function> FunctionTemplate::GetFunction() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005757 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
5758 RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function);
Steve Blocka7e24c12009-10-30 11:49:00 +00005759}
5760
5761
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005762bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
5763 auto self = Utils::OpenHandle(this);
5764 auto obj = Utils::OpenHandle(*value);
5765 return self->IsTemplateFor(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00005766}
5767
5768
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005769Local<External> v8::External::New(Isolate* isolate, void* value) {
5770 STATIC_ASSERT(sizeof(value) == sizeof(i::Address));
5771 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5772 LOG_API(i_isolate, "External::New");
5773 ENTER_V8(i_isolate);
5774 i::Handle<i::JSObject> external = i_isolate->factory()->NewExternal(value);
5775 return Utils::ExternalToLocal(external);
Steve Blocka7e24c12009-10-30 11:49:00 +00005776}
5777
5778
5779void* External::Value() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005780 return ExternalValue(*Utils::OpenHandle(this));
Steve Blocka7e24c12009-10-30 11:49:00 +00005781}
5782
5783
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005784// anonymous namespace for string creation helper functions
5785namespace {
5786
5787inline int StringLength(const char* string) {
5788 return i::StrLength(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005789}
5790
5791
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005792inline int StringLength(const uint8_t* string) {
5793 return i::StrLength(reinterpret_cast<const char*>(string));
5794}
5795
5796
5797inline int StringLength(const uint16_t* string) {
5798 int length = 0;
5799 while (string[length] != '\0')
5800 length++;
5801 return length;
5802}
5803
5804
5805MUST_USE_RESULT
5806inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005807 v8::NewStringType type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005808 i::Vector<const char> string) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005809 if (type == v8::NewStringType::kInternalized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005810 return factory->InternalizeUtf8String(string);
5811 }
5812 return factory->NewStringFromUtf8(string);
5813}
5814
5815
5816MUST_USE_RESULT
5817inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005818 v8::NewStringType type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005819 i::Vector<const uint8_t> string) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005820 if (type == v8::NewStringType::kInternalized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005821 return factory->InternalizeOneByteString(string);
5822 }
5823 return factory->NewStringFromOneByte(string);
5824}
5825
5826
5827MUST_USE_RESULT
5828inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005829 v8::NewStringType type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005830 i::Vector<const uint16_t> string) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005831 if (type == v8::NewStringType::kInternalized) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005832 return factory->InternalizeTwoByteString(string);
5833 }
5834 return factory->NewStringFromTwoByte(string);
5835}
5836
5837
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005838STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
5839
5840
5841template <typename Char>
5842inline MaybeLocal<String> NewString(Isolate* v8_isolate, const char* location,
5843 const char* env, const Char* data,
5844 v8::NewStringType type, int length) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005845 i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005846 if (length == 0) return String::Empty(v8_isolate);
5847 // TODO(dcarney): throw a context free exception.
5848 if (length > i::String::kMaxLength) return MaybeLocal<String>();
Steve Block44f0eee2011-05-26 01:26:41 +01005849 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005850 LOG_API(isolate, env);
5851 if (length < 0) length = StringLength(data);
5852 i::Handle<i::String> result =
5853 NewString(isolate->factory(), type, i::Vector<const Char>(data, length))
5854 .ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00005855 return Utils::ToLocal(result);
5856}
5857
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005858} // anonymous namespace
5859
5860
5861Local<String> String::NewFromUtf8(Isolate* isolate,
5862 const char* data,
5863 NewStringType type,
5864 int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005865 RETURN_TO_LOCAL_UNCHECKED(
5866 NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
5867 data, static_cast<v8::NewStringType>(type), length),
5868 String);
5869}
5870
5871
5872MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
5873 v8::NewStringType type, int length) {
5874 return NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
5875 data, type, length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005876}
5877
5878
5879Local<String> String::NewFromOneByte(Isolate* isolate,
5880 const uint8_t* data,
5881 NewStringType type,
5882 int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005883 RETURN_TO_LOCAL_UNCHECKED(
5884 NewString(isolate, "v8::String::NewFromOneByte()",
5885 "String::NewFromOneByte", data,
5886 static_cast<v8::NewStringType>(type), length),
5887 String);
5888}
5889
5890
5891MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
5892 v8::NewStringType type, int length) {
5893 return NewString(isolate, "v8::String::NewFromOneByte()",
5894 "String::NewFromOneByte", data, type, length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005895}
5896
5897
5898Local<String> String::NewFromTwoByte(Isolate* isolate,
5899 const uint16_t* data,
5900 NewStringType type,
5901 int length) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005902 RETURN_TO_LOCAL_UNCHECKED(
5903 NewString(isolate, "v8::String::NewFromTwoByte()",
5904 "String::NewFromTwoByte", data,
5905 static_cast<v8::NewStringType>(type), length),
5906 String);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005907}
5908
Steve Blocka7e24c12009-10-30 11:49:00 +00005909
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005910MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
5911 const uint16_t* data,
5912 v8::NewStringType type, int length) {
5913 return NewString(isolate, "v8::String::NewFromTwoByte()",
5914 "String::NewFromTwoByte", data, type, length);
5915}
5916
5917
5918Local<String> v8::String::Concat(Local<String> left, Local<String> right) {
Steve Block3ce2e202009-11-05 08:53:23 +00005919 i::Handle<i::String> left_string = Utils::OpenHandle(*left);
Steve Block44f0eee2011-05-26 01:26:41 +01005920 i::Isolate* isolate = left_string->GetIsolate();
Steve Block44f0eee2011-05-26 01:26:41 +01005921 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005922 LOG_API(isolate, "v8::String::Concat");
Steve Block3ce2e202009-11-05 08:53:23 +00005923 i::Handle<i::String> right_string = Utils::OpenHandle(*right);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005924 // If we are steering towards a range error, do not wait for the error to be
5925 // thrown, and return the null handle instead.
5926 if (left_string->length() + right_string->length() > i::String::kMaxLength) {
5927 return Local<String>();
5928 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005929 i::Handle<i::String> result = isolate->factory()->NewConsString(
5930 left_string, right_string).ToHandleChecked();
Steve Block3ce2e202009-11-05 08:53:23 +00005931 return Utils::ToLocal(result);
5932}
5933
5934
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005935MaybeLocal<String> v8::String::NewExternalTwoByte(
5936 Isolate* isolate, v8::String::ExternalStringResource* resource) {
5937 CHECK(resource && resource->data());
5938 // TODO(dcarney): throw a context free exception.
5939 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
5940 return MaybeLocal<String>();
5941 }
5942 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5943 ENTER_V8(i_isolate);
5944 LOG_API(i_isolate, "String::NewExternalTwoByte");
5945 i::Handle<i::String> string = i_isolate->factory()
5946 ->NewExternalStringFromTwoByte(resource)
5947 .ToHandleChecked();
5948 i_isolate->heap()->RegisterExternalString(*string);
5949 return Utils::ToLocal(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005950}
5951
5952
Steve Blocka7e24c12009-10-30 11:49:00 +00005953Local<String> v8::String::NewExternal(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005954 Isolate* isolate, v8::String::ExternalStringResource* resource) {
5955 RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String);
5956}
5957
5958
5959MaybeLocal<String> v8::String::NewExternalOneByte(
5960 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005961 CHECK(resource && resource->data());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005962 // TODO(dcarney): throw a context free exception.
5963 if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
5964 return MaybeLocal<String>();
5965 }
5966 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
5967 ENTER_V8(i_isolate);
5968 LOG_API(i_isolate, "String::NewExternalOneByte");
5969 i::Handle<i::String> string = i_isolate->factory()
5970 ->NewExternalStringFromOneByte(resource)
5971 .ToHandleChecked();
5972 i_isolate->heap()->RegisterExternalString(*string);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04005973 return Utils::ToLocal(string);
Steve Blocka7e24c12009-10-30 11:49:00 +00005974}
5975
5976
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005977Local<String> v8::String::NewExternal(
5978 Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
5979 RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String);
5980}
5981
5982
Steve Blocka7e24c12009-10-30 11:49:00 +00005983bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00005984 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01005985 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005986 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01005987 return false; // Already an external string.
5988 }
5989 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00005990 if (isolate->heap()->IsInGCPostProcessing()) {
5991 return false;
5992 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005993 CHECK(resource && resource->data());
5994
Steve Blocka7e24c12009-10-30 11:49:00 +00005995 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005996 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
5997 DCHECK(!CanMakeExternal() || result);
5998 if (result) {
5999 DCHECK(obj->IsExternalString());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006000 isolate->heap()->RegisterExternalString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00006001 }
6002 return result;
6003}
6004
6005
Steve Blocka7e24c12009-10-30 11:49:00 +00006006bool v8::String::MakeExternal(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006007 v8::String::ExternalOneByteStringResource* resource) {
Steve Blocka7e24c12009-10-30 11:49:00 +00006008 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01006009 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006010 if (i::StringShape(*obj).IsExternal()) {
Steve Block44f0eee2011-05-26 01:26:41 +01006011 return false; // Already an external string.
6012 }
6013 ENTER_V8(isolate);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006014 if (isolate->heap()->IsInGCPostProcessing()) {
6015 return false;
6016 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006017 CHECK(resource && resource->data());
6018
Steve Blocka7e24c12009-10-30 11:49:00 +00006019 bool result = obj->MakeExternal(resource);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006020 // Assert that if CanMakeExternal(), then externalizing actually succeeds.
6021 DCHECK(!CanMakeExternal() || result);
6022 if (result) {
6023 DCHECK(obj->IsExternalString());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006024 isolate->heap()->RegisterExternalString(*obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00006025 }
6026 return result;
6027}
6028
6029
6030bool v8::String::CanMakeExternal() {
Steve Blocka7e24c12009-10-30 11:49:00 +00006031 i::Handle<i::String> obj = Utils::OpenHandle(this);
Steve Block44f0eee2011-05-26 01:26:41 +01006032 i::Isolate* isolate = obj->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006033
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006034 // Old space strings should be externalized.
6035 if (!isolate->heap()->new_space()->Contains(*obj)) return true;
Steve Blocka7e24c12009-10-30 11:49:00 +00006036 int size = obj->Size(); // Byte size of the original string.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006037 if (size <= i::ExternalString::kShortSize) return false;
Steve Blocka7e24c12009-10-30 11:49:00 +00006038 i::StringShape shape(*obj);
6039 return !shape.IsExternal();
6040}
6041
6042
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006043Isolate* v8::Object::GetIsolate() {
6044 i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
6045 return reinterpret_cast<Isolate*>(i_isolate);
6046}
6047
6048
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006049Local<v8::Object> v8::Object::New(Isolate* isolate) {
6050 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6051 LOG_API(i_isolate, "Object::New");
6052 ENTER_V8(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00006053 i::Handle<i::JSObject> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006054 i_isolate->factory()->NewJSObject(i_isolate->object_function());
Steve Blocka7e24c12009-10-30 11:49:00 +00006055 return Utils::ToLocal(obj);
6056}
6057
6058
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006059Local<v8::Value> v8::NumberObject::New(Isolate* isolate, double value) {
6060 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6061 LOG_API(i_isolate, "NumberObject::New");
6062 ENTER_V8(i_isolate);
6063 i::Handle<i::Object> number = i_isolate->factory()->NewNumber(value);
6064 i::Handle<i::Object> obj =
6065 i::Object::ToObject(i_isolate, number).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006066 return Utils::ToLocal(obj);
6067}
6068
6069
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006070double v8::NumberObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006071 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6072 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006073 i::Isolate* isolate = jsvalue->GetIsolate();
6074 LOG_API(isolate, "NumberObject::NumberValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006075 return jsvalue->value()->Number();
6076}
6077
6078
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006079Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
6080 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6081 LOG_API(i_isolate, "BooleanObject::New");
6082 ENTER_V8(i_isolate);
6083 i::Handle<i::Object> boolean(value ? i_isolate->heap()->true_value()
6084 : i_isolate->heap()->false_value(),
6085 i_isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006086 i::Handle<i::Object> obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006087 i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006088 return Utils::ToLocal(obj);
6089}
6090
6091
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006092Local<v8::Value> v8::BooleanObject::New(bool value) {
6093 return New(Isolate::GetCurrent(), value);
6094}
6095
6096
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006097bool v8::BooleanObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006098 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6099 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006100 i::Isolate* isolate = jsvalue->GetIsolate();
6101 LOG_API(isolate, "BooleanObject::BooleanValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006102 return jsvalue->value()->IsTrue();
6103}
6104
6105
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006106Local<v8::Value> v8::StringObject::New(Local<String> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006107 i::Handle<i::String> string = Utils::OpenHandle(*value);
6108 i::Isolate* isolate = string->GetIsolate();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006109 LOG_API(isolate, "StringObject::New");
6110 ENTER_V8(isolate);
6111 i::Handle<i::Object> obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006112 i::Object::ToObject(isolate, string).ToHandleChecked();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006113 return Utils::ToLocal(obj);
6114}
6115
6116
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006117Local<v8::String> v8::StringObject::ValueOf() const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006118 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6119 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006120 i::Isolate* isolate = jsvalue->GetIsolate();
6121 LOG_API(isolate, "StringObject::StringValue");
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00006122 return Utils::ToLocal(
6123 i::Handle<i::String>(i::String::cast(jsvalue->value())));
6124}
6125
6126
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006127Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006128 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6129 LOG_API(i_isolate, "SymbolObject::New");
6130 ENTER_V8(i_isolate);
6131 i::Handle<i::Object> obj = i::Object::ToObject(
6132 i_isolate, Utils::OpenHandle(*value)).ToHandleChecked();
Steve Blocka7e24c12009-10-30 11:49:00 +00006133 return Utils::ToLocal(obj);
6134}
6135
6136
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006137Local<v8::Symbol> v8::SymbolObject::ValueOf() const {
6138 i::Handle<i::Object> obj = Utils::OpenHandle(this);
6139 i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
6140 i::Isolate* isolate = jsvalue->GetIsolate();
6141 LOG_API(isolate, "SymbolObject::SymbolValue");
6142 return Utils::ToLocal(
6143 i::Handle<i::Symbol>(i::Symbol::cast(jsvalue->value())));
6144}
6145
6146
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006147MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006148 if (std::isnan(time)) {
6149 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006150 time = std::numeric_limits<double>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006151 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006152 PREPARE_FOR_EXECUTION(context, "Date::New", Value);
6153 Local<Value> result;
6154 has_pending_exception = !ToLocal<Value>(
6155 i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
6156 &result);
6157 RETURN_ON_FAILED_EXECUTION(Value);
6158 RETURN_ESCAPED(result);
6159}
6160
6161
6162Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
6163 auto context = isolate->GetCurrentContext();
6164 RETURN_TO_LOCAL_UNCHECKED(New(context, time), Value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006165}
6166
6167
6168double v8::Date::ValueOf() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00006169 i::Handle<i::Object> obj = Utils::OpenHandle(this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006170 i::Handle<i::JSDate> jsdate = i::Handle<i::JSDate>::cast(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006171 i::Isolate* isolate = jsdate->GetIsolate();
6172 LOG_API(isolate, "Date::NumberValue");
Ben Murdoch3ef787d2012-04-12 10:51:47 +01006173 return jsdate->value()->Number();
Steve Blocka7e24c12009-10-30 11:49:00 +00006174}
6175
6176
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006177void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
6178 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006179 LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
6180 ENTER_V8(i_isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006181 i_isolate->date_cache()->ResetDateCache();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006182 if (!i_isolate->eternal_handles()->Exists(
6183 i::EternalHandles::DATE_CACHE_VERSION)) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01006184 return;
6185 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006186 i::Handle<i::FixedArray> date_cache_version =
6187 i::Handle<i::FixedArray>::cast(i_isolate->eternal_handles()->GetSingleton(
6188 i::EternalHandles::DATE_CACHE_VERSION));
6189 DCHECK_EQ(1, date_cache_version->length());
6190 CHECK(date_cache_version->get(0)->IsSmi());
6191 date_cache_version->set(
6192 0,
6193 i::Smi::FromInt(i::Smi::cast(date_cache_version->get(0))->value() + 1));
Ben Murdochb0fe1622011-05-05 13:52:32 +01006194}
6195
6196
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006197MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
6198 Local<String> pattern, Flags flags) {
6199 PREPARE_FOR_EXECUTION(context, "RegExp::New", RegExp);
6200 Local<v8::RegExp> result;
6201 has_pending_exception =
6202 !ToLocal<RegExp>(i::JSRegExp::New(Utils::OpenHandle(*pattern),
6203 static_cast<i::JSRegExp::Flags>(flags)),
6204 &result);
6205 RETURN_ON_FAILED_EXECUTION(RegExp);
6206 RETURN_ESCAPED(result);
Ben Murdochf87a2032010-10-22 12:50:53 +01006207}
6208
6209
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006210Local<v8::RegExp> v8::RegExp::New(Local<String> pattern, Flags flags) {
6211 auto isolate =
6212 reinterpret_cast<Isolate*>(Utils::OpenHandle(*pattern)->GetIsolate());
6213 auto context = isolate->GetCurrentContext();
6214 RETURN_TO_LOCAL_UNCHECKED(New(context, pattern, flags), RegExp);
Ben Murdochf87a2032010-10-22 12:50:53 +01006215}
6216
6217
6218Local<v8::String> v8::RegExp::GetSource() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01006219 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
6220 return Utils::ToLocal(i::Handle<i::String>(obj->Pattern()));
6221}
6222
6223
6224// Assert that the static flags cast in GetFlags is valid.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006225#define REGEXP_FLAG_ASSERT_EQ(flag) \
6226 STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
6227 static_cast<int>(i::JSRegExp::flag))
6228REGEXP_FLAG_ASSERT_EQ(kNone);
6229REGEXP_FLAG_ASSERT_EQ(kGlobal);
6230REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
6231REGEXP_FLAG_ASSERT_EQ(kMultiline);
6232REGEXP_FLAG_ASSERT_EQ(kSticky);
6233REGEXP_FLAG_ASSERT_EQ(kUnicode);
Ben Murdochf87a2032010-10-22 12:50:53 +01006234#undef REGEXP_FLAG_ASSERT_EQ
6235
6236v8::RegExp::Flags v8::RegExp::GetFlags() const {
Ben Murdochf87a2032010-10-22 12:50:53 +01006237 i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006238 return RegExp::Flags(static_cast<int>(obj->GetFlags()));
Ben Murdochf87a2032010-10-22 12:50:53 +01006239}
6240
6241
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006242Local<v8::Array> v8::Array::New(Isolate* isolate, int length) {
6243 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6244 LOG_API(i_isolate, "Array::New");
6245 ENTER_V8(i_isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01006246 int real_length = length > 0 ? length : 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006247 i::Handle<i::JSArray> obj = i_isolate->factory()->NewJSArray(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01006248 i::Handle<i::Object> length_obj =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006249 i_isolate->factory()->NewNumberFromInt(real_length);
Ben Murdoch8b112d22011-06-08 16:22:53 +01006250 obj->set_length(*length_obj);
Steve Blocka7e24c12009-10-30 11:49:00 +00006251 return Utils::ToLocal(obj);
6252}
6253
6254
6255uint32_t v8::Array::Length() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00006256 i::Handle<i::JSArray> obj = Utils::OpenHandle(this);
6257 i::Object* length = obj->length();
6258 if (length->IsSmi()) {
6259 return i::Smi::cast(length)->value();
6260 } else {
6261 return static_cast<uint32_t>(length->Number());
6262 }
6263}
6264
6265
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006266MaybeLocal<Object> Array::CloneElementAt(Local<Context> context,
6267 uint32_t index) {
6268 PREPARE_FOR_EXECUTION(context, "v8::Array::CloneElementAt()", Object);
6269 auto self = Utils::OpenHandle(this);
6270 if (!self->HasFastObjectElements()) return Local<Object>();
Steve Blocka7e24c12009-10-30 11:49:00 +00006271 i::FixedArray* elms = i::FixedArray::cast(self->elements());
6272 i::Object* paragon = elms->get(index);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006273 if (!paragon->IsJSObject()) return Local<Object>();
Steve Blocka7e24c12009-10-30 11:49:00 +00006274 i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006275 Local<Object> result;
6276 has_pending_exception =
6277 !ToLocal<Object>(isolate->factory()->CopyJSObject(paragon_handle),
6278 &result);
6279 RETURN_ON_FAILED_EXECUTION(Object);
6280 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00006281}
6282
6283
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006284Local<Object> Array::CloneElementAt(uint32_t index) { return Local<Object>(); }
6285
6286
6287Local<v8::Map> v8::Map::New(Isolate* isolate) {
6288 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6289 LOG_API(i_isolate, "Map::New");
6290 ENTER_V8(i_isolate);
6291 i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
6292 return Utils::ToLocal(obj);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006293}
6294
6295
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006296size_t v8::Map::Size() const {
6297 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
6298 return i::OrderedHashMap::cast(obj->table())->NumberOfElements();
6299}
6300
6301
6302void Map::Clear() {
6303 auto self = Utils::OpenHandle(this);
6304 i::Isolate* isolate = self->GetIsolate();
6305 LOG_API(isolate, "Map::Clear");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006306 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006307 i::JSMap::Clear(self);
6308}
6309
6310
6311MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
6312 PREPARE_FOR_EXECUTION(context, "Map::Get", Value);
6313 auto self = Utils::OpenHandle(this);
6314 Local<Value> result;
6315 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6316 has_pending_exception =
6317 !ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
6318 arraysize(argv), argv),
6319 &result);
6320 RETURN_ON_FAILED_EXECUTION(Value);
6321 RETURN_ESCAPED(result);
6322}
6323
6324
6325MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
6326 Local<Value> value) {
6327 PREPARE_FOR_EXECUTION(context, "Map::Set", Map);
6328 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006329 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006330 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
6331 Utils::OpenHandle(*value)};
6332 has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self,
6333 arraysize(argv), argv)
6334 .ToHandle(&result);
6335 RETURN_ON_FAILED_EXECUTION(Map);
6336 RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
6337}
6338
6339
6340Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
6341 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Has", bool);
6342 auto self = Utils::OpenHandle(this);
6343 i::Handle<i::Object> result;
6344 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6345 has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self,
6346 arraysize(argv), argv)
6347 .ToHandle(&result);
6348 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6349 return Just(result->IsTrue());
6350}
6351
6352
6353Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
6354 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Delete", bool);
6355 auto self = Utils::OpenHandle(this);
6356 i::Handle<i::Object> result;
6357 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6358 has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(),
6359 self, arraysize(argv), argv)
6360 .ToHandle(&result);
6361 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6362 return Just(result->IsTrue());
6363}
6364
6365
6366Local<Array> Map::AsArray() const {
6367 i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
6368 i::Isolate* isolate = obj->GetIsolate();
6369 i::Factory* factory = isolate->factory();
6370 LOG_API(isolate, "Map::AsArray");
6371 ENTER_V8(isolate);
6372 i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(obj->table()));
6373 int size = table->NumberOfElements();
6374 int length = size * 2;
6375 i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
6376 for (int i = 0; i < size; ++i) {
6377 if (table->KeyAt(i)->IsTheHole()) continue;
6378 result->set(i * 2, table->KeyAt(i));
6379 result->set(i * 2 + 1, table->ValueAt(i));
6380 }
6381 i::Handle<i::JSArray> result_array =
6382 factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
6383 return Utils::ToLocal(result_array);
6384}
6385
6386
6387Local<v8::Set> v8::Set::New(Isolate* isolate) {
6388 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6389 LOG_API(i_isolate, "Set::New");
6390 ENTER_V8(i_isolate);
6391 i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
6392 return Utils::ToLocal(obj);
6393}
6394
6395
6396size_t v8::Set::Size() const {
6397 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
6398 return i::OrderedHashSet::cast(obj->table())->NumberOfElements();
6399}
6400
6401
6402void Set::Clear() {
6403 auto self = Utils::OpenHandle(this);
6404 i::Isolate* isolate = self->GetIsolate();
6405 LOG_API(isolate, "Set::Clear");
6406 ENTER_V8(isolate);
6407 i::JSSet::Clear(self);
6408}
6409
6410
6411MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
6412 PREPARE_FOR_EXECUTION(context, "Set::Add", Set);
6413 auto self = Utils::OpenHandle(this);
6414 i::Handle<i::Object> result;
6415 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6416 has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self,
6417 arraysize(argv), argv)
6418 .ToHandle(&result);
6419 RETURN_ON_FAILED_EXECUTION(Set);
6420 RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
6421}
6422
6423
6424Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
6425 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Has", bool);
6426 auto self = Utils::OpenHandle(this);
6427 i::Handle<i::Object> result;
6428 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6429 has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self,
6430 arraysize(argv), argv)
6431 .ToHandle(&result);
6432 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6433 return Just(result->IsTrue());
6434}
6435
6436
6437Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
6438 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Delete", bool);
6439 auto self = Utils::OpenHandle(this);
6440 i::Handle<i::Object> result;
6441 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
6442 has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(),
6443 self, arraysize(argv), argv)
6444 .ToHandle(&result);
6445 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6446 return Just(result->IsTrue());
6447}
6448
6449
6450Local<Array> Set::AsArray() const {
6451 i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
6452 i::Isolate* isolate = obj->GetIsolate();
6453 i::Factory* factory = isolate->factory();
6454 LOG_API(isolate, "Set::AsArray");
6455 ENTER_V8(isolate);
6456 i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(obj->table()));
6457 int length = table->NumberOfElements();
6458 i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
6459 for (int i = 0; i < length; ++i) {
6460 i::Object* key = table->KeyAt(i);
6461 if (!key->IsTheHole()) {
6462 result->set(i, key);
6463 }
6464 }
6465 i::Handle<i::JSArray> result_array =
6466 factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
6467 return Utils::ToLocal(result_array);
6468}
6469
6470
6471MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
6472 PREPARE_FOR_EXECUTION(context, "Promise::Resolver::New", Resolver);
6473 i::Handle<i::Object> result;
6474 has_pending_exception =
6475 !i::Execution::Call(isolate, isolate->promise_create(),
6476 isolate->factory()->undefined_value(), 0, NULL)
6477 .ToHandle(&result);
6478 RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
6479 RETURN_ESCAPED(Local<Promise::Resolver>::Cast(Utils::ToLocal(result)));
6480}
6481
6482
6483Local<Promise::Resolver> Promise::Resolver::New(Isolate* isolate) {
6484 RETURN_TO_LOCAL_UNCHECKED(New(isolate->GetCurrentContext()),
6485 Promise::Resolver);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006486}
6487
6488
6489Local<Promise> Promise::Resolver::GetPromise() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006490 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006491 return Local<Promise>::Cast(Utils::ToLocal(promise));
6492}
6493
6494
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006495Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
6496 Local<Value> value) {
6497 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
6498 auto self = Utils::OpenHandle(this);
6499 i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
6500 has_pending_exception =
6501 i::Execution::Call(isolate, isolate->promise_resolve(),
6502 isolate->factory()->undefined_value(), arraysize(argv),
6503 argv)
6504 .is_null();
6505 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6506 return Just(true);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006507}
6508
6509
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006510void Promise::Resolver::Resolve(Local<Value> value) {
6511 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6512 USE(Resolve(context, value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006513}
6514
6515
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006516Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
6517 Local<Value> value) {
6518 PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
6519 auto self = Utils::OpenHandle(this);
6520 i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
6521 has_pending_exception =
6522 i::Execution::Call(isolate, isolate->promise_reject(),
6523 isolate->factory()->undefined_value(), arraysize(argv),
6524 argv)
6525 .is_null();
6526 RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
6527 return Just(true);
6528}
6529
6530
6531void Promise::Resolver::Reject(Local<Value> value) {
6532 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6533 USE(Reject(context, value));
6534}
6535
6536
6537namespace {
6538
6539MaybeLocal<Promise> DoChain(Value* value, Local<Context> context,
6540 Local<Function> handler) {
6541 PREPARE_FOR_EXECUTION(context, "Promise::Chain", Promise);
6542 auto self = Utils::OpenHandle(value);
6543 i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
6544 i::Handle<i::Object> result;
6545 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_chain(),
6546 self, arraysize(argv), argv)
6547 .ToHandle(&result);
6548 RETURN_ON_FAILED_EXECUTION(Promise);
6549 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
6550}
6551
6552} // namespace
6553
6554
6555MaybeLocal<Promise> Promise::Chain(Local<Context> context,
6556 Local<Function> handler) {
6557 return DoChain(this, context, handler);
6558}
6559
6560
6561Local<Promise> Promise::Chain(Local<Function> handler) {
6562 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6563 RETURN_TO_LOCAL_UNCHECKED(DoChain(this, context, handler), Promise);
6564}
6565
6566
6567MaybeLocal<Promise> Promise::Catch(Local<Context> context,
6568 Local<Function> handler) {
6569 PREPARE_FOR_EXECUTION(context, "Promise::Catch", Promise);
6570 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006571 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
6572 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006573 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(),
6574 self, arraysize(argv), argv)
6575 .ToHandle(&result);
6576 RETURN_ON_FAILED_EXECUTION(Promise);
6577 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006578}
6579
6580
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006581Local<Promise> Promise::Catch(Local<Function> handler) {
6582 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6583 RETURN_TO_LOCAL_UNCHECKED(Catch(context, handler), Promise);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006584}
6585
6586
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006587MaybeLocal<Promise> Promise::Then(Local<Context> context,
6588 Local<Function> handler) {
6589 PREPARE_FOR_EXECUTION(context, "Promise::Then", Promise);
6590 auto self = Utils::OpenHandle(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006591 i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
6592 i::Handle<i::Object> result;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006593 has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
6594 self, arraysize(argv), argv)
6595 .ToHandle(&result);
6596 RETURN_ON_FAILED_EXECUTION(Promise);
6597 RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
6598}
6599
6600
6601Local<Promise> Promise::Then(Local<Function> handler) {
6602 auto context = ContextFromHeapObject(Utils::OpenHandle(this));
6603 RETURN_TO_LOCAL_UNCHECKED(Then(context, handler), Promise);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006604}
6605
6606
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006607bool Promise::HasHandler() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006608 i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006609 i::Isolate* isolate = promise->GetIsolate();
6610 LOG_API(isolate, "Promise::HasRejectHandler");
6611 ENTER_V8(isolate);
6612 i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006613 return i::JSReceiver::GetDataProperty(promise, key)->IsTrue();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006614}
6615
6616
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006617Local<Object> Proxy::GetTarget() {
6618 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6619 i::Handle<i::JSReceiver> target(self->target());
6620 return Utils::ToLocal(target);
6621}
6622
6623
6624Local<Value> Proxy::GetHandler() {
6625 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6626 i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
6627 return Utils::ToLocal(handler);
6628}
6629
6630
6631bool Proxy::IsRevoked() {
6632 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6633 return self->IsRevoked();
6634}
6635
6636
6637void Proxy::Revoke() {
6638 i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
6639 i::JSProxy::Revoke(self);
6640}
6641
6642
6643MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
6644 Local<Object> local_handler) {
6645 PREPARE_FOR_EXECUTION(context, "Proxy::New", Proxy);
6646 i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
6647 i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
6648 Local<Proxy> result;
6649 has_pending_exception =
6650 !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
6651 RETURN_ON_FAILED_EXECUTION(Proxy);
6652 RETURN_ESCAPED(result);
6653}
6654
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006655bool v8::ArrayBuffer::IsExternal() const {
6656 return Utils::OpenHandle(this)->is_external();
6657}
6658
6659
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006660bool v8::ArrayBuffer::IsNeuterable() const {
6661 return Utils::OpenHandle(this)->is_neuterable();
6662}
6663
6664
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006665v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006666 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6667 i::Isolate* isolate = self->GetIsolate();
6668 Utils::ApiCheck(!self->is_external(), "v8::ArrayBuffer::Externalize",
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006669 "ArrayBuffer already externalized");
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006670 self->set_is_external(true);
6671 isolate->heap()->UnregisterArrayBuffer(*self);
6672
6673 return GetContents();
6674}
6675
6676
6677v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
6678 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6679 size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006680 Contents contents;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006681 contents.data_ = self->backing_store();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006682 contents.byte_length_ = byte_length;
6683 return contents;
6684}
6685
6686
6687void v8::ArrayBuffer::Neuter() {
6688 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6689 i::Isolate* isolate = obj->GetIsolate();
6690 Utils::ApiCheck(obj->is_external(),
6691 "v8::ArrayBuffer::Neuter",
6692 "Only externalized ArrayBuffers can be neutered");
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006693 Utils::ApiCheck(obj->is_neuterable(), "v8::ArrayBuffer::Neuter",
6694 "Only neuterable ArrayBuffers can be neutered");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006695 LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
6696 ENTER_V8(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006697 obj->Neuter();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006698}
6699
6700
6701size_t v8::ArrayBuffer::ByteLength() const {
6702 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6703 return static_cast<size_t>(obj->byte_length()->Number());
6704}
6705
6706
6707Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, size_t byte_length) {
6708 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6709 LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
6710 ENTER_V8(i_isolate);
6711 i::Handle<i::JSArrayBuffer> obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006712 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
6713 i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006714 return Utils::ToLocal(obj);
6715}
6716
6717
6718Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006719 size_t byte_length,
6720 ArrayBufferCreationMode mode) {
6721 // Embedders must guarantee that the external backing store is valid.
6722 CHECK(byte_length == 0 || data != NULL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006723 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6724 LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
6725 ENTER_V8(i_isolate);
6726 i::Handle<i::JSArrayBuffer> obj =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006727 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
6728 i::JSArrayBuffer::Setup(obj, i_isolate,
6729 mode == ArrayBufferCreationMode::kExternalized, data,
6730 byte_length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006731 return Utils::ToLocal(obj);
6732}
6733
6734
6735Local<ArrayBuffer> v8::ArrayBufferView::Buffer() {
6736 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6737 i::Handle<i::JSArrayBuffer> buffer;
6738 if (obj->IsJSDataView()) {
6739 i::Handle<i::JSDataView> data_view(i::JSDataView::cast(*obj));
6740 DCHECK(data_view->buffer()->IsJSArrayBuffer());
6741 buffer = i::handle(i::JSArrayBuffer::cast(data_view->buffer()));
6742 } else {
6743 DCHECK(obj->IsJSTypedArray());
6744 buffer = i::JSTypedArray::cast(*obj)->GetBuffer();
6745 }
6746 return Utils::ToLocal(buffer);
6747}
6748
6749
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006750size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
6751 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
6752 i::Isolate* isolate = self->GetIsolate();
6753 size_t byte_offset = i::NumberToSize(isolate, self->byte_offset());
6754 size_t bytes_to_copy =
6755 i::Min(byte_length, i::NumberToSize(isolate, self->byte_length()));
6756 if (bytes_to_copy) {
6757 i::DisallowHeapAllocation no_gc;
6758 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
6759 const char* source = reinterpret_cast<char*>(buffer->backing_store());
6760 if (source == nullptr) {
6761 DCHECK(self->IsJSTypedArray());
6762 i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self));
6763 i::Handle<i::FixedTypedArrayBase> fixed_array(
6764 i::FixedTypedArrayBase::cast(typed_array->elements()));
6765 source = reinterpret_cast<char*>(fixed_array->DataPtr());
6766 }
6767 memcpy(dest, source + byte_offset, bytes_to_copy);
6768 }
6769 return bytes_to_copy;
6770}
6771
6772
6773bool v8::ArrayBufferView::HasBuffer() const {
6774 i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
6775 i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
6776 return buffer->backing_store() != nullptr;
6777}
6778
6779
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006780size_t v8::ArrayBufferView::ByteOffset() {
6781 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6782 return static_cast<size_t>(obj->byte_offset()->Number());
6783}
6784
6785
6786size_t v8::ArrayBufferView::ByteLength() {
6787 i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
6788 return static_cast<size_t>(obj->byte_length()->Number());
6789}
6790
6791
6792size_t v8::TypedArray::Length() {
6793 i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006794 return static_cast<size_t>(obj->length_value());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006795}
6796
6797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006798#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
6799 Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
6800 size_t byte_offset, size_t length) { \
6801 i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
6802 LOG_API(isolate, \
6803 "v8::" #Type "Array::New(Local<ArrayBuffer>, size_t, size_t)"); \
6804 ENTER_V8(isolate); \
6805 if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
6806 "v8::" #Type \
6807 "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
6808 "length exceeds max allowed value")) { \
6809 return Local<Type##Array>(); \
6810 } \
6811 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
6812 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
6813 i::kExternal##Type##Array, buffer, byte_offset, length); \
6814 return Utils::ToLocal##Type##Array(obj); \
6815 } \
6816 Local<Type##Array> Type##Array::New( \
6817 Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
6818 size_t length) { \
6819 CHECK(i::FLAG_harmony_sharedarraybuffer); \
6820 i::Isolate* isolate = \
6821 Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
6822 LOG_API(isolate, "v8::" #Type \
6823 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)"); \
6824 ENTER_V8(isolate); \
6825 if (!Utils::ApiCheck( \
6826 length <= static_cast<size_t>(i::Smi::kMaxValue), \
6827 "v8::" #Type \
6828 "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
6829 "length exceeds max allowed value")) { \
6830 return Local<Type##Array>(); \
6831 } \
6832 i::Handle<i::JSArrayBuffer> buffer = \
6833 Utils::OpenHandle(*shared_array_buffer); \
6834 i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
6835 i::kExternal##Type##Array, buffer, byte_offset, length); \
6836 return Utils::ToLocal##Type##Array(obj); \
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006837 }
6838
6839
6840TYPED_ARRAYS(TYPED_ARRAY_NEW)
6841#undef TYPED_ARRAY_NEW
6842
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006843Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006844 size_t byte_offset, size_t byte_length) {
6845 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
6846 i::Isolate* isolate = buffer->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006847 LOG_API(isolate, "v8::DataView::New(Local<ArrayBuffer>, size_t, size_t)");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006848 ENTER_V8(isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006849 i::Handle<i::JSDataView> obj =
6850 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006851 return Utils::ToLocal(obj);
6852}
6853
6854
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006855Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
6856 size_t byte_offset, size_t byte_length) {
6857 CHECK(i::FLAG_harmony_sharedarraybuffer);
6858 i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
6859 i::Isolate* isolate = buffer->GetIsolate();
6860 LOG_API(isolate,
6861 "v8::DataView::New(Local<SharedArrayBuffer>, size_t, size_t)");
6862 ENTER_V8(isolate);
6863 i::Handle<i::JSDataView> obj =
6864 isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
6865 return Utils::ToLocal(obj);
6866}
6867
6868
6869bool v8::SharedArrayBuffer::IsExternal() const {
6870 return Utils::OpenHandle(this)->is_external();
6871}
6872
6873
6874v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
6875 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6876 i::Isolate* isolate = self->GetIsolate();
6877 Utils::ApiCheck(!self->is_external(), "v8::SharedArrayBuffer::Externalize",
6878 "SharedArrayBuffer already externalized");
6879 self->set_is_external(true);
6880 isolate->heap()->UnregisterArrayBuffer(*self);
6881 return GetContents();
6882}
6883
6884
6885v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() {
6886 i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
6887 size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
6888 Contents contents;
6889 contents.data_ = self->backing_store();
6890 contents.byte_length_ = byte_length;
6891 return contents;
6892}
6893
6894
6895size_t v8::SharedArrayBuffer::ByteLength() const {
6896 i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
6897 return static_cast<size_t>(obj->byte_length()->Number());
6898}
6899
6900
6901Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
6902 size_t byte_length) {
6903 CHECK(i::FLAG_harmony_sharedarraybuffer);
6904 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6905 LOG_API(i_isolate, "v8::SharedArrayBuffer::New(size_t)");
6906 ENTER_V8(i_isolate);
6907 i::Handle<i::JSArrayBuffer> obj =
6908 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
6909 i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length, true,
6910 i::SharedFlag::kShared);
6911 return Utils::ToLocalShared(obj);
6912}
6913
6914
6915Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
6916 Isolate* isolate, void* data, size_t byte_length,
6917 ArrayBufferCreationMode mode) {
6918 CHECK(i::FLAG_harmony_sharedarraybuffer);
6919 // Embedders must guarantee that the external backing store is valid.
6920 CHECK(byte_length == 0 || data != NULL);
6921 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6922 LOG_API(i_isolate, "v8::SharedArrayBuffer::New(void*, size_t)");
6923 ENTER_V8(i_isolate);
6924 i::Handle<i::JSArrayBuffer> obj =
6925 i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
6926 i::JSArrayBuffer::Setup(obj, i_isolate,
6927 mode == ArrayBufferCreationMode::kExternalized, data,
6928 byte_length, i::SharedFlag::kShared);
6929 return Utils::ToLocalShared(obj);
6930}
6931
6932
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006933Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
6934 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6935 LOG_API(i_isolate, "Symbol::New()");
6936 ENTER_V8(i_isolate);
6937 i::Handle<i::Symbol> result = i_isolate->factory()->NewSymbol();
6938 if (!name.IsEmpty()) result->set_name(*Utils::OpenHandle(*name));
Steve Blocka7e24c12009-10-30 11:49:00 +00006939 return Utils::ToLocal(result);
6940}
6941
6942
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006943static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
6944 i::Handle<i::String> name,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006945 i::Handle<i::String> part,
6946 bool private_symbol) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006947 i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
6948 i::Handle<i::JSObject> symbols =
6949 i::Handle<i::JSObject>::cast(
6950 i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
6951 i::Handle<i::Object> symbol =
6952 i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
6953 if (!symbol->IsSymbol()) {
6954 DCHECK(symbol->IsUndefined());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006955 if (private_symbol)
6956 symbol = isolate->factory()->NewPrivateSymbol();
6957 else
6958 symbol = isolate->factory()->NewSymbol();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006959 i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
Ben Murdochda12d292016-06-02 14:46:10 +01006960 i::Object::SetPropertyOrElement(symbols, name, symbol, i::STRICT).Assert();
Steve Blockd0582a62009-12-15 09:54:21 +00006961 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006962 return i::Handle<i::Symbol>::cast(symbol);
6963}
6964
6965
6966Local<Symbol> v8::Symbol::For(Isolate* isolate, Local<String> name) {
6967 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6968 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6969 i::Handle<i::String> part = i_isolate->factory()->for_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006970 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006971}
6972
6973
6974Local<Symbol> v8::Symbol::ForApi(Isolate* isolate, Local<String> name) {
6975 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6976 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
6977 i::Handle<i::String> part = i_isolate->factory()->for_api_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006978 return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006979}
6980
6981
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006982Local<Symbol> v8::Symbol::GetIterator(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006983 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6984 return Utils::ToLocal(i_isolate->factory()->iterator_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006985}
6986
6987
6988Local<Symbol> v8::Symbol::GetUnscopables(Isolate* isolate) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006989 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6990 return Utils::ToLocal(i_isolate->factory()->unscopables_symbol());
6991}
6992
6993
6994Local<Symbol> v8::Symbol::GetToStringTag(Isolate* isolate) {
6995 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
6996 return Utils::ToLocal(i_isolate->factory()->to_string_tag_symbol());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00006997}
6998
6999
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007000Local<Symbol> v8::Symbol::GetIsConcatSpreadable(Isolate* isolate) {
7001 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7002 return Utils::ToLocal(i_isolate->factory()->is_concat_spreadable_symbol());
7003}
7004
7005
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007006Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
7007 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7008 LOG_API(i_isolate, "Private::New()");
7009 ENTER_V8(i_isolate);
7010 i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
7011 if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
7012 Local<Symbol> result = Utils::ToLocal(symbol);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007013 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007014}
7015
7016
7017Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
7018 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7019 i::Handle<i::String> i_name = Utils::OpenHandle(*name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007020 i::Handle<i::String> part = i_isolate->factory()->private_api_string();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007021 Local<Symbol> result =
7022 Utils::ToLocal(SymbolFor(i_isolate, i_name, part, true));
7023 return v8::Local<Private>(reinterpret_cast<Private*>(*result));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007024}
7025
7026
7027Local<Number> v8::Number::New(Isolate* isolate, double value) {
7028 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007029 if (std::isnan(value)) {
7030 // Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007031 value = std::numeric_limits<double>::quiet_NaN();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007032 }
7033 ENTER_V8(internal_isolate);
7034 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00007035 return Utils::NumberToLocal(result);
7036}
7037
7038
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007039Local<Integer> v8::Integer::New(Isolate* isolate, int32_t value) {
7040 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00007041 if (i::Smi::IsValid(value)) {
Steve Block44f0eee2011-05-26 01:26:41 +01007042 return Utils::IntegerToLocal(i::Handle<i::Object>(i::Smi::FromInt(value),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007043 internal_isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00007044 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007045 ENTER_V8(internal_isolate);
7046 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Blocka7e24c12009-10-30 11:49:00 +00007047 return Utils::IntegerToLocal(result);
7048}
7049
7050
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007051Local<Integer> v8::Integer::NewFromUnsigned(Isolate* isolate, uint32_t value) {
7052 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
Steve Block3ce2e202009-11-05 08:53:23 +00007053 bool fits_into_int32_t = (value & (1 << 31)) == 0;
7054 if (fits_into_int32_t) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007055 return Integer::New(isolate, static_cast<int32_t>(value));
Steve Block3ce2e202009-11-05 08:53:23 +00007056 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007057 ENTER_V8(internal_isolate);
7058 i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
Steve Block3ce2e202009-11-05 08:53:23 +00007059 return Utils::IntegerToLocal(result);
7060}
7061
7062
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007063void Isolate::ReportExternalAllocationLimitReached() {
7064 i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
7065 if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
7066 heap->ReportExternalMemoryPressure(
7067 "external memory allocation limit reached.");
Steve Blocka7e24c12009-10-30 11:49:00 +00007068}
7069
7070
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007071HeapProfiler* Isolate::GetHeapProfiler() {
7072 i::HeapProfiler* heap_profiler =
7073 reinterpret_cast<i::Isolate*>(this)->heap_profiler();
7074 return reinterpret_cast<HeapProfiler*>(heap_profiler);
Steve Blocka7e24c12009-10-30 11:49:00 +00007075}
7076
7077
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007078CpuProfiler* Isolate::GetCpuProfiler() {
7079 i::CpuProfiler* cpu_profiler =
7080 reinterpret_cast<i::Isolate*>(this)->cpu_profiler();
7081 return reinterpret_cast<CpuProfiler*>(cpu_profiler);
7082}
7083
7084
7085bool Isolate::InContext() {
7086 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7087 return isolate->context() != NULL;
7088}
7089
7090
7091v8::Local<v8::Context> Isolate::GetCurrentContext() {
7092 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7093 i::Context* context = isolate->context();
7094 if (context == NULL) return Local<Context>();
7095 i::Context* native_context = context->native_context();
7096 if (native_context == NULL) return Local<Context>();
7097 return Utils::ToLocal(i::Handle<i::Context>(native_context));
7098}
7099
7100
7101v8::Local<v8::Context> Isolate::GetCallingContext() {
7102 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7103 i::Handle<i::Object> calling = isolate->GetCallingNativeContext();
7104 if (calling.is_null()) return Local<Context>();
7105 return Utils::ToLocal(i::Handle<i::Context>::cast(calling));
7106}
7107
7108
7109v8::Local<v8::Context> Isolate::GetEnteredContext() {
7110 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7111 i::Handle<i::Object> last =
7112 isolate->handle_scope_implementer()->LastEnteredContext();
7113 if (last.is_null()) return Local<Context>();
7114 return Utils::ToLocal(i::Handle<i::Context>::cast(last));
7115}
7116
7117
7118v8::Local<Value> Isolate::ThrowException(v8::Local<v8::Value> value) {
7119 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7120 ENTER_V8(isolate);
7121 // If we're passed an empty handle, we throw an undefined exception
7122 // to deal more gracefully with out of memory situations.
7123 if (value.IsEmpty()) {
7124 isolate->ScheduleThrow(isolate->heap()->undefined_value());
7125 } else {
7126 isolate->ScheduleThrow(*Utils::OpenHandle(*value));
Steve Block44f0eee2011-05-26 01:26:41 +01007127 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007128 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Steve Blocka7e24c12009-10-30 11:49:00 +00007129}
7130
7131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007132void Isolate::SetObjectGroupId(internal::Object** object, UniqueId id) {
7133 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
7134 internal_isolate->global_handles()->SetObjectGroupId(
7135 v8::internal::Handle<v8::internal::Object>(object).location(),
7136 id);
Steve Blocka7e24c12009-10-30 11:49:00 +00007137}
7138
7139
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007140void Isolate::SetReferenceFromGroup(UniqueId id, internal::Object** object) {
7141 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
7142 internal_isolate->global_handles()->SetReferenceFromGroup(
7143 id,
7144 v8::internal::Handle<v8::internal::Object>(object).location());
7145}
7146
7147
7148void Isolate::SetReference(internal::Object** parent,
7149 internal::Object** child) {
7150 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(this);
7151 i::Object** parent_location =
7152 v8::internal::Handle<v8::internal::Object>(parent).location();
7153 internal_isolate->global_handles()->SetReference(
7154 reinterpret_cast<i::HeapObject**>(parent_location),
7155 v8::internal::Handle<v8::internal::Object>(child).location());
7156}
7157
7158
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007159void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007160 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7161 isolate->heap()->AddGCPrologueCallback(callback, gc_type);
7162}
7163
7164
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007165void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007166 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7167 isolate->heap()->RemoveGCPrologueCallback(callback);
7168}
7169
7170
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007171void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007172 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7173 isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
7174}
7175
7176
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007177void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007178 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7179 isolate->heap()->RemoveGCEpilogueCallback(callback);
Steve Blocka7e24c12009-10-30 11:49:00 +00007180}
7181
7182
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007183void V8::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01007184 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007185 isolate->heap()->AddGCPrologueCallback(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007186 reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
Steve Block6ded16b2010-05-10 14:33:55 +01007187}
7188
7189
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007190void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
Steve Block44f0eee2011-05-26 01:26:41 +01007191 i::Isolate* isolate = i::Isolate::Current();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007192 isolate->heap()->AddGCEpilogueCallback(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007193 reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
Steve Block6ded16b2010-05-10 14:33:55 +01007194}
7195
Ben Murdochda12d292016-06-02 14:46:10 +01007196void Isolate::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) {
7197 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7198 isolate->heap()->SetEmbedderHeapTracer(tracer);
7199}
Steve Block6ded16b2010-05-10 14:33:55 +01007200
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007201void Isolate::AddMemoryAllocationCallback(MemoryAllocationCallback callback,
7202 ObjectSpace space,
7203 AllocationAction action) {
7204 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01007205 isolate->memory_allocator()->AddMemoryAllocationCallback(
7206 callback, space, action);
Iain Merrick9ac36c92010-09-13 15:29:50 +01007207}
7208
7209
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007210void Isolate::RemoveMemoryAllocationCallback(
7211 MemoryAllocationCallback callback) {
7212 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Steve Block44f0eee2011-05-26 01:26:41 +01007213 isolate->memory_allocator()->RemoveMemoryAllocationCallback(
7214 callback);
Iain Merrick9ac36c92010-09-13 15:29:50 +01007215}
7216
7217
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007218void Isolate::TerminateExecution() {
7219 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7220 isolate->stack_guard()->RequestTerminateExecution();
Steve Blocka7e24c12009-10-30 11:49:00 +00007221}
7222
7223
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007224bool Isolate::IsExecutionTerminating() {
7225 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7226 return IsExecutionTerminatingCheck(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01007227}
7228
7229
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007230void Isolate::CancelTerminateExecution() {
7231 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7232 isolate->stack_guard()->ClearTerminateExecution();
7233 isolate->CancelTerminateExecution();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007234}
7235
7236
7237void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007238 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7239 isolate->RequestInterrupt(callback, data);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007240}
7241
7242
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007243void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
7244 CHECK(i::FLAG_expose_gc);
7245 if (type == kMinorGarbageCollection) {
7246 reinterpret_cast<i::Isolate*>(this)->heap()->CollectGarbage(
7247 i::NEW_SPACE, "Isolate::RequestGarbageCollection",
7248 kGCCallbackFlagForced);
7249 } else {
7250 DCHECK_EQ(kFullGarbageCollection, type);
7251 reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
7252 i::Heap::kAbortIncrementalMarkingMask,
7253 "Isolate::RequestGarbageCollection", kGCCallbackFlagForced);
7254 }
7255}
7256
7257
Steve Block44f0eee2011-05-26 01:26:41 +01007258Isolate* Isolate::GetCurrent() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007259 i::Isolate* isolate = i::Isolate::Current();
Steve Block44f0eee2011-05-26 01:26:41 +01007260 return reinterpret_cast<Isolate*>(isolate);
7261}
7262
7263
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007264Isolate* Isolate::New(const Isolate::CreateParams& params) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007265 i::Isolate* isolate = new i::Isolate(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007266 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007267 CHECK(params.array_buffer_allocator != NULL);
7268 isolate->set_array_buffer_allocator(params.array_buffer_allocator);
7269 if (params.snapshot_blob != NULL) {
7270 isolate->set_snapshot_blob(params.snapshot_blob);
7271 } else {
7272 isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
7273 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007274 if (params.entry_hook) {
7275 isolate->set_function_entry_hook(params.entry_hook);
7276 }
Ben Murdoch097c5b22016-05-18 11:27:45 +01007277 auto code_event_handler = params.code_event_handler;
7278#ifdef ENABLE_GDB_JIT_INTERFACE
7279 if (code_event_handler == nullptr && i::FLAG_gdbjit) {
7280 code_event_handler = i::GDBJITInterface::EventHandler;
7281 }
7282#endif // ENABLE_GDB_JIT_INTERFACE
7283 if (code_event_handler) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007284 isolate->InitializeLoggingAndCounters();
7285 isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
Ben Murdoch097c5b22016-05-18 11:27:45 +01007286 code_event_handler);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007287 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007288 if (params.counter_lookup_callback) {
7289 v8_isolate->SetCounterFunction(params.counter_lookup_callback);
7290 }
7291
7292 if (params.create_histogram_callback) {
7293 v8_isolate->SetCreateHistogramFunction(params.create_histogram_callback);
7294 }
7295
7296 if (params.add_histogram_sample_callback) {
7297 v8_isolate->SetAddHistogramSampleFunction(
7298 params.add_histogram_sample_callback);
7299 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007300 SetResourceConstraints(isolate, params.constraints);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007301 // TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
7302 Isolate::Scope isolate_scope(v8_isolate);
7303 if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
7304 // If the isolate has a function entry hook, it needs to re-build all its
7305 // code stubs with entry hooks embedded, so don't deserialize a snapshot.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007306 if (i::Snapshot::EmbedsScript(isolate)) {
7307 // If the snapshot embeds a script, we cannot initialize the isolate
7308 // without the snapshot as a fallback. This is unlikely to happen though.
7309 V8_Fatal(__FILE__, __LINE__,
7310 "Initializing isolate from custom startup snapshot failed");
7311 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007312 isolate->Init(NULL);
7313 }
7314 return v8_isolate;
Steve Block44f0eee2011-05-26 01:26:41 +01007315}
7316
7317
7318void Isolate::Dispose() {
7319 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007320 if (!Utils::ApiCheck(!isolate->IsInUse(),
7321 "v8::Isolate::Dispose()",
7322 "Disposing the isolate that is entered by a thread.")) {
Steve Block44f0eee2011-05-26 01:26:41 +01007323 return;
Steve Block6ded16b2010-05-10 14:33:55 +01007324 }
Steve Block44f0eee2011-05-26 01:26:41 +01007325 isolate->TearDown();
7326}
7327
7328
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007329void Isolate::DiscardThreadSpecificMetadata() {
7330 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7331 isolate->DiscardPerThreadDataForThisThread();
7332}
7333
7334
Steve Block44f0eee2011-05-26 01:26:41 +01007335void Isolate::Enter() {
7336 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7337 isolate->Enter();
7338}
7339
7340
7341void Isolate::Exit() {
7342 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7343 isolate->Exit();
Steve Block6ded16b2010-05-10 14:33:55 +01007344}
7345
7346
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007347void Isolate::SetAbortOnUncaughtExceptionCallback(
7348 AbortOnUncaughtExceptionCallback callback) {
7349 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7350 isolate->SetAbortOnUncaughtExceptionCallback(callback);
7351}
7352
7353
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007354Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
7355 Isolate* isolate,
7356 Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
7357 : on_failure_(on_failure) {
7358 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7359 if (on_failure_ == CRASH_ON_FAILURE) {
7360 internal_ = reinterpret_cast<void*>(
7361 new i::DisallowJavascriptExecution(i_isolate));
7362 } else {
7363 DCHECK_EQ(THROW_ON_FAILURE, on_failure);
7364 internal_ = reinterpret_cast<void*>(
7365 new i::ThrowOnJavascriptExecution(i_isolate));
7366 }
Ben Murdoch257744e2011-11-30 15:57:28 +00007367}
7368
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007369
7370Isolate::DisallowJavascriptExecutionScope::~DisallowJavascriptExecutionScope() {
7371 if (on_failure_ == CRASH_ON_FAILURE) {
7372 delete reinterpret_cast<i::DisallowJavascriptExecution*>(internal_);
7373 } else {
7374 delete reinterpret_cast<i::ThrowOnJavascriptExecution*>(internal_);
7375 }
7376}
7377
7378
7379Isolate::AllowJavascriptExecutionScope::AllowJavascriptExecutionScope(
7380 Isolate* isolate) {
7381 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7382 internal_assert_ = reinterpret_cast<void*>(
7383 new i::AllowJavascriptExecution(i_isolate));
7384 internal_throws_ = reinterpret_cast<void*>(
7385 new i::NoThrowOnJavascriptExecution(i_isolate));
7386}
7387
7388
7389Isolate::AllowJavascriptExecutionScope::~AllowJavascriptExecutionScope() {
7390 delete reinterpret_cast<i::AllowJavascriptExecution*>(internal_assert_);
7391 delete reinterpret_cast<i::NoThrowOnJavascriptExecution*>(internal_throws_);
7392}
7393
7394
7395Isolate::SuppressMicrotaskExecutionScope::SuppressMicrotaskExecutionScope(
7396 Isolate* isolate)
7397 : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
7398 isolate_->handle_scope_implementer()->IncrementCallDepth();
Ben Murdochda12d292016-06-02 14:46:10 +01007399 isolate_->handle_scope_implementer()->IncrementMicrotasksSuppressions();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007400}
7401
7402
7403Isolate::SuppressMicrotaskExecutionScope::~SuppressMicrotaskExecutionScope() {
Ben Murdochda12d292016-06-02 14:46:10 +01007404 isolate_->handle_scope_implementer()->DecrementMicrotasksSuppressions();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007405 isolate_->handle_scope_implementer()->DecrementCallDepth();
7406}
7407
7408
7409void Isolate::GetHeapStatistics(HeapStatistics* heap_statistics) {
Ben Murdoch257744e2011-11-30 15:57:28 +00007410 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007411 i::Heap* heap = isolate->heap();
7412 heap_statistics->total_heap_size_ = heap->CommittedMemory();
7413 heap_statistics->total_heap_size_executable_ =
7414 heap->CommittedMemoryExecutable();
7415 heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007416 heap_statistics->total_available_size_ = heap->Available();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007417 heap_statistics->used_heap_size_ = heap->SizeOfObjects();
7418 heap_statistics->heap_size_limit_ = heap->MaxReserved();
Ben Murdochda12d292016-06-02 14:46:10 +01007419 heap_statistics->malloced_memory_ =
7420 isolate->allocator()->GetCurrentMemoryUsage();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007421 heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
7422}
7423
7424
7425size_t Isolate::NumberOfHeapSpaces() {
7426 return i::LAST_SPACE - i::FIRST_SPACE + 1;
7427}
7428
7429
7430bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
7431 size_t index) {
7432 if (!space_statistics) return false;
7433 if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
7434 return false;
7435
7436 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7437 i::Heap* heap = isolate->heap();
7438 i::Space* space = heap->space(static_cast<int>(index));
7439
7440 space_statistics->space_name_ = heap->GetSpaceName(static_cast<int>(index));
7441 space_statistics->space_size_ = space->CommittedMemory();
7442 space_statistics->space_used_size_ = space->SizeOfObjects();
7443 space_statistics->space_available_size_ = space->Available();
7444 space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
7445 return true;
7446}
7447
7448
7449size_t Isolate::NumberOfTrackedHeapObjectTypes() {
7450 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7451 i::Heap* heap = isolate->heap();
7452 return heap->NumberOfTrackedHeapObjectTypes();
7453}
7454
7455
7456bool Isolate::GetHeapObjectStatisticsAtLastGC(
7457 HeapObjectStatistics* object_statistics, size_t type_index) {
7458 if (!object_statistics) return false;
7459 if (!i::FLAG_track_gc_object_stats) return false;
7460
7461 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7462 i::Heap* heap = isolate->heap();
7463 if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
7464
7465 const char* object_type;
7466 const char* object_sub_type;
7467 size_t object_count = heap->ObjectCountAtLastGC(type_index);
7468 size_t object_size = heap->ObjectSizeAtLastGC(type_index);
7469 if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
7470 // There should be no objects counted when the type is unknown.
7471 DCHECK_EQ(object_count, 0U);
7472 DCHECK_EQ(object_size, 0U);
7473 return false;
7474 }
7475
7476 object_statistics->object_type_ = object_type;
7477 object_statistics->object_sub_type_ = object_sub_type;
7478 object_statistics->object_count_ = object_count;
7479 object_statistics->object_size_ = object_size;
7480 return true;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007481}
7482
7483
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007484void Isolate::GetStackSample(const RegisterState& state, void** frames,
7485 size_t frames_limit, SampleInfo* sample_info) {
7486 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7487 i::TickSample::GetStackSample(isolate, state, i::TickSample::kSkipCEntryFrame,
7488 frames, frames_limit, sample_info);
7489}
7490
7491
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007492void Isolate::SetEventLogger(LogEventCallback that) {
7493 // Do not overwrite the event logger if we want to log explicitly.
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007494 if (i::FLAG_log_internal_timer_events) return;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007495 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7496 isolate->set_event_logger(that);
7497}
7498
7499
Ben Murdoch097c5b22016-05-18 11:27:45 +01007500void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
7501 if (callback == NULL) return;
7502 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7503 isolate->AddBeforeCallEnteredCallback(callback);
7504}
7505
7506
7507void Isolate::RemoveBeforeCallEnteredCallback(
7508 BeforeCallEnteredCallback callback) {
7509 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7510 isolate->RemoveBeforeCallEnteredCallback(callback);
7511}
7512
7513
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007514void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
7515 if (callback == NULL) return;
7516 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7517 isolate->AddCallCompletedCallback(callback);
7518}
7519
7520
7521void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
7522 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7523 isolate->RemoveCallCompletedCallback(callback);
7524}
7525
7526
Ben Murdoch097c5b22016-05-18 11:27:45 +01007527void Isolate::AddCallCompletedCallback(
7528 DeprecatedCallCompletedCallback callback) {
7529 AddCallCompletedCallback(reinterpret_cast<CallCompletedCallback>(callback));
7530}
7531
7532
7533void Isolate::RemoveCallCompletedCallback(
7534 DeprecatedCallCompletedCallback callback) {
7535 RemoveCallCompletedCallback(
7536 reinterpret_cast<CallCompletedCallback>(callback));
7537}
7538
7539
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007540void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
7541 if (callback == NULL) return;
7542 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7543 isolate->SetPromiseRejectCallback(callback);
7544}
7545
7546
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007547void Isolate::RunMicrotasks() {
Ben Murdochda12d292016-06-02 14:46:10 +01007548 DCHECK(MicrotasksPolicy::kScoped != GetMicrotasksPolicy());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007549 reinterpret_cast<i::Isolate*>(this)->RunMicrotasks();
7550}
7551
7552
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007553void Isolate::EnqueueMicrotask(Local<Function> microtask) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007554 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7555 isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
7556}
7557
7558
7559void Isolate::EnqueueMicrotask(MicrotaskCallback microtask, void* data) {
7560 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7561 i::HandleScope scope(isolate);
7562 i::Handle<i::CallHandlerInfo> callback_info =
7563 i::Handle<i::CallHandlerInfo>::cast(
7564 isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE));
7565 SET_FIELD_WRAPPED(callback_info, set_callback, microtask);
7566 SET_FIELD_WRAPPED(callback_info, set_data, data);
7567 isolate->EnqueueMicrotask(callback_info);
7568}
7569
7570
7571void Isolate::SetAutorunMicrotasks(bool autorun) {
Ben Murdochda12d292016-06-02 14:46:10 +01007572 SetMicrotasksPolicy(
7573 autorun ? MicrotasksPolicy::kAuto : MicrotasksPolicy::kExplicit);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007574}
7575
7576
7577bool Isolate::WillAutorunMicrotasks() const {
Ben Murdochda12d292016-06-02 14:46:10 +01007578 return GetMicrotasksPolicy() == MicrotasksPolicy::kAuto;
7579}
7580
7581
7582void Isolate::SetMicrotasksPolicy(MicrotasksPolicy policy) {
7583 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7584 isolate->handle_scope_implementer()->set_microtasks_policy(policy);
7585}
7586
7587
7588MicrotasksPolicy Isolate::GetMicrotasksPolicy() const {
7589 i::Isolate* isolate =
7590 reinterpret_cast<i::Isolate*>(const_cast<Isolate*>(this));
7591 return isolate->handle_scope_implementer()->microtasks_policy();
7592}
7593
7594
7595void Isolate::AddMicrotasksCompletedCallback(
7596 MicrotasksCompletedCallback callback) {
7597 DCHECK(callback);
7598 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7599 isolate->AddMicrotasksCompletedCallback(callback);
7600}
7601
7602
7603void Isolate::RemoveMicrotasksCompletedCallback(
7604 MicrotasksCompletedCallback callback) {
7605 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7606 isolate->RemoveMicrotasksCompletedCallback(callback);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007607}
7608
7609
7610void Isolate::SetUseCounterCallback(UseCounterCallback callback) {
7611 reinterpret_cast<i::Isolate*>(this)->SetUseCounterCallback(callback);
7612}
7613
7614
7615void Isolate::SetCounterFunction(CounterLookupCallback callback) {
7616 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7617 isolate->stats_table()->SetCounterFunction(callback);
7618 isolate->InitializeLoggingAndCounters();
7619 isolate->counters()->ResetCounters();
7620}
7621
7622
7623void Isolate::SetCreateHistogramFunction(CreateHistogramCallback callback) {
7624 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7625 isolate->stats_table()->SetCreateHistogramFunction(callback);
7626 isolate->InitializeLoggingAndCounters();
7627 isolate->counters()->ResetHistograms();
7628}
7629
7630
7631void Isolate::SetAddHistogramSampleFunction(
7632 AddHistogramSampleCallback callback) {
7633 reinterpret_cast<i::Isolate*>(this)
7634 ->stats_table()
7635 ->SetAddHistogramSampleFunction(callback);
7636}
7637
7638
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007639bool Isolate::IdleNotification(int idle_time_in_ms) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007640 // Returning true tells the caller that it need not
7641 // continue to call IdleNotification.
7642 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7643 if (!i::FLAG_use_idle_notification) return true;
7644 return isolate->heap()->IdleNotification(idle_time_in_ms);
7645}
7646
7647
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007648bool Isolate::IdleNotificationDeadline(double deadline_in_seconds) {
7649 // Returning true tells the caller that it need not
7650 // continue to call IdleNotification.
7651 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7652 if (!i::FLAG_use_idle_notification) return true;
7653 return isolate->heap()->IdleNotification(deadline_in_seconds);
7654}
7655
7656
7657void Isolate::LowMemoryNotification() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007658 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7659 {
7660 i::HistogramTimerScope idle_notification_scope(
7661 isolate->counters()->gc_low_memory_notification());
Ben Murdoch097c5b22016-05-18 11:27:45 +01007662 TRACE_EVENT0("v8", "V8.GCLowMemoryNotification");
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007663 isolate->heap()->CollectAllAvailableGarbage("low memory notification");
7664 }
7665}
7666
7667
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007668int Isolate::ContextDisposedNotification(bool dependant_context) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007669 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007670 return isolate->heap()->NotifyContextDisposed(dependant_context);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007671}
7672
7673
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007674void Isolate::IsolateInForegroundNotification() {
7675 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7676 return isolate->heap()->SetOptimizeForLatency();
7677}
7678
7679
7680void Isolate::IsolateInBackgroundNotification() {
7681 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7682 return isolate->heap()->SetOptimizeForMemoryUsage();
7683}
7684
Ben Murdochda12d292016-06-02 14:46:10 +01007685void Isolate::MemoryPressureNotification(MemoryPressureLevel level) {
7686 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7687 return isolate->heap()->MemoryPressureNotification(level,
7688 Locker::IsLocked(this));
7689}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007690
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007691void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
7692 JitCodeEventHandler event_handler) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007693 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7694 // Ensure that logging is initialized for our isolate.
7695 isolate->InitializeLoggingAndCounters();
7696 isolate->logger()->SetCodeEventHandler(options, event_handler);
7697}
7698
7699
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007700void Isolate::SetStackLimit(uintptr_t stack_limit) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007701 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7702 CHECK(stack_limit);
7703 isolate->stack_guard()->SetStackLimit(stack_limit);
Ben Murdoch257744e2011-11-30 15:57:28 +00007704}
7705
7706
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007707void Isolate::GetCodeRange(void** start, size_t* length_in_bytes) {
7708 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7709 if (isolate->code_range()->valid()) {
7710 *start = isolate->code_range()->start();
7711 *length_in_bytes = isolate->code_range()->size();
7712 } else {
7713 *start = NULL;
7714 *length_in_bytes = 0;
7715 }
7716}
7717
7718
7719void Isolate::SetFatalErrorHandler(FatalErrorCallback that) {
7720 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7721 isolate->set_exception_behavior(that);
7722}
7723
7724
7725void Isolate::SetAllowCodeGenerationFromStringsCallback(
7726 AllowCodeGenerationFromStringsCallback callback) {
7727 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7728 isolate->set_allow_code_gen_callback(callback);
7729}
7730
7731
7732bool Isolate::IsDead() {
7733 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7734 return isolate->IsDead();
7735}
7736
7737
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007738bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007739 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007740 ENTER_V8(isolate);
7741 i::HandleScope scope(isolate);
7742 NeanderArray listeners(isolate->factory()->message_listeners());
7743 NeanderObject obj(isolate, 2);
7744 obj.set(0, *isolate->factory()->NewForeign(FUNCTION_ADDR(that)));
7745 obj.set(1, data.IsEmpty() ? isolate->heap()->undefined_value()
7746 : *Utils::OpenHandle(*data));
7747 listeners.add(isolate, obj.value());
7748 return true;
7749}
7750
7751
7752void Isolate::RemoveMessageListeners(MessageCallback that) {
7753 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007754 ENTER_V8(isolate);
7755 i::HandleScope scope(isolate);
7756 NeanderArray listeners(isolate->factory()->message_listeners());
7757 for (int i = 0; i < listeners.length(); i++) {
7758 if (listeners.get(i)->IsUndefined()) continue; // skip deleted ones
7759
7760 NeanderObject listener(i::JSObject::cast(listeners.get(i)));
7761 i::Handle<i::Foreign> callback_obj(i::Foreign::cast(listener.get(0)));
7762 if (callback_obj->foreign_address() == FUNCTION_ADDR(that)) {
7763 listeners.set(i, isolate->heap()->undefined_value());
7764 }
7765 }
7766}
7767
7768
7769void Isolate::SetFailedAccessCheckCallbackFunction(
7770 FailedAccessCheckCallback callback) {
7771 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7772 isolate->SetFailedAccessCheckCallback(callback);
7773}
7774
7775
7776void Isolate::SetCaptureStackTraceForUncaughtExceptions(
7777 bool capture, int frame_limit, StackTrace::StackTraceOptions options) {
7778 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7779 isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit,
7780 options);
7781}
7782
7783
7784void Isolate::VisitExternalResources(ExternalResourceVisitor* visitor) {
7785 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7786 isolate->heap()->VisitExternalResources(visitor);
7787}
7788
7789
7790class VisitorAdapter : public i::ObjectVisitor {
7791 public:
7792 explicit VisitorAdapter(PersistentHandleVisitor* visitor)
7793 : visitor_(visitor) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007794 void VisitPointers(i::Object** start, i::Object** end) override {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007795 UNREACHABLE();
7796 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007797 void VisitEmbedderReference(i::Object** p, uint16_t class_id) override {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007798 Value* value = ToApi<Value>(i::Handle<i::Object>(p));
7799 visitor_->VisitPersistentHandle(
7800 reinterpret_cast<Persistent<Value>*>(&value), class_id);
7801 }
7802
7803 private:
7804 PersistentHandleVisitor* visitor_;
7805};
7806
7807
7808void Isolate::VisitHandlesWithClassIds(PersistentHandleVisitor* visitor) {
7809 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7810 i::DisallowHeapAllocation no_allocation;
7811 VisitorAdapter visitor_adapter(visitor);
7812 isolate->global_handles()->IterateAllRootsWithClassIds(&visitor_adapter);
7813}
7814
7815
7816void Isolate::VisitHandlesForPartialDependence(
7817 PersistentHandleVisitor* visitor) {
7818 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7819 i::DisallowHeapAllocation no_allocation;
7820 VisitorAdapter visitor_adapter(visitor);
7821 isolate->global_handles()->IterateAllRootsInNewSpaceWithClassIds(
7822 &visitor_adapter);
7823}
7824
7825
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007826void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
7827 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
7828 i::DisallowHeapAllocation no_allocation;
7829 VisitorAdapter visitor_adapter(visitor);
7830 isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds(
7831 &visitor_adapter);
7832}
7833
7834
Ben Murdochda12d292016-06-02 14:46:10 +01007835MicrotasksScope::MicrotasksScope(Isolate* isolate, MicrotasksScope::Type type)
7836 : isolate_(reinterpret_cast<i::Isolate*>(isolate)),
7837 run_(type == MicrotasksScope::kRunMicrotasks) {
7838 auto handle_scope_implementer = isolate_->handle_scope_implementer();
7839 if (run_) handle_scope_implementer->IncrementMicrotasksScopeDepth();
7840#ifdef DEBUG
7841 if (!run_) handle_scope_implementer->IncrementDebugMicrotasksScopeDepth();
7842#endif
7843}
7844
7845
7846MicrotasksScope::~MicrotasksScope() {
7847 auto handle_scope_implementer = isolate_->handle_scope_implementer();
7848 if (run_) {
7849 handle_scope_implementer->DecrementMicrotasksScopeDepth();
7850 if (MicrotasksPolicy::kScoped ==
7851 handle_scope_implementer->microtasks_policy()) {
7852 PerformCheckpoint(reinterpret_cast<Isolate*>(isolate_));
7853 }
7854 }
7855#ifdef DEBUG
7856 if (!run_) handle_scope_implementer->DecrementDebugMicrotasksScopeDepth();
7857#endif
7858}
7859
7860
7861void MicrotasksScope::PerformCheckpoint(Isolate* v8Isolate) {
7862 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
7863 if (IsExecutionTerminatingCheck(isolate)) return;
7864 auto handle_scope_implementer = isolate->handle_scope_implementer();
7865 if (!handle_scope_implementer->GetMicrotasksScopeDepth() &&
7866 !handle_scope_implementer->HasMicrotasksSuppressions()) {
7867 isolate->RunMicrotasks();
7868 }
7869}
7870
7871
7872int MicrotasksScope::GetCurrentDepth(Isolate* v8Isolate) {
7873 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8Isolate);
7874 return isolate->handle_scope_implementer()->GetMicrotasksScopeDepth();
7875}
7876
7877
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007878String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
Ben Murdoch257744e2011-11-30 15:57:28 +00007879 : str_(NULL), length_(0) {
Ben Murdoch257744e2011-11-30 15:57:28 +00007880 if (obj.IsEmpty()) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007881 i::Isolate* isolate = i::Isolate::Current();
7882 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01007883 ENTER_V8(isolate);
7884 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007885 Local<Context> context = v8_isolate->GetCurrentContext();
7886 TryCatch try_catch(v8_isolate);
7887 Local<String> str;
7888 if (!obj->ToString(context).ToLocal(&str)) return;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01007889 i::Handle<i::String> i_str = Utils::OpenHandle(*str);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007890 length_ = v8::Utf8Length(*i_str, isolate);
Ben Murdoch257744e2011-11-30 15:57:28 +00007891 str_ = i::NewArray<char>(length_ + 1);
7892 str->WriteUtf8(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00007893}
7894
7895
7896String::Utf8Value::~Utf8Value() {
7897 i::DeleteArray(str_);
7898}
7899
7900
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007901String::Value::Value(v8::Local<v8::Value> obj) : str_(NULL), length_(0) {
Ben Murdoch257744e2011-11-30 15:57:28 +00007902 if (obj.IsEmpty()) return;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007903 i::Isolate* isolate = i::Isolate::Current();
7904 Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
Steve Block44f0eee2011-05-26 01:26:41 +01007905 ENTER_V8(isolate);
7906 i::HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007907 Local<Context> context = v8_isolate->GetCurrentContext();
7908 TryCatch try_catch(v8_isolate);
7909 Local<String> str;
7910 if (!obj->ToString(context).ToLocal(&str)) return;
Ben Murdoch257744e2011-11-30 15:57:28 +00007911 length_ = str->Length();
7912 str_ = i::NewArray<uint16_t>(length_ + 1);
7913 str->Write(str_);
Steve Blocka7e24c12009-10-30 11:49:00 +00007914}
7915
7916
7917String::Value::~Value() {
7918 i::DeleteArray(str_);
7919}
7920
Steve Blocka7e24c12009-10-30 11:49:00 +00007921
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007922#define DEFINE_ERROR(NAME, name) \
7923 Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \
7924 i::Isolate* isolate = i::Isolate::Current(); \
7925 LOG_API(isolate, #NAME); \
7926 ENTER_V8(isolate); \
7927 i::Object* error; \
7928 { \
7929 i::HandleScope scope(isolate); \
7930 i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
7931 i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
7932 error = *isolate->factory()->NewError(constructor, message); \
7933 } \
7934 i::Handle<i::Object> result(error, isolate); \
7935 return Utils::ToLocal(result); \
Steve Blocka7e24c12009-10-30 11:49:00 +00007936 }
Steve Blocka7e24c12009-10-30 11:49:00 +00007937
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007938DEFINE_ERROR(RangeError, range_error)
7939DEFINE_ERROR(ReferenceError, reference_error)
7940DEFINE_ERROR(SyntaxError, syntax_error)
7941DEFINE_ERROR(TypeError, type_error)
7942DEFINE_ERROR(Error, error)
Steve Blocka7e24c12009-10-30 11:49:00 +00007943
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007944#undef DEFINE_ERROR
Steve Blocka7e24c12009-10-30 11:49:00 +00007945
7946
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007947Local<Message> Exception::CreateMessage(Isolate* isolate,
7948 Local<Value> exception) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007949 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007950 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7951 ENTER_V8(i_isolate);
7952 i::HandleScope scope(i_isolate);
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007953 return Utils::MessageToLocal(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007954 scope.CloseAndEscape(i_isolate->CreateMessage(obj, NULL)));
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007955}
7956
7957
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007958Local<Message> Exception::CreateMessage(Local<Value> exception) {
7959 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
7960 if (!obj->IsHeapObject()) return Local<Message>();
7961 i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
7962 return CreateMessage(reinterpret_cast<Isolate*>(isolate), exception);
7963}
7964
7965
7966Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007967 i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
7968 if (!obj->IsJSObject()) return Local<StackTrace>();
7969 i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
7970 i::Isolate* isolate = js_obj->GetIsolate();
7971 ENTER_V8(isolate);
7972 return Utils::StackTraceToLocal(isolate->GetDetailedStackTrace(js_obj));
7973}
7974
7975
Steve Blocka7e24c12009-10-30 11:49:00 +00007976// --- D e b u g S u p p o r t ---
7977
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007978bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that,
7979 Local<Value> data) {
7980 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
7981 ENTER_V8(i_isolate);
7982 i::HandleScope scope(i_isolate);
7983 i::Handle<i::Object> foreign = i_isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00007984 if (that != NULL) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007985 foreign = i_isolate->factory()->NewForeign(FUNCTION_ADDR(that));
Steve Blocka7e24c12009-10-30 11:49:00 +00007986 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007987 i_isolate->debug()->SetEventListener(foreign, Utils::OpenHandle(*data, true));
Steve Blocka7e24c12009-10-30 11:49:00 +00007988 return true;
7989}
7990
7991
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007992bool Debug::SetDebugEventListener(EventCallback that, Local<Value> data) {
7993 return SetDebugEventListener(
7994 reinterpret_cast<Isolate*>(i::Isolate::Current()), that, data);
7995}
7996
7997
Steve Block44f0eee2011-05-26 01:26:41 +01007998void Debug::DebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007999 reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
Steve Blocka7e24c12009-10-30 11:49:00 +00008000}
8001
8002
Steve Block44f0eee2011-05-26 01:26:41 +01008003void Debug::CancelDebugBreak(Isolate* isolate) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008004 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8005 internal_isolate->stack_guard()->ClearDebugBreak();
Ben Murdochf87a2032010-10-22 12:50:53 +01008006}
8007
8008
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008009bool Debug::CheckDebugBreak(Isolate* isolate) {
8010 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8011 return internal_isolate->stack_guard()->CheckDebugBreak();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01008012}
8013
8014
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008015void Debug::SetMessageHandler(Isolate* isolate,
8016 v8::Debug::MessageHandler handler) {
8017 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8018 ENTER_V8(i_isolate);
8019 i_isolate->debug()->SetMessageHandler(handler);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008020}
8021
8022
8023void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008024 SetMessageHandler(reinterpret_cast<Isolate*>(i::Isolate::Current()), handler);
Steve Blocka7e24c12009-10-30 11:49:00 +00008025}
8026
8027
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008028void Debug::SendCommand(Isolate* isolate,
8029 const uint16_t* command,
8030 int length,
8031 ClientData* client_data) {
8032 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8033 internal_isolate->debug()->EnqueueCommandMessage(
8034 i::Vector<const uint16_t>(command, length), client_data);
Steve Blockd0582a62009-12-15 09:54:21 +00008035}
8036
8037
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008038MaybeLocal<Value> Debug::Call(Local<Context> context,
8039 v8::Local<v8::Function> fun,
8040 v8::Local<v8::Value> data) {
8041 PREPARE_FOR_EXECUTION(context, "v8::Debug::Call()", Value);
8042 i::Handle<i::Object> data_obj;
Steve Blocka7e24c12009-10-30 11:49:00 +00008043 if (data.IsEmpty()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008044 data_obj = isolate->factory()->undefined_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00008045 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008046 data_obj = Utils::OpenHandle(*data);
Steve Blocka7e24c12009-10-30 11:49:00 +00008047 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008048 Local<Value> result;
8049 has_pending_exception =
8050 !ToLocal<Value>(isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj),
8051 &result);
8052 RETURN_ON_FAILED_EXECUTION(Value);
8053 RETURN_ESCAPED(result);
Steve Blocka7e24c12009-10-30 11:49:00 +00008054}
8055
8056
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008057Local<Value> Debug::Call(v8::Local<v8::Function> fun,
8058 v8::Local<v8::Value> data) {
8059 auto context = ContextFromHeapObject(Utils::OpenHandle(*fun));
8060 RETURN_TO_LOCAL_UNCHECKED(Call(context, fun, data), Value);
8061}
8062
8063
8064MaybeLocal<Value> Debug::GetMirror(Local<Context> context,
8065 v8::Local<v8::Value> obj) {
8066 PREPARE_FOR_EXECUTION(context, "v8::Debug::GetMirror()", Value);
Steve Block44f0eee2011-05-26 01:26:41 +01008067 i::Debug* isolate_debug = isolate->debug();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008068 has_pending_exception = !isolate_debug->Load();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008069 RETURN_ON_FAILED_EXECUTION(Value);
8070 i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
8071 auto name = isolate->factory()->NewStringFromStaticChars("MakeMirror");
Ben Murdochda12d292016-06-02 14:46:10 +01008072 auto fun_obj = i::JSReceiver::GetProperty(debug, name).ToHandleChecked();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008073 auto v8_fun = Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(fun_obj));
8074 const int kArgc = 1;
8075 v8::Local<v8::Value> argv[kArgc] = {obj};
8076 Local<Value> result;
8077 has_pending_exception =
8078 !v8_fun->Call(context, Utils::ToLocal(debug), kArgc, argv)
8079 .ToLocal(&result);
8080 RETURN_ON_FAILED_EXECUTION(Value);
8081 RETURN_ESCAPED(result);
8082}
8083
8084
8085Local<Value> Debug::GetMirror(v8::Local<v8::Value> obj) {
8086 RETURN_TO_LOCAL_UNCHECKED(GetMirror(Local<Context>(), obj), Value);
8087}
8088
8089
8090void Debug::ProcessDebugMessages(Isolate* isolate) {
8091 reinterpret_cast<i::Isolate*>(isolate)->debug()->ProcessDebugMessages(true);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008092}
8093
8094
Leon Clarkee46be812010-01-19 14:06:41 +00008095void Debug::ProcessDebugMessages() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008096 ProcessDebugMessages(reinterpret_cast<Isolate*>(i::Isolate::Current()));
8097}
8098
8099
8100Local<Context> Debug::GetDebugContext(Isolate* isolate) {
8101 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8102 ENTER_V8(i_isolate);
8103 return Utils::ToLocal(i_isolate->debug()->GetDebugContext());
Leon Clarkee46be812010-01-19 14:06:41 +00008104}
8105
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008106
Steve Block6ded16b2010-05-10 14:33:55 +01008107Local<Context> Debug::GetDebugContext() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008108 return GetDebugContext(reinterpret_cast<Isolate*>(i::Isolate::Current()));
Steve Block6ded16b2010-05-10 14:33:55 +01008109}
8110
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008111
8112void Debug::SetLiveEditEnabled(Isolate* isolate, bool enable) {
8113 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8114 internal_isolate->debug()->set_live_edit_enabled(enable);
8115}
Steve Blocka7e24c12009-10-30 11:49:00 +00008116
Ben Murdochda12d292016-06-02 14:46:10 +01008117bool Debug::IsTailCallEliminationEnabled(Isolate* isolate) {
8118 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8119 return internal_isolate->is_tail_call_elimination_enabled();
8120}
8121
8122void Debug::SetTailCallEliminationEnabled(Isolate* isolate, bool enabled) {
8123 i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
8124 internal_isolate->SetTailCallEliminationEnabled(enabled);
8125}
Steve Block6ded16b2010-05-10 14:33:55 +01008126
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008127MaybeLocal<Array> Debug::GetInternalProperties(Isolate* v8_isolate,
8128 Local<Value> value) {
8129 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
8130 ENTER_V8(isolate);
8131 i::Handle<i::Object> val = Utils::OpenHandle(*value);
8132 i::Handle<i::JSArray> result;
8133 if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result))
8134 return MaybeLocal<Array>();
8135 return Utils::ToLocal(result);
8136}
8137
8138
8139Local<String> CpuProfileNode::GetFunctionName() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008140 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008141 i::Isolate* isolate = node->isolate();
Steve Block6ded16b2010-05-10 14:33:55 +01008142 const i::CodeEntry* entry = node->entry();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008143 i::Handle<i::String> name =
8144 isolate->factory()->InternalizeUtf8String(entry->name());
Steve Block6ded16b2010-05-10 14:33:55 +01008145 if (!entry->has_name_prefix()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008146 return ToApiHandle<String>(name);
Steve Block6ded16b2010-05-10 14:33:55 +01008147 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008148 // We do not expect this to fail. Change this if it does.
8149 i::Handle<i::String> cons = isolate->factory()->NewConsString(
8150 isolate->factory()->InternalizeUtf8String(entry->name_prefix()),
8151 name).ToHandleChecked();
8152 return ToApiHandle<String>(cons);
Steve Block6ded16b2010-05-10 14:33:55 +01008153 }
8154}
8155
8156
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008157int CpuProfileNode::GetScriptId() const {
8158 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
8159 const i::CodeEntry* entry = node->entry();
8160 return entry->script_id();
8161}
8162
8163
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008164Local<String> CpuProfileNode::GetScriptResourceName() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008165 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008166 i::Isolate* isolate = node->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008167 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
8168 node->entry()->resource_name()));
Steve Block6ded16b2010-05-10 14:33:55 +01008169}
8170
8171
8172int CpuProfileNode::GetLineNumber() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008173 return reinterpret_cast<const i::ProfileNode*>(this)->entry()->line_number();
8174}
8175
8176
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008177int CpuProfileNode::GetColumnNumber() const {
8178 return reinterpret_cast<const i::ProfileNode*>(this)->
8179 entry()->column_number();
Steve Block6ded16b2010-05-10 14:33:55 +01008180}
8181
8182
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008183unsigned int CpuProfileNode::GetHitLineCount() const {
8184 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
8185 return node->GetHitLineCount();
8186}
8187
8188
8189bool CpuProfileNode::GetLineTicks(LineTick* entries,
8190 unsigned int length) const {
8191 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
8192 return node->GetLineTicks(entries, length);
8193}
8194
8195
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008196const char* CpuProfileNode::GetBailoutReason() const {
8197 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
8198 return node->entry()->bailout_reason();
Steve Block6ded16b2010-05-10 14:33:55 +01008199}
8200
8201
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008202unsigned CpuProfileNode::GetHitCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008203 return reinterpret_cast<const i::ProfileNode*>(this)->self_ticks();
8204}
8205
8206
8207unsigned CpuProfileNode::GetCallUid() const {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008208 return reinterpret_cast<const i::ProfileNode*>(this)->function_id();
Steve Block6ded16b2010-05-10 14:33:55 +01008209}
8210
8211
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008212unsigned CpuProfileNode::GetNodeId() const {
8213 return reinterpret_cast<const i::ProfileNode*>(this)->id();
8214}
8215
8216
Steve Block6ded16b2010-05-10 14:33:55 +01008217int CpuProfileNode::GetChildrenCount() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008218 return reinterpret_cast<const i::ProfileNode*>(this)->children()->length();
8219}
8220
8221
8222const CpuProfileNode* CpuProfileNode::GetChild(int index) const {
Steve Block6ded16b2010-05-10 14:33:55 +01008223 const i::ProfileNode* child =
8224 reinterpret_cast<const i::ProfileNode*>(this)->children()->at(index);
8225 return reinterpret_cast<const CpuProfileNode*>(child);
8226}
8227
8228
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008229const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
8230 const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
8231 return node->deopt_infos();
Steve Block6ded16b2010-05-10 14:33:55 +01008232}
8233
8234
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008235void CpuProfile::Delete() {
8236 i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
8237 i::Isolate* isolate = profile->top_down()->isolate();
8238 i::CpuProfiler* profiler = isolate->cpu_profiler();
8239 DCHECK(profiler != NULL);
8240 profiler->DeleteProfile(profile);
8241}
8242
8243
8244Local<String> CpuProfile::GetTitle() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008245 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008246 i::Isolate* isolate = profile->top_down()->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008247 return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
8248 profile->title()));
Steve Block6ded16b2010-05-10 14:33:55 +01008249}
8250
8251
8252const CpuProfileNode* CpuProfile::GetTopDownRoot() const {
Steve Block6ded16b2010-05-10 14:33:55 +01008253 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8254 return reinterpret_cast<const CpuProfileNode*>(profile->top_down()->root());
8255}
8256
8257
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008258const CpuProfileNode* CpuProfile::GetSample(int index) const {
8259 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8260 return reinterpret_cast<const CpuProfileNode*>(profile->sample(index));
Steve Block6ded16b2010-05-10 14:33:55 +01008261}
8262
8263
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008264int64_t CpuProfile::GetSampleTimestamp(int index) const {
8265 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8266 return (profile->sample_timestamp(index) - base::TimeTicks())
8267 .InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01008268}
8269
8270
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008271int64_t CpuProfile::GetStartTime() const {
8272 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8273 return (profile->start_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01008274}
8275
8276
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008277int64_t CpuProfile::GetEndTime() const {
8278 const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
8279 return (profile->end_time() - base::TimeTicks()).InMicroseconds();
Steve Block6ded16b2010-05-10 14:33:55 +01008280}
8281
8282
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008283int CpuProfile::GetSamplesCount() const {
8284 return reinterpret_cast<const i::CpuProfile*>(this)->samples_count();
8285}
8286
8287
8288void CpuProfiler::SetSamplingInterval(int us) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008289 DCHECK_GE(us, 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008290 return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
8291 base::TimeDelta::FromMicroseconds(us));
8292}
8293
Ben Murdoch097c5b22016-05-18 11:27:45 +01008294void CpuProfiler::CollectSample() {
8295 reinterpret_cast<i::CpuProfiler*>(this)->CollectSample();
8296}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008298void CpuProfiler::StartProfiling(Local<String> title, bool record_samples) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008299 reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
8300 *Utils::OpenHandle(*title), record_samples);
8301}
8302
8303
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008304CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008305 return reinterpret_cast<CpuProfile*>(
8306 reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
Leon Clarkef7060e22010-06-03 12:02:55 +01008307 *Utils::OpenHandle(*title)));
Steve Block6ded16b2010-05-10 14:33:55 +01008308}
8309
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008310
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008311void CpuProfiler::SetIdle(bool is_idle) {
8312 i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008313 v8::StateTag state = isolate->current_vm_state();
8314 DCHECK(state == v8::EXTERNAL || state == v8::IDLE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008315 if (isolate->js_entry_sp() != NULL) return;
8316 if (is_idle) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -04008317 isolate->set_current_vm_state(v8::IDLE);
8318 } else if (state == v8::IDLE) {
8319 isolate->set_current_vm_state(v8::EXTERNAL);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008320 }
Steve Block44f0eee2011-05-26 01:26:41 +01008321}
8322
8323
Iain Merrick75681382010-08-19 15:07:18 +01008324static i::HeapGraphEdge* ToInternal(const HeapGraphEdge* edge) {
8325 return const_cast<i::HeapGraphEdge*>(
8326 reinterpret_cast<const i::HeapGraphEdge*>(edge));
8327}
8328
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008329
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008330HeapGraphEdge::Type HeapGraphEdge::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01008331 return static_cast<HeapGraphEdge::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008332}
8333
8334
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008335Local<Value> HeapGraphEdge::GetName() const {
Iain Merrick75681382010-08-19 15:07:18 +01008336 i::HeapGraphEdge* edge = ToInternal(this);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008337 i::Isolate* isolate = edge->isolate();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008338 switch (edge->type()) {
Iain Merrick75681382010-08-19 15:07:18 +01008339 case i::HeapGraphEdge::kContextVariable:
8340 case i::HeapGraphEdge::kInternal:
8341 case i::HeapGraphEdge::kProperty:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08008342 case i::HeapGraphEdge::kShortcut:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008343 case i::HeapGraphEdge::kWeak:
8344 return ToApiHandle<String>(
8345 isolate->factory()->InternalizeUtf8String(edge->name()));
Iain Merrick75681382010-08-19 15:07:18 +01008346 case i::HeapGraphEdge::kElement:
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08008347 case i::HeapGraphEdge::kHidden:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008348 return ToApiHandle<Number>(
8349 isolate->factory()->NewNumberFromInt(edge->index()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008350 default: UNREACHABLE();
8351 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008352 return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008353}
8354
8355
8356const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008357 const i::HeapEntry* from = ToInternal(this)->from();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008358 return reinterpret_cast<const HeapGraphNode*>(from);
8359}
8360
8361
8362const HeapGraphNode* HeapGraphEdge::GetToNode() const {
Iain Merrick75681382010-08-19 15:07:18 +01008363 const i::HeapEntry* to = ToInternal(this)->to();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008364 return reinterpret_cast<const HeapGraphNode*>(to);
8365}
8366
8367
Iain Merrick75681382010-08-19 15:07:18 +01008368static i::HeapEntry* ToInternal(const HeapGraphNode* entry) {
8369 return const_cast<i::HeapEntry*>(
8370 reinterpret_cast<const i::HeapEntry*>(entry));
8371}
8372
8373
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008374HeapGraphNode::Type HeapGraphNode::GetType() const {
Iain Merrick75681382010-08-19 15:07:18 +01008375 return static_cast<HeapGraphNode::Type>(ToInternal(this)->type());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008376}
8377
8378
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008379Local<String> HeapGraphNode::GetName() const {
8380 i::Isolate* isolate = ToInternal(this)->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008381 return ToApiHandle<String>(
8382 isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008383}
8384
8385
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008386SnapshotObjectId HeapGraphNode::GetId() const {
Iain Merrick75681382010-08-19 15:07:18 +01008387 return ToInternal(this)->id();
Ben Murdoch3bec4d22010-07-22 14:51:16 +01008388}
8389
8390
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008391size_t HeapGraphNode::GetShallowSize() const {
Iain Merrick75681382010-08-19 15:07:18 +01008392 return ToInternal(this)->self_size();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008393}
8394
8395
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008396int HeapGraphNode::GetChildrenCount() const {
Iain Merrick75681382010-08-19 15:07:18 +01008397 return ToInternal(this)->children().length();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008398}
8399
8400
8401const HeapGraphEdge* HeapGraphNode::GetChild(int index) const {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008402 return reinterpret_cast<const HeapGraphEdge*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008403 ToInternal(this)->children()[index]);
Ben Murdoch69a99ed2011-11-30 16:03:39 +00008404}
8405
8406
Iain Merrick75681382010-08-19 15:07:18 +01008407static i::HeapSnapshot* ToInternal(const HeapSnapshot* snapshot) {
8408 return const_cast<i::HeapSnapshot*>(
8409 reinterpret_cast<const i::HeapSnapshot*>(snapshot));
8410}
8411
8412
Steve Block44f0eee2011-05-26 01:26:41 +01008413void HeapSnapshot::Delete() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008414 i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008415 if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
Steve Block44f0eee2011-05-26 01:26:41 +01008416 ToInternal(this)->Delete();
8417 } else {
8418 // If this is the last snapshot, clean up all accessory data as well.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008419 isolate->heap_profiler()->DeleteAllSnapshots();
Steve Block44f0eee2011-05-26 01:26:41 +01008420 }
8421}
8422
8423
Ben Murdoch3bec4d22010-07-22 14:51:16 +01008424const HeapGraphNode* HeapSnapshot::GetRoot() const {
Iain Merrick75681382010-08-19 15:07:18 +01008425 return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008426}
8427
8428
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008429const HeapGraphNode* HeapSnapshot::GetNodeById(SnapshotObjectId id) const {
Ben Murdochb0fe1622011-05-05 13:52:32 +01008430 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008431 ToInternal(this)->GetEntryById(id));
Ben Murdochb0fe1622011-05-05 13:52:32 +01008432}
8433
8434
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008435int HeapSnapshot::GetNodesCount() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008436 return ToInternal(this)->entries().length();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008437}
8438
8439
8440const HeapGraphNode* HeapSnapshot::GetNode(int index) const {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008441 return reinterpret_cast<const HeapGraphNode*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008442 &ToInternal(this)->entries().at(index));
8443}
8444
8445
8446SnapshotObjectId HeapSnapshot::GetMaxSnapshotJSObjectId() const {
8447 return ToInternal(this)->max_snapshot_js_object_id();
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00008448}
8449
8450
Kristian Monsen0d5e1162010-09-30 15:31:59 +01008451void HeapSnapshot::Serialize(OutputStream* stream,
8452 HeapSnapshot::SerializationFormat format) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008453 Utils::ApiCheck(format == kJSON,
8454 "v8::HeapSnapshot::Serialize",
8455 "Unknown serialization format");
8456 Utils::ApiCheck(stream->GetChunkSize() > 0,
8457 "v8::HeapSnapshot::Serialize",
8458 "Invalid stream chunk size");
Kristian Monsen0d5e1162010-09-30 15:31:59 +01008459 i::HeapSnapshotJSONSerializer serializer(ToInternal(this));
8460 serializer.Serialize(stream);
8461}
8462
8463
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008464// static
8465STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
8466 HeapProfiler::kUnknownObjectId;
8467
8468
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008469int HeapProfiler::GetSnapshotCount() {
8470 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008471}
8472
8473
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008474const HeapSnapshot* HeapProfiler::GetHeapSnapshot(int index) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008475 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008476 reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshot(index));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008477}
8478
8479
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008480SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008481 i::Handle<i::Object> obj = Utils::OpenHandle(*value);
8482 return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
8483}
8484
8485
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008486Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008487 i::Handle<i::Object> obj =
8488 reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
8489 if (obj.is_null()) return Local<Value>();
8490 return Utils::ToLocal(obj);
8491}
8492
8493
8494void HeapProfiler::ClearObjectIds() {
8495 reinterpret_cast<i::HeapProfiler*>(this)->ClearHeapObjectMap();
8496}
8497
8498
8499const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008500 ActivityControl* control, ObjectNameResolver* resolver) {
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008501 return reinterpret_cast<const HeapSnapshot*>(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008502 reinterpret_cast<i::HeapProfiler*>(this)
8503 ->TakeSnapshot(control, resolver));
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008504}
8505
8506
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008507void HeapProfiler::StartTrackingHeapObjects(bool track_allocations) {
8508 reinterpret_cast<i::HeapProfiler*>(this)->StartHeapObjectsTracking(
8509 track_allocations);
Kristian Monsen9dcf7e22010-06-28 14:14:28 +01008510}
8511
Steve Block44f0eee2011-05-26 01:26:41 +01008512
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008513void HeapProfiler::StopTrackingHeapObjects() {
8514 reinterpret_cast<i::HeapProfiler*>(this)->StopHeapObjectsTracking();
Steve Block44f0eee2011-05-26 01:26:41 +01008515}
8516
8517
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008518SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
8519 int64_t* timestamp_us) {
8520 i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
8521 return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
Steve Block44f0eee2011-05-26 01:26:41 +01008522}
8523
Steve Block6ded16b2010-05-10 14:33:55 +01008524
Ben Murdoch097c5b22016-05-18 11:27:45 +01008525bool HeapProfiler::StartSamplingHeapProfiler(uint64_t sample_interval,
8526 int stack_depth) {
8527 return reinterpret_cast<i::HeapProfiler*>(this)
8528 ->StartSamplingHeapProfiler(sample_interval, stack_depth);
8529}
8530
8531
8532void HeapProfiler::StopSamplingHeapProfiler() {
8533 reinterpret_cast<i::HeapProfiler*>(this)->StopSamplingHeapProfiler();
8534}
8535
8536
8537AllocationProfile* HeapProfiler::GetAllocationProfile() {
8538 return reinterpret_cast<i::HeapProfiler*>(this)->GetAllocationProfile();
8539}
8540
8541
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008542void HeapProfiler::DeleteAllHeapSnapshots() {
8543 reinterpret_cast<i::HeapProfiler*>(this)->DeleteAllSnapshots();
8544}
8545
8546
8547void HeapProfiler::SetWrapperClassInfoProvider(uint16_t class_id,
8548 WrapperInfoCallback callback) {
8549 reinterpret_cast<i::HeapProfiler*>(this)->DefineWrapperClass(class_id,
8550 callback);
8551}
8552
8553
8554size_t HeapProfiler::GetProfilerMemorySize() {
8555 return reinterpret_cast<i::HeapProfiler*>(this)->
8556 GetMemorySizeUsedByProfiler();
8557}
8558
8559
8560void HeapProfiler::SetRetainedObjectInfo(UniqueId id,
8561 RetainedObjectInfo* info) {
8562 reinterpret_cast<i::HeapProfiler*>(this)->SetRetainedObjectInfo(id, info);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008563}
8564
Steve Block6ded16b2010-05-10 14:33:55 +01008565
Ben Murdochb0fe1622011-05-05 13:52:32 +01008566v8::Testing::StressType internal::Testing::stress_type_ =
8567 v8::Testing::kStressTypeOpt;
8568
8569
8570void Testing::SetStressRunType(Testing::StressType type) {
8571 internal::Testing::set_stress_type(type);
8572}
8573
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008574
Ben Murdochb0fe1622011-05-05 13:52:32 +01008575int Testing::GetStressRuns() {
8576 if (internal::FLAG_stress_runs != 0) return internal::FLAG_stress_runs;
8577#ifdef DEBUG
8578 // In debug mode the code runs much slower so stressing will only make two
8579 // runs.
8580 return 2;
8581#else
8582 return 5;
8583#endif
8584}
8585
8586
8587static void SetFlagsFromString(const char* flags) {
8588 V8::SetFlagsFromString(flags, i::StrLength(flags));
8589}
8590
8591
8592void Testing::PrepareStressRun(int run) {
8593 static const char* kLazyOptimizations =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008594 "--prepare-always-opt "
8595 "--max-inlined-source-size=999999 "
8596 "--max-inlined-nodes=999999 "
8597 "--max-inlined-nodes-cumulative=999999 "
8598 "--noalways-opt";
Ben Murdochb0fe1622011-05-05 13:52:32 +01008599 static const char* kForcedOptimizations = "--always-opt";
8600
8601 // If deoptimization stressed turn on frequent deoptimization. If no value
8602 // is spefified through --deopt-every-n-times use a default default value.
8603 static const char* kDeoptEvery13Times = "--deopt-every-n-times=13";
8604 if (internal::Testing::stress_type() == Testing::kStressTypeDeopt &&
8605 internal::FLAG_deopt_every_n_times == 0) {
8606 SetFlagsFromString(kDeoptEvery13Times);
8607 }
8608
8609#ifdef DEBUG
8610 // As stressing in debug mode only make two runs skip the deopt stressing
8611 // here.
8612 if (run == GetStressRuns() - 1) {
8613 SetFlagsFromString(kForcedOptimizations);
8614 } else {
Ben Murdochb0fe1622011-05-05 13:52:32 +01008615 SetFlagsFromString(kLazyOptimizations);
8616 }
8617#else
8618 if (run == GetStressRuns() - 1) {
8619 SetFlagsFromString(kForcedOptimizations);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01008620 } else if (run != GetStressRuns() - 2) {
Ben Murdochb0fe1622011-05-05 13:52:32 +01008621 SetFlagsFromString(kLazyOptimizations);
8622 }
8623#endif
8624}
8625
8626
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008627void Testing::DeoptimizeAll(Isolate* isolate) {
8628 i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
8629 i::HandleScope scope(i_isolate);
8630 internal::Deoptimizer::DeoptimizeAll(i_isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00008631}
8632
8633
Steve Block44f0eee2011-05-26 01:26:41 +01008634namespace internal {
8635
8636
Steve Blocka7e24c12009-10-30 11:49:00 +00008637void HandleScopeImplementer::FreeThreadResources() {
Steve Block44f0eee2011-05-26 01:26:41 +01008638 Free();
Steve Blocka7e24c12009-10-30 11:49:00 +00008639}
8640
8641
8642char* HandleScopeImplementer::ArchiveThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008643 HandleScopeData* current = isolate_->handle_scope_data();
Steve Blocka7e24c12009-10-30 11:49:00 +00008644 handle_scope_data_ = *current;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008645 MemCopy(storage, this, sizeof(*this));
Steve Blocka7e24c12009-10-30 11:49:00 +00008646
8647 ResetAfterArchive();
8648 current->Initialize();
8649
8650 return storage + ArchiveSpacePerThread();
8651}
8652
8653
8654int HandleScopeImplementer::ArchiveSpacePerThread() {
Steve Block44f0eee2011-05-26 01:26:41 +01008655 return sizeof(HandleScopeImplementer);
Steve Blocka7e24c12009-10-30 11:49:00 +00008656}
8657
8658
8659char* HandleScopeImplementer::RestoreThread(char* storage) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008660 MemCopy(this, storage, sizeof(*this));
Ben Murdoch257744e2011-11-30 15:57:28 +00008661 *isolate_->handle_scope_data() = handle_scope_data_;
Steve Blocka7e24c12009-10-30 11:49:00 +00008662 return storage + ArchiveSpacePerThread();
8663}
8664
8665
8666void HandleScopeImplementer::IterateThis(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008667#ifdef DEBUG
8668 bool found_block_before_deferred = false;
8669#endif
Steve Blocka7e24c12009-10-30 11:49:00 +00008670 // Iterate over all handles in the blocks except for the last.
8671 for (int i = blocks()->length() - 2; i >= 0; --i) {
8672 Object** block = blocks()->at(i);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008673 if (last_handle_before_deferred_block_ != NULL &&
8674 (last_handle_before_deferred_block_ <= &block[kHandleBlockSize]) &&
8675 (last_handle_before_deferred_block_ >= block)) {
8676 v->VisitPointers(block, last_handle_before_deferred_block_);
8677 DCHECK(!found_block_before_deferred);
8678#ifdef DEBUG
8679 found_block_before_deferred = true;
8680#endif
8681 } else {
8682 v->VisitPointers(block, &block[kHandleBlockSize]);
8683 }
Steve Blocka7e24c12009-10-30 11:49:00 +00008684 }
8685
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008686 DCHECK(last_handle_before_deferred_block_ == NULL ||
8687 found_block_before_deferred);
8688
Steve Blocka7e24c12009-10-30 11:49:00 +00008689 // Iterate over live handles in the last block (if any).
8690 if (!blocks()->is_empty()) {
8691 v->VisitPointers(blocks()->last(), handle_scope_data_.next);
8692 }
8693
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008694 List<Context*>* context_lists[2] = { &saved_contexts_, &entered_contexts_};
8695 for (unsigned i = 0; i < arraysize(context_lists); i++) {
8696 if (context_lists[i]->is_empty()) continue;
8697 Object** start = reinterpret_cast<Object**>(&context_lists[i]->first());
8698 v->VisitPointers(start, start + context_lists[i]->length());
Steve Blocka7e24c12009-10-30 11:49:00 +00008699 }
8700}
8701
8702
8703void HandleScopeImplementer::Iterate(ObjectVisitor* v) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008704 HandleScopeData* current = isolate_->handle_scope_data();
Steve Block44f0eee2011-05-26 01:26:41 +01008705 handle_scope_data_ = *current;
8706 IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00008707}
8708
8709
8710char* HandleScopeImplementer::Iterate(ObjectVisitor* v, char* storage) {
Steve Block44f0eee2011-05-26 01:26:41 +01008711 HandleScopeImplementer* scope_implementer =
Steve Blocka7e24c12009-10-30 11:49:00 +00008712 reinterpret_cast<HandleScopeImplementer*>(storage);
Steve Block44f0eee2011-05-26 01:26:41 +01008713 scope_implementer->IterateThis(v);
Steve Blocka7e24c12009-10-30 11:49:00 +00008714 return storage + ArchiveSpacePerThread();
8715}
8716
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008717
8718DeferredHandles* HandleScopeImplementer::Detach(Object** prev_limit) {
8719 DeferredHandles* deferred =
8720 new DeferredHandles(isolate()->handle_scope_data()->next, isolate());
8721
8722 while (!blocks_.is_empty()) {
8723 Object** block_start = blocks_.last();
8724 Object** block_limit = &block_start[kHandleBlockSize];
8725 // We should not need to check for SealHandleScope here. Assert this.
8726 DCHECK(prev_limit == block_limit ||
8727 !(block_start <= prev_limit && prev_limit <= block_limit));
8728 if (prev_limit == block_limit) break;
8729 deferred->blocks_.Add(blocks_.last());
8730 blocks_.RemoveLast();
8731 }
8732
8733 // deferred->blocks_ now contains the blocks installed on the
8734 // HandleScope stack since BeginDeferredScope was called, but in
8735 // reverse order.
8736
8737 DCHECK(prev_limit == NULL || !blocks_.is_empty());
8738
8739 DCHECK(!blocks_.is_empty() && prev_limit != NULL);
8740 DCHECK(last_handle_before_deferred_block_ != NULL);
8741 last_handle_before_deferred_block_ = NULL;
8742 return deferred;
8743}
8744
8745
8746void HandleScopeImplementer::BeginDeferredScope() {
8747 DCHECK(last_handle_before_deferred_block_ == NULL);
8748 last_handle_before_deferred_block_ = isolate()->handle_scope_data()->next;
8749}
8750
8751
8752DeferredHandles::~DeferredHandles() {
8753 isolate_->UnlinkDeferredHandles(this);
8754
8755 for (int i = 0; i < blocks_.length(); i++) {
8756#ifdef ENABLE_HANDLE_ZAPPING
8757 HandleScope::ZapRange(blocks_[i], &blocks_[i][kHandleBlockSize]);
8758#endif
8759 isolate_->handle_scope_implementer()->ReturnBlock(blocks_[i]);
8760 }
8761}
8762
8763
8764void DeferredHandles::Iterate(ObjectVisitor* v) {
8765 DCHECK(!blocks_.is_empty());
8766
8767 DCHECK((first_block_limit_ >= blocks_.first()) &&
8768 (first_block_limit_ <= &(blocks_.first())[kHandleBlockSize]));
8769
8770 v->VisitPointers(blocks_.first(), first_block_limit_);
8771
8772 for (int i = 1; i < blocks_.length(); i++) {
8773 v->VisitPointers(blocks_[i], &blocks_[i][kHandleBlockSize]);
8774 }
8775}
8776
8777
8778void InvokeAccessorGetterCallback(
8779 v8::Local<v8::Name> property,
8780 const v8::PropertyCallbackInfo<v8::Value>& info,
8781 v8::AccessorNameGetterCallback getter) {
8782 // Leaving JavaScript.
8783 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
8784 Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
8785 getter));
8786 VMState<EXTERNAL> state(isolate);
8787 ExternalCallbackScope call_scope(isolate, getter_address);
8788 getter(property, info);
8789}
8790
8791
8792void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
8793 v8::FunctionCallback callback) {
8794 Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
8795 Address callback_address =
8796 reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
8797 VMState<EXTERNAL> state(isolate);
8798 ExternalCallbackScope call_scope(isolate, callback_address);
8799 callback(info);
8800}
8801
8802
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008803} // namespace internal
8804} // namespace v8