Upgrade V8 to version 4.9.385.28
https://chromium.googlesource.com/v8/v8/+/4.9.385.28
FPIIM-449
Change-Id: I4b2e74289d4bf3667f2f3dc8aa2e541f63e26eb4
diff --git a/src/api.cc b/src/api.cc
index a459076..8274a73 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -9,9 +9,14 @@
#include <sanitizer/asan_interface.h>
#endif // V8_USE_ADDRESS_SANITIZER
#include <cmath> // For isnan.
+#include <limits>
+#include <vector>
#include "include/v8-debug.h"
+#include "include/v8-experimental.h"
#include "include/v8-profiler.h"
#include "include/v8-testing.h"
+#include "src/api-experimental.h"
+#include "src/api-natives.h"
#include "src/assert-scope.h"
#include "src/background-parsing-task.h"
#include "src/base/functional.h"
@@ -19,80 +24,192 @@
#include "src/base/platform/time.h"
#include "src/base/utils/random-number-generator.h"
#include "src/bootstrapper.h"
+#include "src/char-predicates-inl.h"
#include "src/code-stubs.h"
#include "src/compiler.h"
+#include "src/context-measure.h"
+#include "src/contexts.h"
#include "src/conversions-inl.h"
#include "src/counters.h"
-#include "src/cpu-profiler.h"
-#include "src/debug.h"
+#include "src/debug/debug.h"
#include "src/deoptimizer.h"
#include "src/execution.h"
#include "src/global-handles.h"
-#include "src/heap-profiler.h"
-#include "src/heap-snapshot-generator-inl.h"
#include "src/icu_util.h"
-#include "src/json-parser.h"
+#include "src/isolate-inl.h"
#include "src/messages.h"
-#include "src/natives.h"
-#include "src/parser.h"
-#include "src/profile-generator-inl.h"
+#include "src/parsing/json-parser.h"
+#include "src/parsing/parser.h"
+#include "src/parsing/scanner-character-streams.h"
+#include "src/pending-compilation-error-handler.h"
+#include "src/profiler/cpu-profiler.h"
+#include "src/profiler/heap-profiler.h"
+#include "src/profiler/heap-snapshot-generator-inl.h"
+#include "src/profiler/profile-generator-inl.h"
+#include "src/profiler/sampler.h"
#include "src/property.h"
+#include "src/property-descriptor.h"
#include "src/property-details.h"
#include "src/prototype.h"
#include "src/runtime/runtime.h"
#include "src/runtime-profiler.h"
-#include "src/sampler.h"
-#include "src/scanner-character-streams.h"
#include "src/simulator.h"
-#include "src/snapshot.h"
+#include "src/snapshot/natives.h"
+#include "src/snapshot/snapshot.h"
+#include "src/startup-data-util.h"
#include "src/unicode-inl.h"
+#include "src/v8.h"
#include "src/v8threads.h"
#include "src/version.h"
#include "src/vm-state-inl.h"
-#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
-
-#define ENTER_V8(isolate) \
- i::VMState<v8::OTHER> __state__((isolate))
-
namespace v8 {
-#define ON_BAILOUT(isolate, location, code) \
- if (IsExecutionTerminatingCheck(isolate)) { \
- code; \
- UNREACHABLE(); \
- }
+#define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr))
-#define EXCEPTION_PREAMBLE(isolate) \
- (isolate)->handle_scope_implementer()->IncrementCallDepth(); \
- DCHECK(!(isolate)->external_caught_exception()); \
+#define ENTER_V8(isolate) i::VMState<v8::OTHER> __state__((isolate))
+
+
+#define PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
+ bailout_value, HandleScopeClass, \
+ do_callback) \
+ if (IsExecutionTerminatingCheck(isolate)) { \
+ return bailout_value; \
+ } \
+ HandleScopeClass handle_scope(isolate); \
+ CallDepthScope call_depth_scope(isolate, context, do_callback); \
+ LOG_API(isolate, function_name); \
+ ENTER_V8(isolate); \
bool has_pending_exception = false
-#define EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, do_callback) \
- do { \
- i::HandleScopeImplementer* handle_scope_implementer = \
- (isolate)->handle_scope_implementer(); \
- handle_scope_implementer->DecrementCallDepth(); \
- if (has_pending_exception) { \
- bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \
- (isolate)->OptionalRescheduleException(call_depth_is_zero); \
- do_callback \
- return value; \
- } \
- do_callback \
+#define PREPARE_FOR_EXECUTION_WITH_CONTEXT( \
+ context, function_name, bailout_value, HandleScopeClass, do_callback) \
+ auto isolate = context.IsEmpty() \
+ ? i::Isolate::Current() \
+ : reinterpret_cast<i::Isolate*>(context->GetIsolate()); \
+ PREPARE_FOR_EXECUTION_GENERIC(isolate, context, function_name, \
+ bailout_value, HandleScopeClass, do_callback);
+
+
+#define PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, function_name, T) \
+ PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(), function_name, \
+ MaybeLocal<T>(), InternalEscapableScope, \
+ false);
+
+
+#define PREPARE_FOR_EXECUTION(context, function_name, T) \
+ PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \
+ InternalEscapableScope, false)
+
+
+#define PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, function_name, T) \
+ PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, MaybeLocal<T>(), \
+ InternalEscapableScope, true)
+
+
+#define PREPARE_FOR_EXECUTION_PRIMITIVE(context, function_name, T) \
+ PREPARE_FOR_EXECUTION_WITH_CONTEXT(context, function_name, Nothing<T>(), \
+ i::HandleScope, false)
+
+
+#define EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, value) \
+ do { \
+ if (has_pending_exception) { \
+ call_depth_scope.Escape(); \
+ return value; \
+ } \
} while (false)
-#define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \
- EXCEPTION_BAILOUT_CHECK_GENERIC( \
- isolate, value, isolate->FireCallCompletedCallback();)
+#define RETURN_ON_FAILED_EXECUTION(T) \
+ EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, MaybeLocal<T>())
-#define EXCEPTION_BAILOUT_CHECK(isolate, value) \
- EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;)
+#define RETURN_ON_FAILED_EXECUTION_PRIMITIVE(T) \
+ EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, Nothing<T>())
+
+
+#define RETURN_TO_LOCAL_UNCHECKED(maybe_local, T) \
+ return maybe_local.FromMaybe(Local<T>());
+
+
+#define RETURN_ESCAPED(value) return handle_scope.Escape(value);
+
+
+namespace {
+
+Local<Context> ContextFromHeapObject(i::Handle<i::Object> obj) {
+ return reinterpret_cast<v8::Isolate*>(i::HeapObject::cast(*obj)->GetIsolate())
+ ->GetCurrentContext();
+}
+
+class InternalEscapableScope : public v8::EscapableHandleScope {
+ public:
+ explicit inline InternalEscapableScope(i::Isolate* isolate)
+ : v8::EscapableHandleScope(reinterpret_cast<v8::Isolate*>(isolate)) {}
+};
+
+
+class CallDepthScope {
+ public:
+ explicit CallDepthScope(i::Isolate* isolate, Local<Context> context,
+ bool do_callback)
+ : isolate_(isolate),
+ context_(context),
+ escaped_(false),
+ do_callback_(do_callback) {
+ // TODO(dcarney): remove this when blink stops crashing.
+ DCHECK(!isolate_->external_caught_exception());
+ isolate_->IncrementJsCallsFromApiCounter();
+ isolate_->handle_scope_implementer()->IncrementCallDepth();
+ if (!context_.IsEmpty()) context_->Enter();
+ }
+ ~CallDepthScope() {
+ if (!context_.IsEmpty()) context_->Exit();
+ if (!escaped_) isolate_->handle_scope_implementer()->DecrementCallDepth();
+ if (do_callback_) isolate_->FireCallCompletedCallback();
+ }
+
+ void Escape() {
+ DCHECK(!escaped_);
+ escaped_ = true;
+ auto handle_scope_implementer = isolate_->handle_scope_implementer();
+ handle_scope_implementer->DecrementCallDepth();
+ bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero();
+ isolate_->OptionalRescheduleException(call_depth_is_zero);
+ }
+
+ private:
+ i::Isolate* const isolate_;
+ Local<Context> context_;
+ bool escaped_;
+ bool do_callback_;
+};
+
+} // namespace
+
+
+static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
+ i::Handle<i::Script> script) {
+ i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
+ i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
+ v8::Isolate* v8_isolate =
+ reinterpret_cast<v8::Isolate*>(script->GetIsolate());
+ ScriptOriginOptions options(script->origin_options());
+ v8::ScriptOrigin origin(
+ Utils::ToLocal(scriptName),
+ v8::Integer::New(v8_isolate, script->line_offset()),
+ v8::Integer::New(v8_isolate, script->column_offset()),
+ v8::Boolean::New(v8_isolate, options.IsSharedCrossOrigin()),
+ v8::Integer::New(v8_isolate, script->id()),
+ v8::Boolean::New(v8_isolate, options.IsEmbedderDebugScript()),
+ Utils::ToLocal(source_map_url),
+ v8::Boolean::New(v8_isolate, options.IsOpaque()));
+ return origin;
+}
// --- E x c e p t i o n B e h a v i o r ---
@@ -106,6 +223,12 @@
// When V8 cannot allocated memory FatalProcessOutOfMemory is called.
// The default fatal error handler is called and execution is stopped.
void i::V8::FatalProcessOutOfMemory(const char* location, bool take_snapshot) {
+ i::Isolate* isolate = i::Isolate::Current();
+ char last_few_messages[Heap::kTraceRingBufferSize + 1];
+ char js_stacktrace[Heap::kStacktraceBufferSize + 1];
+ memset(last_few_messages, 0, Heap::kTraceRingBufferSize + 1);
+ memset(js_stacktrace, 0, Heap::kStacktraceBufferSize + 1);
+
i::HeapStats heap_stats;
int start_marker;
heap_stats.start_marker = &start_marker;
@@ -113,14 +236,10 @@
heap_stats.new_space_size = &new_space_size;
int new_space_capacity;
heap_stats.new_space_capacity = &new_space_capacity;
- intptr_t old_pointer_space_size;
- heap_stats.old_pointer_space_size = &old_pointer_space_size;
- intptr_t old_pointer_space_capacity;
- heap_stats.old_pointer_space_capacity = &old_pointer_space_capacity;
- intptr_t old_data_space_size;
- heap_stats.old_data_space_size = &old_data_space_size;
- intptr_t old_data_space_capacity;
- heap_stats.old_data_space_capacity = &old_data_space_capacity;
+ intptr_t old_space_size;
+ heap_stats.old_space_size = &old_space_size;
+ intptr_t old_space_capacity;
+ heap_stats.old_space_capacity = &old_space_capacity;
intptr_t code_space_size;
heap_stats.code_space_size = &code_space_size;
intptr_t code_space_capacity;
@@ -129,14 +248,6 @@
heap_stats.map_space_size = &map_space_size;
intptr_t map_space_capacity;
heap_stats.map_space_capacity = &map_space_capacity;
- intptr_t cell_space_size;
- heap_stats.cell_space_size = &cell_space_size;
- intptr_t cell_space_capacity;
- heap_stats.cell_space_capacity = &cell_space_capacity;
- intptr_t property_cell_space_size;
- heap_stats.property_cell_space_size = &property_cell_space_size;
- intptr_t property_cell_space_capacity;
- heap_stats.property_cell_space_capacity = &property_cell_space_capacity;
intptr_t lo_space_size;
heap_stats.lo_space_size = &lo_space_size;
int global_handle_count;
@@ -159,13 +270,19 @@
heap_stats.size_per_type = size_per_type;
int os_error;
heap_stats.os_error = &os_error;
+ heap_stats.last_few_messages = last_few_messages;
+ heap_stats.js_stacktrace = js_stacktrace;
int end_marker;
heap_stats.end_marker = &end_marker;
- i::Isolate* isolate = i::Isolate::Current();
if (isolate->heap()->HasBeenSetUp()) {
// BUG(1718): Don't use the take_snapshot since we don't support
// HeapIterator here without doing a special GC.
isolate->heap()->RecordStats(&heap_stats, false);
+ char* first_newline = strchr(last_few_messages, '\n');
+ if (first_newline == NULL || first_newline[1] == '\0')
+ first_newline = last_few_messages;
+ PrintF("\n<--- Last few GCs --->\n%s\n", first_newline);
+ PrintF("\n<--- JS stacktrace --->\n%s\n", js_stacktrace);
}
Utils::ApiCheck(false, location, "Allocation failed - process out of memory");
// If the fatal error handler returns, we stop execution.
@@ -206,30 +323,99 @@
}
-StartupData V8::CreateSnapshotDataBlob() {
- Isolate::CreateParams params;
- params.enable_serializer = true;
- Isolate* isolate = v8::Isolate::New(params);
+bool RunExtraCode(Isolate* isolate, Local<Context> context,
+ const char* utf8_source) {
+ // Run custom script if provided.
+ base::ElapsedTimer timer;
+ timer.Start();
+ TryCatch try_catch(isolate);
+ Local<String> source_string;
+ if (!String::NewFromUtf8(isolate, utf8_source, NewStringType::kNormal)
+ .ToLocal(&source_string)) {
+ return false;
+ }
+ Local<String> resource_name =
+ String::NewFromUtf8(isolate, "<embedded script>", NewStringType::kNormal)
+ .ToLocalChecked();
+ ScriptOrigin origin(resource_name);
+ ScriptCompiler::Source source(source_string, origin);
+ Local<Script> script;
+ if (!ScriptCompiler::Compile(context, &source).ToLocal(&script)) return false;
+ if (script->Run(context).IsEmpty()) return false;
+ if (i::FLAG_profile_deserialization) {
+ i::PrintF("Executing custom snapshot script took %0.3f ms\n",
+ timer.Elapsed().InMillisecondsF());
+ }
+ timer.Stop();
+ CHECK(!try_catch.HasCaught());
+ return true;
+}
+
+
+namespace {
+
+class ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
+ public:
+ virtual void* Allocate(size_t length) {
+ void* data = AllocateUninitialized(length);
+ return data == NULL ? data : memset(data, 0, length);
+ }
+ virtual void* AllocateUninitialized(size_t length) { return malloc(length); }
+ virtual void Free(void* data, size_t) { free(data); }
+};
+
+} // namespace
+
+
+StartupData V8::CreateSnapshotDataBlob(const char* custom_source) {
+ i::Isolate* internal_isolate = new i::Isolate(true);
+ ArrayBufferAllocator allocator;
+ internal_isolate->set_array_buffer_allocator(&allocator);
+ Isolate* isolate = reinterpret_cast<Isolate*>(internal_isolate);
StartupData result = {NULL, 0};
{
+ base::ElapsedTimer timer;
+ timer.Start();
Isolate::Scope isolate_scope(isolate);
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ internal_isolate->Init(NULL);
Persistent<Context> context;
+ i::Snapshot::Metadata metadata;
{
HandleScope handle_scope(isolate);
- context.Reset(isolate, Context::New(isolate));
+ Local<Context> new_context = Context::New(isolate);
+ context.Reset(isolate, new_context);
+ if (custom_source != NULL) {
+ metadata.set_embeds_script(true);
+ Context::Scope context_scope(new_context);
+ if (!RunExtraCode(isolate, new_context, custom_source)) context.Reset();
+ }
}
if (!context.IsEmpty()) {
- // Make sure all builtin scripts are cached.
- {
- HandleScope scope(isolate);
- for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) {
- internal_isolate->bootstrapper()->NativesSourceLookup(i);
- }
- }
// If we don't do this then we end up with a stray root pointing at the
// context even after we have disposed of the context.
internal_isolate->heap()->CollectAllAvailableGarbage("mksnapshot");
+
+ // GC may have cleared weak cells, so compact any WeakFixedArrays
+ // found on the heap.
+ i::HeapIterator iterator(internal_isolate->heap(),
+ i::HeapIterator::kFilterUnreachable);
+ for (i::HeapObject* o = iterator.next(); o != NULL; o = iterator.next()) {
+ if (o->IsPrototypeInfo()) {
+ i::Object* prototype_users =
+ i::PrototypeInfo::cast(o)->prototype_users();
+ if (prototype_users->IsWeakFixedArray()) {
+ i::WeakFixedArray* array = i::WeakFixedArray::cast(prototype_users);
+ array->Compact<i::JSObject::PrototypeRegistryCompactionCallback>();
+ }
+ } else if (o->IsScript()) {
+ i::Object* shared_list = i::Script::cast(o)->shared_function_infos();
+ if (shared_list->IsWeakFixedArray()) {
+ i::WeakFixedArray* array = i::WeakFixedArray::cast(shared_list);
+ array->Compact<i::WeakFixedArray::NullCallback>();
+ }
+ }
+ }
+
i::Object* raw_context = *v8::Utils::OpenPersistent(context);
context.Reset();
@@ -240,13 +426,15 @@
i::SnapshotByteSink context_sink;
i::PartialSerializer context_ser(internal_isolate, &ser, &context_sink);
context_ser.Serialize(&raw_context);
- ser.SerializeWeakReferences();
+ ser.SerializeWeakReferencesAndDeferred();
- i::SnapshotData sd(snapshot_sink, ser);
- i::SnapshotData csd(context_sink, context_ser);
-
- result = i::Snapshot::CreateSnapshotBlob(sd.RawData(), csd.RawData());
+ result = i::Snapshot::CreateSnapshotBlob(ser, context_ser, metadata);
}
+ if (i::FLAG_profile_deserialization) {
+ i::PrintF("Creating snapshot took %0.3f ms\n",
+ timer.Elapsed().InMillisecondsF());
+ }
+ timer.Stop();
}
isolate->Dispose();
return result;
@@ -315,12 +503,10 @@
max_old_space_size_(0),
max_executable_size_(0),
stack_limit_(NULL),
- max_available_threads_(0),
code_range_size_(0) { }
void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory,
- uint64_t virtual_memory_limit,
- uint32_t number_of_processors) {
+ uint64_t virtual_memory_limit) {
#if V8_OS_ANDROID
// Android has higher physical memory requirements before raising the maximum
// heap size limits since it has no swap space.
@@ -351,8 +537,6 @@
set_max_executable_size(i::Heap::kMaxExecutableSizeHugeMemoryDevice);
}
- set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u));
-
if (virtual_memory_limit > 0 && i::kRequiresCodeRange) {
// Reserve no more than 1/8 of the memory for the code range, but at most
// kMaximalCodeRangeSize.
@@ -378,8 +562,6 @@
uintptr_t limit = reinterpret_cast<uintptr_t>(constraints.stack_limit());
isolate->stack_guard()->SetStackLimit(limit);
}
-
- isolate->set_max_available_threads(constraints.max_available_threads());
}
@@ -387,7 +569,9 @@
LOG_API(isolate, "Persistent::New");
i::Handle<i::Object> result = isolate->global_handles()->Create(*obj);
#ifdef VERIFY_HEAP
- (*obj)->ObjectVerify();
+ if (i::FLAG_verify_heap) {
+ (*obj)->ObjectVerify();
+ }
#endif // VERIFY_HEAP
return result.location();
}
@@ -396,7 +580,9 @@
i::Object** V8::CopyPersistent(i::Object** obj) {
i::Handle<i::Object> result = i::GlobalHandles::CopyGlobal(obj);
#ifdef VERIFY_HEAP
- (*obj)->ObjectVerify();
+ if (i::FLAG_verify_heap) {
+ (*obj)->ObjectVerify();
+ }
#endif // VERIFY_HEAP
return result.location();
}
@@ -408,18 +594,29 @@
}
-void V8::MakePhantom(i::Object** object, void* parameter,
- PhantomCallbackData<void>::Callback weak_callback) {
- i::GlobalHandles::MakePhantom(object, parameter, weak_callback);
+void V8::MakeWeak(i::Object** object, void* parameter,
+ int internal_field_index1, int internal_field_index2,
+ WeakCallbackInfo<void>::Callback weak_callback) {
+ WeakCallbackType type = WeakCallbackType::kParameter;
+ if (internal_field_index1 == 0) {
+ if (internal_field_index2 == 1) {
+ type = WeakCallbackType::kInternalFields;
+ } else {
+ DCHECK_EQ(internal_field_index2, -1);
+ type = WeakCallbackType::kInternalFields;
+ }
+ } else {
+ DCHECK_EQ(internal_field_index1, -1);
+ DCHECK_EQ(internal_field_index2, -1);
+ }
+ i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
}
-void V8::MakePhantom(
- i::Object** object,
- InternalFieldsCallbackData<void, void>::Callback weak_callback,
- int internal_field_index1, int internal_field_index2) {
- i::GlobalHandles::MakePhantom(object, weak_callback, internal_field_index1,
- internal_field_index2);
+void V8::MakeWeak(i::Object** object, void* parameter,
+ WeakCallbackInfo<void>::Callback weak_callback,
+ WeakCallbackType type) {
+ i::GlobalHandles::MakeWeak(object, parameter, weak_callback, type);
}
@@ -446,6 +643,23 @@
}
+void V8::FromJustIsNothing() {
+ Utils::ApiCheck(false, "v8::FromJust", "Maybe value is Nothing.");
+}
+
+
+void V8::ToLocalEmpty() {
+ Utils::ApiCheck(false, "v8::ToLocalChecked", "Empty MaybeLocal.");
+}
+
+
+void V8::InternalFieldOutOfBounds(int index) {
+ Utils::ApiCheck(0 <= index && index < kInternalFieldsInWeakCallback,
+ "WeakCallbackInfo::GetInternalField",
+ "Internal field out of bounds.");
+}
+
+
// --- H a n d l e s ---
@@ -459,10 +673,14 @@
// We do not want to check the correct usage of the Locker class all over the
// place, so we do it only here: Without a HandleScope, an embedder can do
// almost nothing, so it is enough to check in this central place.
- Utils::ApiCheck(!v8::Locker::IsActive() ||
- internal_isolate->thread_manager()->IsLockedByCurrentThread(),
- "HandleScope::HandleScope",
- "Entering the V8 API without proper locking in place");
+ // We make an exception if the serializer is enabled, which means that the
+ // Isolate is exclusively used to create a snapshot.
+ Utils::ApiCheck(
+ !v8::Locker::IsActive() ||
+ internal_isolate->thread_manager()->IsLockedByCurrentThread() ||
+ internal_isolate->serializer_enabled(),
+ "HandleScope::HandleScope",
+ "Entering the V8 API without proper locking in place");
i::HandleScopeData* current = internal_isolate->handle_scope_data();
isolate_ = internal_isolate;
prev_next_ = current->next;
@@ -515,6 +733,27 @@
}
+SealHandleScope::SealHandleScope(Isolate* isolate) {
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+
+ isolate_ = internal_isolate;
+ i::HandleScopeData* current = internal_isolate->handle_scope_data();
+ prev_limit_ = current->limit;
+ current->limit = current->next;
+ prev_sealed_level_ = current->sealed_level;
+ current->sealed_level = current->level;
+}
+
+
+SealHandleScope::~SealHandleScope() {
+ i::HandleScopeData* current = isolate_->handle_scope_data();
+ DCHECK_EQ(current->next, current->limit);
+ current->limit = prev_limit_;
+ DCHECK_EQ(current->level, current->sealed_level);
+ current->sealed_level = prev_sealed_level_;
+}
+
+
void Context::Enter() {
i::Handle<i::Context> env = Utils::OpenHandle(this);
i::Isolate* isolate = env->GetIsolate();
@@ -559,6 +798,7 @@
bool can_grow,
const char* location) {
i::Handle<i::Context> env = Utils::OpenHandle(context);
+ i::Isolate* isolate = env->GetIsolate();
bool ok =
Utils::ApiCheck(env->IsNativeContext(),
location,
@@ -571,7 +811,8 @@
return i::Handle<i::FixedArray>();
}
int new_size = i::Max(index, data->length() << 1) + 1;
- data = i::FixedArray::CopySize(data, new_size);
+ int grow_by = new_size - data->length();
+ data = isolate->factory()->CopyFixedArrayAndGrow(data, grow_by);
env->set_embedder_data(*data);
return data;
}
@@ -586,7 +827,7 @@
}
-void Context::SetEmbedderData(int index, v8::Handle<Value> value) {
+void Context::SetEmbedderData(int index, v8::Local<Value> value) {
const char* location = "v8::Context::SetEmbedderData()";
i::Handle<i::FixedArray> data = EmbedderDataFor(this, index, true, location);
if (data.is_null()) return;
@@ -645,8 +886,8 @@
i::Object* NeanderArray::get(int offset) {
- DCHECK(0 <= offset);
- DCHECK(offset < length());
+ DCHECK_LE(0, offset);
+ DCHECK_LT(offset, length());
return obj_.get(offset + 1);
}
@@ -681,43 +922,21 @@
static void InitializeTemplate(i::Handle<i::TemplateInfo> that, int type) {
+ that->set_number_of_properties(0);
that->set_tag(i::Smi::FromInt(type));
}
-static void TemplateSet(i::Isolate* isolate,
- v8::Template* templ,
- int length,
- v8::Handle<v8::Data>* data) {
- i::Handle<i::Object> list(Utils::OpenHandle(templ)->property_list(), isolate);
- if (list->IsUndefined()) {
- list = NeanderArray(isolate).value();
- Utils::OpenHandle(templ)->set_property_list(*list);
- }
- NeanderArray array(list);
- array.add(isolate, isolate->factory()->NewNumberFromInt(length));
- for (int i = 0; i < length; i++) {
- i::Handle<i::Object> value = data[i].IsEmpty() ?
- i::Handle<i::Object>(isolate->factory()->undefined_value()) :
- Utils::OpenHandle(*data[i]);
- array.add(isolate, value);
- }
-}
-
-
-void Template::Set(v8::Handle<Name> name,
- v8::Handle<Data> value,
+void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
v8::PropertyAttribute attribute) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ auto templ = Utils::OpenHandle(this);
+ i::Isolate* isolate = templ->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- const int kSize = 3;
- v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
- v8::Handle<v8::Data> data[kSize] = {
- name,
- value,
- v8::Integer::New(v8_isolate, attribute)};
- TemplateSet(isolate, this, kSize, data);
+ // TODO(dcarney): split api to allow values of v8::Value or v8::TemplateInfo.
+ i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
+ Utils::OpenHandle(*value),
+ static_cast<i::PropertyAttributes>(attribute));
}
@@ -729,26 +948,23 @@
v8::AccessControl access_control) {
// TODO(verwaest): Remove |access_control|.
DCHECK_EQ(v8::DEFAULT, access_control);
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ auto templ = Utils::OpenHandle(this);
+ auto isolate = templ->GetIsolate();
ENTER_V8(isolate);
DCHECK(!name.IsEmpty());
DCHECK(!getter.IsEmpty() || !setter.IsEmpty());
i::HandleScope scope(isolate);
- const int kSize = 5;
- v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
- v8::Handle<v8::Data> data[kSize] = {
- name,
- getter,
- setter,
- v8::Integer::New(v8_isolate, attribute)};
- TemplateSet(isolate, this, kSize, data);
+ i::ApiNatives::AddAccessorProperty(
+ isolate, templ, Utils::OpenHandle(*name),
+ Utils::OpenHandle(*getter, true), Utils::OpenHandle(*setter, true),
+ static_cast<i::PropertyAttributes>(attribute));
}
// --- F u n c t i o n T e m p l a t e ---
static void InitializeFunctionTemplate(
i::Handle<i::FunctionTemplateInfo> info) {
- info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE));
+ InitializeTemplate(info, Consts::FUNCTION_TEMPLATE);
info->set_flag(0);
}
@@ -767,20 +983,26 @@
}
-void FunctionTemplate::Inherit(v8::Handle<FunctionTemplate> value) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+static void EnsureNotInstantiated(i::Handle<i::FunctionTemplateInfo> info,
+ const char* func) {
+ Utils::ApiCheck(!info->instantiated(), func,
+ "FunctionTemplate already instantiated");
+}
+
+
+void FunctionTemplate::Inherit(v8::Local<FunctionTemplate> value) {
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::Inherit");
+ i::Isolate* isolate = info->GetIsolate();
ENTER_V8(isolate);
- Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value));
+ info->set_parent_template(*Utils::OpenHandle(*value));
}
static Local<FunctionTemplate> FunctionTemplateNew(
- i::Isolate* isolate,
- FunctionCallback callback,
- v8::Handle<Value> data,
- v8::Handle<Signature> signature,
- int length,
- bool do_not_cache) {
+ i::Isolate* isolate, FunctionCallback callback,
+ experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
+ v8::Local<Signature> signature, int length, bool do_not_cache) {
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE);
i::Handle<i::FunctionTemplateInfo> obj =
@@ -797,223 +1019,71 @@
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
- Utils::ToLocal(obj)->SetCallHandler(callback, data);
+ Utils::ToLocal(obj)->SetCallHandler(callback, data, fast_handler);
}
obj->set_length(length);
obj->set_undetectable(false);
obj->set_needs_access_check(false);
+ obj->set_accept_any_receiver(true);
if (!signature.IsEmpty())
obj->set_signature(*Utils::OpenHandle(*signature));
return Utils::ToLocal(obj);
}
-Local<FunctionTemplate> FunctionTemplate::New(
- Isolate* isolate,
- FunctionCallback callback,
- v8::Handle<Value> data,
- v8::Handle<Signature> signature,
- int length) {
+
+Local<FunctionTemplate> FunctionTemplate::New(Isolate* isolate,
+ FunctionCallback callback,
+ v8::Local<Value> data,
+ v8::Local<Signature> signature,
+ int length) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
// Changes to the environment cannot be captured in the snapshot. Expect no
// function templates when the isolate is created for serialization.
DCHECK(!i_isolate->serializer_enabled());
LOG_API(i_isolate, "FunctionTemplate::New");
ENTER_V8(i_isolate);
- return FunctionTemplateNew(
- i_isolate, callback, data, signature, length, false);
+ return FunctionTemplateNew(i_isolate, callback, nullptr, data, signature,
+ length, false);
+}
+
+
+Local<FunctionTemplate> FunctionTemplate::NewWithFastHandler(
+ Isolate* isolate, FunctionCallback callback,
+ experimental::FastAccessorBuilder* fast_handler, v8::Local<Value> data,
+ v8::Local<Signature> signature, int length) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ DCHECK(!i_isolate->serializer_enabled());
+ LOG_API(i_isolate, "FunctionTemplate::NewWithFastHandler");
+ ENTER_V8(i_isolate);
+ return FunctionTemplateNew(i_isolate, callback, fast_handler, data, signature,
+ length, false);
}
Local<Signature> Signature::New(Isolate* isolate,
- Handle<FunctionTemplate> receiver, int argc,
- Handle<FunctionTemplate> argv[]) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Signature::New");
- ENTER_V8(i_isolate);
- i::Handle<i::Struct> struct_obj =
- i_isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE);
- i::Handle<i::SignatureInfo> obj =
- i::Handle<i::SignatureInfo>::cast(struct_obj);
- if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver));
- if (argc > 0) {
- i::Handle<i::FixedArray> args = i_isolate->factory()->NewFixedArray(argc);
- for (int i = 0; i < argc; i++) {
- if (!argv[i].IsEmpty())
- args->set(i, *Utils::OpenHandle(*argv[i]));
- }
- obj->set_args(*args);
- }
- return Utils::ToLocal(obj);
+ Local<FunctionTemplate> receiver) {
+ return Utils::SignatureToLocal(Utils::OpenHandle(*receiver));
}
Local<AccessorSignature> AccessorSignature::New(
- Isolate* isolate,
- Handle<FunctionTemplate> receiver) {
+ Isolate* isolate, Local<FunctionTemplate> receiver) {
return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
}
-template<typename Operation>
-static Local<Operation> NewDescriptor(
- Isolate* isolate,
- const i::DeclaredAccessorDescriptorData& data,
- Data* previous_descriptor) {
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- i::Handle<i::DeclaredAccessorDescriptor> previous =
- i::Handle<i::DeclaredAccessorDescriptor>();
- if (previous_descriptor != NULL) {
- previous = Utils::OpenHandle(
- static_cast<DeclaredAccessorDescriptor*>(previous_descriptor));
- }
- i::Handle<i::DeclaredAccessorDescriptor> descriptor =
- i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous);
- return Utils::Convert<i::DeclaredAccessorDescriptor, Operation>(descriptor);
-}
-
-
-Local<RawOperationDescriptor>
-ObjectOperationDescriptor::NewInternalFieldDereference(
- Isolate* isolate,
- int internal_field) {
- i::DeclaredAccessorDescriptorData data;
- data.type = i::kDescriptorObjectDereference;
- data.object_dereference_descriptor.internal_field = internal_field;
- return NewDescriptor<RawOperationDescriptor>(isolate, data, NULL);
-}
-
-
-Local<RawOperationDescriptor> RawOperationDescriptor::NewRawShift(
- Isolate* isolate,
- int16_t byte_offset) {
- i::DeclaredAccessorDescriptorData data;
- data.type = i::kDescriptorPointerShift;
- data.pointer_shift_descriptor.byte_offset = byte_offset;
- return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
-}
-
-
-Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewHandleDereference(
- Isolate* isolate) {
- i::DeclaredAccessorDescriptorData data;
- data.type = i::kDescriptorReturnObject;
- return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
-}
-
-
-Local<RawOperationDescriptor> RawOperationDescriptor::NewRawDereference(
- Isolate* isolate) {
- i::DeclaredAccessorDescriptorData data;
- data.type = i::kDescriptorPointerDereference;
- return NewDescriptor<RawOperationDescriptor>(isolate, data, this);
-}
-
-
-Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPointerCompare(
- Isolate* isolate,
- void* compare_value) {
- i::DeclaredAccessorDescriptorData data;
- data.type = i::kDescriptorPointerCompare;
- data.pointer_compare_descriptor.compare_value = compare_value;
- return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
-}
-
-
-Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewPrimitiveValue(
- Isolate* isolate,
- DeclaredAccessorDescriptorDataType data_type,
- uint8_t bool_offset) {
- i::DeclaredAccessorDescriptorData data;
- data.type = i::kDescriptorPrimitiveValue;
- data.primitive_value_descriptor.data_type = data_type;
- data.primitive_value_descriptor.bool_offset = bool_offset;
- return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, this);
-}
-
-
-template<typename T>
-static Local<DeclaredAccessorDescriptor> NewBitmaskCompare(
- Isolate* isolate,
- T bitmask,
- T compare_value,
- RawOperationDescriptor* operation) {
- i::DeclaredAccessorDescriptorData data;
- data.type = i::kDescriptorBitmaskCompare;
- data.bitmask_compare_descriptor.bitmask = bitmask;
- data.bitmask_compare_descriptor.compare_value = compare_value;
- data.bitmask_compare_descriptor.size = sizeof(T);
- return NewDescriptor<DeclaredAccessorDescriptor>(isolate, data, operation);
-}
-
-
-Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare8(
- Isolate* isolate,
- uint8_t bitmask,
- uint8_t compare_value) {
- return NewBitmaskCompare(isolate, bitmask, compare_value, this);
-}
-
-
-Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare16(
- Isolate* isolate,
- uint16_t bitmask,
- uint16_t compare_value) {
- return NewBitmaskCompare(isolate, bitmask, compare_value, this);
-}
-
-
-Local<DeclaredAccessorDescriptor> RawOperationDescriptor::NewBitmaskCompare32(
- Isolate* isolate,
- uint32_t bitmask,
- uint32_t compare_value) {
- return NewBitmaskCompare(isolate, bitmask, compare_value, this);
-}
-
-
-Local<TypeSwitch> TypeSwitch::New(Handle<FunctionTemplate> type) {
- Handle<FunctionTemplate> types[1] = { type };
- return TypeSwitch::New(1, types);
-}
-
-
-Local<TypeSwitch> TypeSwitch::New(int argc, Handle<FunctionTemplate> types[]) {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "TypeSwitch::New");
- ENTER_V8(isolate);
- i::Handle<i::FixedArray> vector = isolate->factory()->NewFixedArray(argc);
- for (int i = 0; i < argc; i++)
- vector->set(i, *Utils::OpenHandle(*types[i]));
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE);
- i::Handle<i::TypeSwitchInfo> obj =
- i::Handle<i::TypeSwitchInfo>::cast(struct_obj);
- obj->set_types(*vector);
- return Utils::ToLocal(obj);
-}
-
-
-int TypeSwitch::match(v8::Handle<Value> value) {
- i::Handle<i::TypeSwitchInfo> info = Utils::OpenHandle(this);
- LOG_API(info->GetIsolate(), "TypeSwitch::match");
- i::Handle<i::Object> obj = Utils::OpenHandle(*value);
- i::FixedArray* types = i::FixedArray::cast(info->types());
- for (int i = 0; i < types->length(); i++) {
- if (i::FunctionTemplateInfo::cast(types->get(i))->IsTemplateFor(*obj))
- return i + 1;
- }
- return 0;
-}
-
-
#define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
(obj)->setter(*foreign); \
} while (false)
-void FunctionTemplate::SetCallHandler(FunctionCallback callback,
- v8::Handle<Value> data) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+void FunctionTemplate::SetCallHandler(
+ FunctionCallback callback, v8::Local<Value> data,
+ experimental::FastAccessorBuilder* fast_handler) {
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::SetCallHandler");
+ i::Isolate* isolate = info->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
i::Handle<i::Struct> struct_obj =
@@ -1021,24 +1091,27 @@
i::Handle<i::CallHandlerInfo> obj =
i::Handle<i::CallHandlerInfo>::cast(struct_obj);
SET_FIELD_WRAPPED(obj, set_callback, callback);
+ i::MaybeHandle<i::Code> code =
+ i::experimental::BuildCodeFromFastAccessorBuilder(fast_handler);
+ if (!code.is_null()) {
+ obj->set_fast_handler(*code.ToHandleChecked());
+ }
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
}
obj->set_data(*Utils::OpenHandle(*data));
- Utils::OpenHandle(this)->set_call_code(*obj);
+ info->set_call_code(*obj);
}
static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
- i::Handle<i::AccessorInfo> obj,
- v8::Handle<Name> name,
- v8::AccessControl settings,
- v8::PropertyAttribute attributes,
- v8::Handle<AccessorSignature> signature) {
+ i::Handle<i::AccessorInfo> obj, v8::Local<Name> name,
+ v8::AccessControl settings, v8::PropertyAttribute attributes,
+ v8::Local<AccessorSignature> signature) {
obj->set_name(*Utils::OpenHandle(*name));
if (settings & ALL_CAN_READ) obj->set_all_can_read(true);
if (settings & ALL_CAN_WRITE) obj->set_all_can_write(true);
- obj->set_property_attributes(static_cast<PropertyAttributes>(attributes));
+ obj->set_property_attributes(static_cast<i::PropertyAttributes>(attributes));
if (!signature.IsEmpty()) {
obj->set_expected_receiver_type(*Utils::OpenHandle(*signature));
}
@@ -1046,15 +1119,11 @@
}
-template<typename Getter, typename Setter>
+template <typename Getter, typename Setter>
static i::Handle<i::AccessorInfo> MakeAccessorInfo(
- v8::Handle<Name> name,
- Getter getter,
- Setter setter,
- v8::Handle<Value> data,
- v8::AccessControl settings,
- v8::PropertyAttribute attributes,
- v8::Handle<AccessorSignature> signature) {
+ v8::Local<Name> name, Getter getter, Setter setter, v8::Local<Value> data,
+ v8::AccessControl settings, v8::PropertyAttribute attributes,
+ v8::Local<AccessorSignature> signature) {
i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
i::Handle<i::ExecutableAccessorInfo> obj =
isolate->factory()->NewExecutableAccessorInfo();
@@ -1068,23 +1137,6 @@
}
-static i::Handle<i::AccessorInfo> MakeAccessorInfo(
- v8::Handle<Name> name,
- v8::Handle<v8::DeclaredAccessorDescriptor> descriptor,
- void* setter_ignored,
- void* data_ignored,
- v8::AccessControl settings,
- v8::PropertyAttribute attributes,
- v8::Handle<AccessorSignature> signature) {
- i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
- if (descriptor.IsEmpty()) return i::Handle<i::DeclaredAccessorInfo>();
- i::Handle<i::DeclaredAccessorInfo> obj =
- isolate->factory()->NewDeclaredAccessorInfo();
- obj->set_descriptor(*Utils::OpenHandle(*descriptor));
- return SetAccessorInfoProperties(obj, name, settings, attributes, signature);
-}
-
-
Local<ObjectTemplate> FunctionTemplate::InstanceTemplate() {
i::Handle<i::FunctionTemplateInfo> handle = Utils::OpenHandle(this, true);
if (!Utils::ApiCheck(!handle.is_null(),
@@ -1106,45 +1158,65 @@
void FunctionTemplate::SetLength(int length) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::SetLength");
+ auto isolate = info->GetIsolate();
ENTER_V8(isolate);
- Utils::OpenHandle(this)->set_length(length);
+ info->set_length(length);
}
-void FunctionTemplate::SetClassName(Handle<String> name) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+void FunctionTemplate::SetClassName(Local<String> name) {
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::SetClassName");
+ auto isolate = info->GetIsolate();
ENTER_V8(isolate);
- Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name));
+ info->set_class_name(*Utils::OpenHandle(*name));
+}
+
+
+void FunctionTemplate::SetAcceptAnyReceiver(bool value) {
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::SetAcceptAnyReceiver");
+ auto isolate = info->GetIsolate();
+ ENTER_V8(isolate);
+ info->set_accept_any_receiver(value);
}
void FunctionTemplate::SetHiddenPrototype(bool value) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::SetHiddenPrototype");
+ auto isolate = info->GetIsolate();
ENTER_V8(isolate);
- Utils::OpenHandle(this)->set_hidden_prototype(value);
+ info->set_hidden_prototype(value);
}
void FunctionTemplate::ReadOnlyPrototype() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::ReadOnlyPrototype");
+ auto isolate = info->GetIsolate();
ENTER_V8(isolate);
- Utils::OpenHandle(this)->set_read_only_prototype(true);
+ info->set_read_only_prototype(true);
}
void FunctionTemplate::RemovePrototype() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ auto info = Utils::OpenHandle(this);
+ EnsureNotInstantiated(info, "v8::FunctionTemplate::RemovePrototype");
+ auto isolate = info->GetIsolate();
ENTER_V8(isolate);
- Utils::OpenHandle(this)->set_remove_prototype(true);
+ info->set_remove_prototype(true);
}
// --- O b j e c t T e m p l a t e ---
-Local<ObjectTemplate> ObjectTemplate::New(Isolate* isolate) {
- return New(reinterpret_cast<i::Isolate*>(isolate), Local<FunctionTemplate>());
+Local<ObjectTemplate> ObjectTemplate::New(
+ Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
+ return New(reinterpret_cast<i::Isolate*>(isolate), constructor);
}
@@ -1154,8 +1226,7 @@
Local<ObjectTemplate> ObjectTemplate::New(
- i::Isolate* isolate,
- v8::Handle<FunctionTemplate> constructor) {
+ i::Isolate* isolate, v8::Local<FunctionTemplate> constructor) {
// Changes to the environment cannot be captured in the snapshot. Expect no
// object templates when the isolate is created for serialization.
DCHECK(!isolate->serializer_enabled());
@@ -1192,20 +1263,6 @@
}
-static inline void AddPropertyToTemplate(
- i::Handle<i::TemplateInfo> info,
- i::Handle<i::AccessorInfo> obj) {
- i::Isolate* isolate = info->GetIsolate();
- i::Handle<i::Object> list(info->property_accessors(), isolate);
- if (list->IsUndefined()) {
- list = NeanderArray(isolate).value();
- info->set_property_accessors(*list);
- }
- NeanderArray array(list);
- array.add(isolate, obj);
-}
-
-
static inline i::Handle<i::TemplateInfo> GetTemplateInfo(
i::Isolate* isolate,
Template* template_obj) {
@@ -1232,34 +1289,22 @@
AccessControl settings,
PropertyAttribute attribute,
v8::Local<AccessorSignature> signature) {
- i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate();
+ auto isolate = Utils::OpenHandle(template_obj)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- i::Handle<i::AccessorInfo> obj = MakeAccessorInfo(
- name, getter, setter, data, settings, attribute, signature);
+ auto obj = MakeAccessorInfo(name, getter, setter, data, settings, attribute,
+ signature);
if (obj.is_null()) return false;
- i::Handle<i::TemplateInfo> info = GetTemplateInfo(isolate, template_obj);
- AddPropertyToTemplate(info, obj);
+ auto info = GetTemplateInfo(isolate, template_obj);
+ i::ApiNatives::AddNativeDataProperty(isolate, info, obj);
return true;
}
-bool Template::SetDeclaredAccessor(
- Local<Name> name,
- Local<DeclaredAccessorDescriptor> descriptor,
- PropertyAttribute attribute,
- Local<AccessorSignature> signature,
- AccessControl settings) {
- void* null = NULL;
- return TemplateSetAccessor(
- this, name, descriptor, null, null, settings, attribute, signature);
-}
-
-
void Template::SetNativeDataProperty(v8::Local<String> name,
AccessorGetterCallback getter,
AccessorSetterCallback setter,
- v8::Handle<Value> data,
+ v8::Local<Value> data,
PropertyAttribute attribute,
v8::Local<AccessorSignature> signature,
AccessControl settings) {
@@ -1271,7 +1316,7 @@
void Template::SetNativeDataProperty(v8::Local<Name> name,
AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter,
- v8::Handle<Value> data,
+ v8::Local<Value> data,
PropertyAttribute attribute,
v8::Local<AccessorSignature> signature,
AccessControl settings) {
@@ -1280,25 +1325,35 @@
}
-void ObjectTemplate::SetAccessor(v8::Handle<String> name,
+void Template::SetIntrinsicDataProperty(Local<Name> name, Intrinsic intrinsic,
+ PropertyAttribute attribute) {
+ auto templ = Utils::OpenHandle(this);
+ i::Isolate* isolate = templ->GetIsolate();
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::ApiNatives::AddDataProperty(isolate, templ, Utils::OpenHandle(*name),
+ intrinsic,
+ static_cast<i::PropertyAttributes>(attribute));
+}
+
+
+void ObjectTemplate::SetAccessor(v8::Local<String> name,
AccessorGetterCallback getter,
AccessorSetterCallback setter,
- v8::Handle<Value> data,
- AccessControl settings,
+ v8::Local<Value> data, AccessControl settings,
PropertyAttribute attribute,
- v8::Handle<AccessorSignature> signature) {
+ v8::Local<AccessorSignature> signature) {
TemplateSetAccessor(
this, name, getter, setter, data, settings, attribute, signature);
}
-void ObjectTemplate::SetAccessor(v8::Handle<Name> name,
+void ObjectTemplate::SetAccessor(v8::Local<Name> name,
AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter,
- v8::Handle<Value> data,
- AccessControl settings,
+ v8::Local<Value> data, AccessControl settings,
PropertyAttribute attribute,
- v8::Handle<AccessorSignature> signature) {
+ v8::Local<AccessorSignature> signature) {
TemplateSetAccessor(
this, name, getter, setter, data, settings, attribute, signature);
}
@@ -1306,29 +1361,33 @@
template <typename Getter, typename Setter, typename Query, typename Deleter,
typename Enumerator>
-static void ObjectTemplateSetNamedPropertyHandler(
- ObjectTemplate* templ, Getter getter, Setter setter, Query query,
- Deleter remover, Enumerator enumerator, Handle<Value> data,
- bool can_intercept_symbols, PropertyHandlerFlags flags) {
+static void ObjectTemplateSetNamedPropertyHandler(ObjectTemplate* templ,
+ Getter getter, Setter setter,
+ Query query, Deleter remover,
+ Enumerator enumerator,
+ Local<Value> data,
+ PropertyHandlerFlags flags) {
i::Isolate* isolate = Utils::OpenHandle(templ)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EnsureConstructor(isolate, templ);
- i::FunctionTemplateInfo* constructor =
- i::FunctionTemplateInfo::cast(Utils::OpenHandle(templ)->constructor());
- i::Handle<i::FunctionTemplateInfo> cons(constructor);
+ auto cons = EnsureConstructor(isolate, templ);
+ EnsureNotInstantiated(cons, "ObjectTemplateSetNamedPropertyHandler");
auto obj = i::Handle<i::InterceptorInfo>::cast(
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
+ obj->set_flags(0);
if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
- obj->set_flags(0);
- obj->set_can_intercept_symbols(can_intercept_symbols);
+ obj->set_can_intercept_symbols(
+ !(static_cast<int>(flags) &
+ static_cast<int>(PropertyHandlerFlags::kOnlyInterceptStrings)));
obj->set_all_can_read(static_cast<int>(flags) &
static_cast<int>(PropertyHandlerFlags::kAllCanRead));
+ obj->set_non_masking(static_cast<int>(flags) &
+ static_cast<int>(PropertyHandlerFlags::kNonMasking));
if (data.IsEmpty()) {
data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
@@ -1341,10 +1400,10 @@
void ObjectTemplate::SetNamedPropertyHandler(
NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter,
NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover,
- NamedPropertyEnumeratorCallback enumerator, Handle<Value> data) {
- ObjectTemplateSetNamedPropertyHandler(this, getter, setter, query, remover,
- enumerator, data, false,
- PropertyHandlerFlags::kNone);
+ NamedPropertyEnumeratorCallback enumerator, Local<Value> data) {
+ ObjectTemplateSetNamedPropertyHandler(
+ this, getter, setter, query, remover, enumerator, data,
+ PropertyHandlerFlags::kOnlyInterceptStrings);
}
@@ -1352,7 +1411,7 @@
const NamedPropertyHandlerConfiguration& config) {
ObjectTemplateSetNamedPropertyHandler(
this, config.getter, config.setter, config.query, config.deleter,
- config.enumerator, config.data, true, config.flags);
+ config.enumerator, config.data, config.flags);
}
@@ -1360,29 +1419,54 @@
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EnsureConstructor(isolate, this);
- i::FunctionTemplateInfo* constructor =
- i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
- i::Handle<i::FunctionTemplateInfo> cons(constructor);
+ auto cons = EnsureConstructor(isolate, this);
+ EnsureNotInstantiated(cons, "v8::ObjectTemplate::MarkAsUndetectable");
cons->set_undetectable(true);
}
-void ObjectTemplate::SetAccessCheckCallbacks(
- NamedSecurityCallback named_callback,
- IndexedSecurityCallback indexed_callback,
- Handle<Value> data,
- bool turned_on_by_default) {
+void ObjectTemplate::SetAccessCheckCallback(AccessCheckCallback callback,
+ Local<Value> data) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EnsureConstructor(isolate, this);
+ auto cons = EnsureConstructor(isolate, this);
+ EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallback");
i::Handle<i::Struct> struct_info =
isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
i::Handle<i::AccessCheckInfo> info =
i::Handle<i::AccessCheckInfo>::cast(struct_info);
+ SET_FIELD_WRAPPED(info, set_callback, callback);
+ SET_FIELD_WRAPPED(info, set_named_callback, nullptr);
+ SET_FIELD_WRAPPED(info, set_indexed_callback, nullptr);
+
+ if (data.IsEmpty()) {
+ data = v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+ }
+ info->set_data(*Utils::OpenHandle(*data));
+
+ cons->set_access_check_info(*info);
+ cons->set_needs_access_check(true);
+}
+
+
+void ObjectTemplate::SetAccessCheckCallbacks(
+ NamedSecurityCallback named_callback,
+ IndexedSecurityCallback indexed_callback, Local<Value> data) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ auto cons = EnsureConstructor(isolate, this);
+ EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetAccessCheckCallbacks");
+
+ i::Handle<i::Struct> struct_info =
+ isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE);
+ i::Handle<i::AccessCheckInfo> info =
+ i::Handle<i::AccessCheckInfo>::cast(struct_info);
+
+ SET_FIELD_WRAPPED(info, set_callback, nullptr);
SET_FIELD_WRAPPED(info, set_named_callback, named_callback);
SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback);
@@ -1391,11 +1475,8 @@
}
info->set_data(*Utils::OpenHandle(*data));
- i::FunctionTemplateInfo* constructor =
- i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor());
- i::Handle<i::FunctionTemplateInfo> cons(constructor);
cons->set_access_check_info(*info);
- cons->set_needs_access_check(turned_on_by_default);
+ cons->set_needs_access_check(true);
}
@@ -1404,12 +1485,11 @@
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EnsureConstructor(isolate, this);
- i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
- Utils::OpenHandle(this)->constructor());
- i::Handle<i::FunctionTemplateInfo> cons(constructor);
+ auto cons = EnsureConstructor(isolate, this);
+ EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetHandler");
auto obj = i::Handle<i::InterceptorInfo>::cast(
isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE));
+ obj->set_flags(0);
if (config.getter != 0) SET_FIELD_WRAPPED(obj, set_getter, config.getter);
if (config.setter != 0) SET_FIELD_WRAPPED(obj, set_setter, config.setter);
@@ -1418,7 +1498,6 @@
if (config.enumerator != 0) {
SET_FIELD_WRAPPED(obj, set_enumerator, config.enumerator);
}
- obj->set_flags(0);
obj->set_all_can_read(static_cast<int>(config.flags) &
static_cast<int>(PropertyHandlerFlags::kAllCanRead));
@@ -1432,14 +1511,12 @@
void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
- Handle<Value> data) {
+ Local<Value> data) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EnsureConstructor(isolate, this);
- i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
- Utils::OpenHandle(this)->constructor());
- i::Handle<i::FunctionTemplateInfo> cons(constructor);
+ auto cons = EnsureConstructor(isolate, this);
+ EnsureNotInstantiated(cons, "v8::ObjectTemplate::SetCallAsFunctionHandler");
i::Handle<i::Struct> struct_obj =
isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
i::Handle<i::CallHandlerInfo> obj =
@@ -1497,6 +1574,12 @@
}
+bool ScriptCompiler::ExternalSourceStream::SetBookmark() { return false; }
+
+
+void ScriptCompiler::ExternalSourceStream::ResetToBookmark() { UNREACHABLE(); }
+
+
ScriptCompiler::StreamedSource::StreamedSource(ExternalSourceStream* stream,
Encoding encoding)
: impl_(new i::StreamedSource(stream, encoding)) {}
@@ -1516,9 +1599,37 @@
i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
i::Handle<i::SharedFunctionInfo>
function_info(i::SharedFunctionInfo::cast(*obj), obj->GetIsolate());
+ i::Isolate* isolate = obj->GetIsolate();
+
+ i::ScopeInfo* scope_info = function_info->scope_info();
+ i::Handle<i::JSReceiver> global(isolate->native_context()->global_object());
+ for (int i = 0; i < scope_info->StrongModeFreeVariableCount(); ++i) {
+ i::Handle<i::String> name_string(scope_info->StrongModeFreeVariableName(i));
+ i::ScriptContextTable::LookupResult result;
+ i::Handle<i::ScriptContextTable> script_context_table(
+ isolate->native_context()->script_context_table());
+ if (!i::ScriptContextTable::Lookup(script_context_table, name_string,
+ &result)) {
+ i::Handle<i::Name> name(scope_info->StrongModeFreeVariableName(i));
+ Maybe<bool> has = i::JSReceiver::HasProperty(global, name);
+ if (has.IsJust() && !has.FromJust()) {
+ i::PendingCompilationErrorHandler pending_error_handler_;
+ pending_error_handler_.ReportMessageAt(
+ scope_info->StrongModeFreeVariableStartPosition(i),
+ scope_info->StrongModeFreeVariableEndPosition(i),
+ i::MessageTemplate::kStrongUnboundGlobal, name_string,
+ i::kReferenceError);
+ i::Handle<i::Script> script(i::Script::cast(function_info->script()));
+ pending_error_handler_.ThrowPendingError(isolate, script);
+ isolate->ReportPendingMessages();
+ isolate->OptionalRescheduleException(true);
+ return Local<Script>();
+ }
+ }
+ }
i::Handle<i::JSFunction> function =
obj->GetIsolate()->factory()->NewFunctionFromSharedFunctionInfo(
- function_info, obj->GetIsolate()->native_context());
+ function_info, isolate->native_context());
return ToApiHandle<Script>(function);
}
@@ -1527,15 +1638,12 @@
i::Handle<i::HeapObject> obj =
i::Handle<i::HeapObject>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- ON_BAILOUT(isolate, "v8::UnboundScript::GetId()", return -1);
LOG_API(isolate, "v8::UnboundScript::GetId");
- {
- i::HandleScope scope(isolate);
- i::Handle<i::SharedFunctionInfo> function_info(
- i::SharedFunctionInfo::cast(*obj));
- i::Handle<i::Script> script(i::Script::cast(function_info->script()));
- return script->id()->value();
- }
+ i::HandleScope scope(isolate);
+ i::Handle<i::SharedFunctionInfo> function_info(
+ i::SharedFunctionInfo::cast(*obj));
+ i::Handle<i::Script> script(i::Script::cast(function_info->script()));
+ return script->id();
}
@@ -1543,7 +1651,6 @@
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- ON_BAILOUT(isolate, "v8::UnboundScript::GetLineNumber()", return -1);
LOG_API(isolate, "UnboundScript::GetLineNumber");
if (obj->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(obj->script()));
@@ -1554,73 +1661,70 @@
}
-Handle<Value> UnboundScript::GetScriptName() {
+Local<Value> UnboundScript::GetScriptName() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- ON_BAILOUT(isolate, "v8::UnboundScript::GetName()",
- return Handle<String>());
LOG_API(isolate, "UnboundScript::GetName");
if (obj->script()->IsScript()) {
i::Object* name = i::Script::cast(obj->script())->name();
return Utils::ToLocal(i::Handle<i::Object>(name, isolate));
} else {
- return Handle<String>();
+ return Local<String>();
}
}
-Handle<Value> UnboundScript::GetSourceURL() {
+Local<Value> UnboundScript::GetSourceURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceURL()",
- return Handle<String>());
LOG_API(isolate, "UnboundScript::GetSourceURL");
if (obj->script()->IsScript()) {
i::Object* url = i::Script::cast(obj->script())->source_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
} else {
- return Handle<String>();
+ return Local<String>();
}
}
-Handle<Value> UnboundScript::GetSourceMappingURL() {
+Local<Value> UnboundScript::GetSourceMappingURL() {
i::Handle<i::SharedFunctionInfo> obj =
i::Handle<i::SharedFunctionInfo>::cast(Utils::OpenHandle(this));
i::Isolate* isolate = obj->GetIsolate();
- ON_BAILOUT(isolate, "v8::UnboundScript::GetSourceMappingURL()",
- return Handle<String>());
LOG_API(isolate, "UnboundScript::GetSourceMappingURL");
if (obj->script()->IsScript()) {
i::Object* url = i::Script::cast(obj->script())->source_mapping_url();
return Utils::ToLocal(i::Handle<i::Object>(url, isolate));
} else {
- return Handle<String>();
+ return Local<String>();
}
}
+MaybeLocal<Value> Script::Run(Local<Context> context) {
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Script::Run()", Value)
+ i::AggregatingHistogramTimerScope timer(isolate->counters()->compile_lazy());
+ i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
+ auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
+ i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
+ Local<Value> result;
+ has_pending_exception =
+ !ToLocal<Value>(i::Execution::Call(isolate, fun, receiver, 0, NULL),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
Local<Value> Script::Run() {
- i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
+ auto self = Utils::OpenHandle(this, true);
// If execution is terminating, Compile(..)->Run() requires this
// check.
- if (obj.is_null()) return Local<Value>();
- i::Isolate* isolate = i::Handle<i::HeapObject>::cast(obj)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Script::Run()", return Local<Value>());
- LOG_API(isolate, "Script::Run");
- ENTER_V8(isolate);
- i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> receiver(isolate->global_proxy(), isolate);
- i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(
- isolate, fun, receiver, 0, NULL).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
- return Utils::ToLocal(scope.CloseAndEscape(result));
+ if (self.is_null()) return Local<Value>();
+ auto context = ContextFromHeapObject(self);
+ RETURN_TO_LOCAL_UNCHECKED(Run(context), Value);
}
@@ -1631,22 +1735,12 @@
}
-Local<UnboundScript> ScriptCompiler::CompileUnbound(
- Isolate* v8_isolate,
- Source* source,
- CompileOptions options) {
+MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
+ Isolate* v8_isolate, Source* source, CompileOptions options,
+ bool is_module) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileUnbound()",
- return Local<UnboundScript>());
-
- // Support the old API for a transition period:
- // - kProduceToCache -> kProduceParserCache
- // - kNoCompileOptions + cached_data != NULL -> kConsumeParserCache
- if (options == kProduceDataToCache) {
- options = kProduceParserCache;
- } else if (options == kNoCompileOptions && source->cached_data) {
- options = kConsumeParserCache;
- }
+ PREPARE_FOR_EXECUTION_WITH_ISOLATE(
+ isolate, "v8::ScriptCompiler::CompileUnbound()", UnboundScript);
// Don't try to produce any kind of cache when the debugger is loaded.
if (isolate->debug()->is_loaded() &&
@@ -1663,14 +1757,13 @@
}
i::Handle<i::String> str = Utils::OpenHandle(*(source->source_string));
- LOG_API(isolate, "ScriptCompiler::CompileUnbound");
- ENTER_V8(isolate);
- i::SharedFunctionInfo* raw_result = NULL;
- { i::HandleScope scope(isolate);
+ i::Handle<i::SharedFunctionInfo> result;
+ {
+ i::HistogramTimerScope total(isolate->counters()->compile_script(), true);
i::Handle<i::Object> name_obj;
+ i::Handle<i::Object> source_map_url;
int line_offset = 0;
int column_offset = 0;
- bool is_shared_cross_origin = false;
if (!source->resource_name.IsEmpty()) {
name_obj = Utils::OpenHandle(*(source->resource_name));
}
@@ -1681,16 +1774,13 @@
column_offset =
static_cast<int>(source->resource_column_offset->Value());
}
- if (!source->resource_is_shared_cross_origin.IsEmpty()) {
- v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
- is_shared_cross_origin =
- source->resource_is_shared_cross_origin == v8::True(v8_isolate);
+ if (!source->source_map_url.IsEmpty()) {
+ source_map_url = Utils::OpenHandle(*(source->source_map_url));
}
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::SharedFunctionInfo> result = i::Compiler::CompileScript(
- str, name_obj, line_offset, column_offset, is_shared_cross_origin,
- isolate->native_context(), NULL, &script_data, options,
- i::NOT_NATIVES_CODE);
+ result = i::Compiler::CompileScript(
+ str, name_obj, line_offset, column_offset, source->resource_options,
+ source_map_url, isolate->native_context(), NULL, &script_data, options,
+ i::NOT_NATIVES_CODE, is_module);
has_pending_exception = result.is_null();
if (has_pending_exception && script_data != NULL) {
// This case won't happen during normal operation; we have compiled
@@ -1699,8 +1789,7 @@
delete script_data;
script_data = NULL;
}
- EXCEPTION_BAILOUT_CHECK(isolate, Local<UnboundScript>());
- raw_result = *result;
+ RETURN_ON_FAILED_EXECUTION(UnboundScript);
if ((options == kProduceParserCache || options == kProduceCodeCache) &&
script_data != NULL) {
@@ -1714,8 +1803,34 @@
}
delete script_data;
}
- i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
- return ToApiHandle<UnboundScript>(result);
+ RETURN_ESCAPED(ToApiHandle<UnboundScript>(result));
+}
+
+
+MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
+ Isolate* v8_isolate, Source* source, CompileOptions options) {
+ return CompileUnboundInternal(v8_isolate, source, options, false);
+}
+
+
+Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate,
+ Source* source,
+ CompileOptions options) {
+ RETURN_TO_LOCAL_UNCHECKED(
+ CompileUnboundInternal(v8_isolate, source, options, false),
+ UnboundScript);
+}
+
+
+MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
+ Source* source,
+ CompileOptions options) {
+ auto isolate = context->GetIsolate();
+ auto maybe = CompileUnboundInternal(isolate, source, options, false);
+ Local<UnboundScript> result;
+ if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
+ v8::Context::Scope scope(context);
+ return result->BindToCurrentContext();
}
@@ -1723,16 +1838,166 @@
Isolate* v8_isolate,
Source* source,
CompileOptions options) {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
- LOG_API(isolate, "ScriptCompiler::CompiletBound()");
- ENTER_V8(isolate);
- Local<UnboundScript> generic = CompileUnbound(v8_isolate, source, options);
- if (generic.IsEmpty()) return Local<Script>();
+ auto context = v8_isolate->GetCurrentContext();
+ RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, options), Script);
+}
+
+
+MaybeLocal<Script> ScriptCompiler::CompileModule(Local<Context> context,
+ Source* source,
+ CompileOptions options) {
+ CHECK(i::FLAG_harmony_modules);
+ auto isolate = context->GetIsolate();
+ auto maybe = CompileUnboundInternal(isolate, source, options, true);
+ Local<UnboundScript> generic;
+ if (!maybe.ToLocal(&generic)) return MaybeLocal<Script>();
+ v8::Context::Scope scope(context);
return generic->BindToCurrentContext();
}
+class IsIdentifierHelper {
+ public:
+ IsIdentifierHelper() : is_identifier_(false), first_char_(true) {}
+
+ bool Check(i::String* string) {
+ i::ConsString* cons_string = i::String::VisitFlat(this, string, 0);
+ if (cons_string == NULL) return is_identifier_;
+ // We don't support cons strings here.
+ return false;
+ }
+ void VisitOneByteString(const uint8_t* chars, int length) {
+ for (int i = 0; i < length; ++i) {
+ if (first_char_) {
+ first_char_ = false;
+ is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
+ } else {
+ is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
+ }
+ }
+ }
+ void VisitTwoByteString(const uint16_t* chars, int length) {
+ for (int i = 0; i < length; ++i) {
+ if (first_char_) {
+ first_char_ = false;
+ is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]);
+ } else {
+ is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]);
+ }
+ }
+ }
+
+ private:
+ bool is_identifier_;
+ bool first_char_;
+ i::UnicodeCache unicode_cache_;
+ DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper);
+};
+
+
+MaybeLocal<Function> ScriptCompiler::CompileFunctionInContext(
+ Local<Context> v8_context, Source* source, size_t arguments_count,
+ Local<String> arguments[], size_t context_extension_count,
+ Local<Object> context_extensions[]) {
+ PREPARE_FOR_EXECUTION(
+ v8_context, "v8::ScriptCompiler::CompileFunctionInContext()", Function);
+ i::Handle<i::String> source_string;
+ auto factory = isolate->factory();
+ if (arguments_count) {
+ source_string = factory->NewStringFromStaticChars("(function(");
+ for (size_t i = 0; i < arguments_count; ++i) {
+ IsIdentifierHelper helper;
+ if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) {
+ return Local<Function>();
+ }
+ has_pending_exception =
+ !factory->NewConsString(source_string,
+ Utils::OpenHandle(*arguments[i]))
+ .ToHandle(&source_string);
+ RETURN_ON_FAILED_EXECUTION(Function);
+ if (i + 1 == arguments_count) continue;
+ has_pending_exception =
+ !factory->NewConsString(source_string,
+ factory->LookupSingleCharacterStringFromCode(
+ ',')).ToHandle(&source_string);
+ RETURN_ON_FAILED_EXECUTION(Function);
+ }
+ auto brackets = factory->NewStringFromStaticChars("){");
+ has_pending_exception = !factory->NewConsString(source_string, brackets)
+ .ToHandle(&source_string);
+ RETURN_ON_FAILED_EXECUTION(Function);
+ } else {
+ source_string = factory->NewStringFromStaticChars("(function(){");
+ }
+
+ int scope_position = source_string->length();
+ has_pending_exception =
+ !factory->NewConsString(source_string,
+ Utils::OpenHandle(*source->source_string))
+ .ToHandle(&source_string);
+ RETURN_ON_FAILED_EXECUTION(Function);
+ // Include \n in case the source contains a line end comment.
+ auto brackets = factory->NewStringFromStaticChars("\n})");
+ has_pending_exception =
+ !factory->NewConsString(source_string, brackets).ToHandle(&source_string);
+ RETURN_ON_FAILED_EXECUTION(Function);
+
+ i::Handle<i::Context> context = Utils::OpenHandle(*v8_context);
+ i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(),
+ isolate);
+ for (size_t i = 0; i < context_extension_count; ++i) {
+ i::Handle<i::JSReceiver> extension =
+ Utils::OpenHandle(*context_extensions[i]);
+ if (!extension->IsJSObject()) return Local<Function>();
+ i::Handle<i::JSFunction> closure(context->closure(), isolate);
+ context = factory->NewWithContext(closure, context, extension);
+ }
+
+ i::Handle<i::Object> name_obj;
+ int line_offset = 0;
+ int column_offset = 0;
+ if (!source->resource_name.IsEmpty()) {
+ name_obj = Utils::OpenHandle(*(source->resource_name));
+ }
+ if (!source->resource_line_offset.IsEmpty()) {
+ line_offset = static_cast<int>(source->resource_line_offset->Value());
+ }
+ if (!source->resource_column_offset.IsEmpty()) {
+ column_offset = static_cast<int>(source->resource_column_offset->Value());
+ }
+ i::Handle<i::JSFunction> fun;
+ has_pending_exception = !i::Compiler::GetFunctionFromEval(
+ source_string, outer_info, context, i::SLOPPY,
+ i::ONLY_SINGLE_FUNCTION_LITERAL, line_offset,
+ column_offset - scope_position, name_obj,
+ source->resource_options).ToHandle(&fun);
+ if (has_pending_exception) {
+ isolate->ReportPendingMessages();
+ }
+ RETURN_ON_FAILED_EXECUTION(Function);
+
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Execution::Call(isolate, fun,
+ Utils::OpenHandle(*v8_context->Global()), 0,
+ nullptr).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Function);
+ RETURN_ESCAPED(
+ Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(result)));
+}
+
+
+Local<Function> ScriptCompiler::CompileFunctionInContext(
+ Isolate* v8_isolate, Source* source, Local<Context> v8_context,
+ size_t arguments_count, Local<String> arguments[],
+ size_t context_extension_count, Local<Object> context_extensions[]) {
+ RETURN_TO_LOCAL_UNCHECKED(
+ CompileFunctionInContext(v8_context, source, arguments_count, arguments,
+ context_extension_count, context_extensions),
+ Function);
+}
+
+
ScriptCompiler::ScriptStreamingTask* ScriptCompiler::StartStreamingScript(
Isolate* v8_isolate, StreamedSource* source, CompileOptions options) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
@@ -1741,68 +2006,67 @@
}
+MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
+ StreamedSource* v8_source,
+ Local<String> full_source_string,
+ const ScriptOrigin& origin) {
+ PREPARE_FOR_EXECUTION(context, "v8::ScriptCompiler::Compile()", Script);
+ i::StreamedSource* source = v8_source->impl();
+ i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
+ i::Handle<i::Script> script = isolate->factory()->NewScript(str);
+ if (!origin.ResourceName().IsEmpty()) {
+ script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
+ }
+ if (!origin.ResourceLineOffset().IsEmpty()) {
+ script->set_line_offset(
+ static_cast<int>(origin.ResourceLineOffset()->Value()));
+ }
+ if (!origin.ResourceColumnOffset().IsEmpty()) {
+ script->set_column_offset(
+ static_cast<int>(origin.ResourceColumnOffset()->Value()));
+ }
+ script->set_origin_options(origin.Options());
+ if (!origin.SourceMapUrl().IsEmpty()) {
+ script->set_source_mapping_url(
+ *Utils::OpenHandle(*(origin.SourceMapUrl())));
+ }
+
+ source->info->set_script(script);
+ source->info->set_context(isolate->native_context());
+
+ // Do the parsing tasks which need to be done on the main thread. This will
+ // also handle parse errors.
+ source->parser->Internalize(isolate, script,
+ source->info->literal() == nullptr);
+ source->parser->HandleSourceURLComments(isolate, script);
+
+ i::Handle<i::SharedFunctionInfo> result;
+ if (source->info->literal() != nullptr) {
+ // Parsing has succeeded.
+ result = i::Compiler::CompileStreamedScript(script, source->info.get(),
+ str->length());
+ }
+ has_pending_exception = result.is_null();
+ if (has_pending_exception) isolate->ReportPendingMessages();
+ RETURN_ON_FAILED_EXECUTION(Script);
+
+ source->info->clear_script(); // because script goes out of scope.
+
+ Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
+ if (generic.IsEmpty()) return Local<Script>();
+ Local<Script> bound = generic->BindToCurrentContext();
+ if (bound.IsEmpty()) return Local<Script>();
+ RETURN_ESCAPED(bound);
+}
+
+
Local<Script> ScriptCompiler::Compile(Isolate* v8_isolate,
StreamedSource* v8_source,
- Handle<String> full_source_string,
+ Local<String> full_source_string,
const ScriptOrigin& origin) {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- i::StreamedSource* source = v8_source->impl();
- ON_BAILOUT(isolate, "v8::ScriptCompiler::Compile()", return Local<Script>());
- LOG_API(isolate, "ScriptCompiler::Compile()");
- ENTER_V8(isolate);
- i::SharedFunctionInfo* raw_result = NULL;
-
- {
- i::HandleScope scope(isolate);
- i::Handle<i::String> str = Utils::OpenHandle(*(full_source_string));
- i::Handle<i::Script> script = isolate->factory()->NewScript(str);
- if (!origin.ResourceName().IsEmpty()) {
- script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
- }
- if (!origin.ResourceLineOffset().IsEmpty()) {
- script->set_line_offset(i::Smi::FromInt(
- static_cast<int>(origin.ResourceLineOffset()->Value())));
- }
- if (!origin.ResourceColumnOffset().IsEmpty()) {
- script->set_column_offset(i::Smi::FromInt(
- static_cast<int>(origin.ResourceColumnOffset()->Value())));
- }
- if (!origin.ResourceIsSharedCrossOrigin().IsEmpty()) {
- script->set_is_shared_cross_origin(origin.ResourceIsSharedCrossOrigin() ==
- v8::True(v8_isolate));
- }
- source->info->set_script(script);
- source->info->SetContext(isolate->native_context());
-
- EXCEPTION_PREAMBLE(isolate);
-
- // Do the parsing tasks which need to be done on the main thread. This will
- // also handle parse errors.
- source->parser->Internalize();
- source->parser->HandleSourceURLComments();
-
- i::Handle<i::SharedFunctionInfo> result =
- i::Handle<i::SharedFunctionInfo>::null();
- if (source->info->function() != NULL) {
- // Parsing has succeeded.
- result =
- i::Compiler::CompileStreamedScript(source->info.get(), str->length());
- }
- has_pending_exception = result.is_null();
- if (has_pending_exception) isolate->ReportPendingMessages();
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Script>());
-
- raw_result = *result;
- // The Handle<Script> will go out of scope soon; make sure CompilationInfo
- // doesn't point to it.
- source->info->set_script(i::Handle<i::Script>());
- } // HandleScope goes out of scope.
- i::Handle<i::SharedFunctionInfo> result(raw_result, isolate);
- Local<UnboundScript> generic = ToApiHandle<UnboundScript>(result);
- if (generic.IsEmpty()) {
- return Local<Script>();
- }
- return generic->BindToCurrentContext();
+ auto context = v8_isolate->GetCurrentContext();
+ RETURN_TO_LOCAL_UNCHECKED(
+ Compile(context, v8_source, full_source_string, origin), Script);
}
@@ -1813,26 +2077,31 @@
}
-Local<Script> Script::Compile(v8::Handle<String> source,
- v8::ScriptOrigin* origin) {
- i::Handle<i::String> str = Utils::OpenHandle(*source);
+MaybeLocal<Script> Script::Compile(Local<Context> context, Local<String> source,
+ ScriptOrigin* origin) {
if (origin) {
ScriptCompiler::Source script_source(source, *origin);
- return ScriptCompiler::Compile(
- reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
- &script_source);
+ return ScriptCompiler::Compile(context, &script_source);
}
ScriptCompiler::Source script_source(source);
- return ScriptCompiler::Compile(
- reinterpret_cast<v8::Isolate*>(str->GetIsolate()),
- &script_source);
+ return ScriptCompiler::Compile(context, &script_source);
}
-Local<Script> Script::Compile(v8::Handle<String> source,
- v8::Handle<String> file_name) {
+Local<Script> Script::Compile(v8::Local<String> source,
+ v8::ScriptOrigin* origin) {
+ auto str = Utils::OpenHandle(*source);
+ auto context = ContextFromHeapObject(str);
+ RETURN_TO_LOCAL_UNCHECKED(Compile(context, source, origin), Script);
+}
+
+
+Local<Script> Script::Compile(v8::Local<String> source,
+ v8::Local<String> file_name) {
+ auto str = Utils::OpenHandle(*source);
+ auto context = ContextFromHeapObject(str);
ScriptOrigin origin(file_name);
- return Compile(source, &origin);
+ return Compile(context, source, &origin).FromMaybe(Local<Script>());
}
@@ -1851,7 +2120,7 @@
// Special handling for simulators which have a separate JS stack.
js_stack_comparable_address_ =
reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
- v8::internal::GetCurrentStackPosition()));
+ isolate_, v8::internal::GetCurrentStackPosition()));
isolate_->RegisterTryCatchHandler(this);
}
@@ -1868,7 +2137,7 @@
// Special handling for simulators which have a separate JS stack.
js_stack_comparable_address_ =
reinterpret_cast<void*>(v8::internal::SimulatorStack::RegisterCTryCatch(
- v8::internal::GetCurrentStackPosition()));
+ isolate_, v8::internal::GetCurrentStackPosition()));
isolate_->RegisterTryCatchHandler(this);
}
@@ -1881,13 +2150,13 @@
if (HasCaught() && capture_message_) {
// If an exception was caught and rethrow_ is indicated, the saved
// message, script, and location need to be restored to Isolate TLS
- // for reuse. capture_message_ needs to be disabled so that DoThrow()
+ // for reuse. capture_message_ needs to be disabled so that Throw()
// does not create a new message.
isolate_->thread_local_top()->rethrowing_message_ = true;
isolate_->RestorePendingMessageFromTryCatch(this);
}
isolate_->UnregisterTryCatchHandler(this);
- v8::internal::SimulatorStack::UnregisterCTryCatch();
+ v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_);
reinterpret_cast<Isolate*>(isolate_)->ThrowException(exc);
DCHECK(!isolate_->thread_local_top()->rethrowing_message_);
} else {
@@ -1898,7 +2167,7 @@
isolate_->CancelScheduledExceptionFromTryCatch(this);
}
isolate_->UnregisterTryCatchHandler(this);
- v8::internal::SimulatorStack::UnregisterCTryCatch();
+ v8::internal::SimulatorStack::UnregisterCTryCatch(isolate_);
}
}
@@ -1918,7 +2187,7 @@
}
-v8::Handle<v8::Value> v8::TryCatch::ReThrow() {
+v8::Local<v8::Value> v8::TryCatch::ReThrow() {
if (!HasCaught()) return v8::Local<v8::Value>();
rethrow_ = true;
return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate_));
@@ -1936,26 +2205,28 @@
}
+MaybeLocal<Value> v8::TryCatch::StackTrace(Local<Context> context) const {
+ if (!HasCaught()) return v8::Local<Value>();
+ i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
+ if (!raw_obj->IsJSObject()) return v8::Local<Value>();
+ PREPARE_FOR_EXECUTION(context, "v8::TryCatch::StackTrace", Value);
+ i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
+ i::Handle<i::String> name = isolate->factory()->stack_string();
+ Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
+ has_pending_exception = !maybe.IsJust();
+ RETURN_ON_FAILED_EXECUTION(Value);
+ if (!maybe.FromJust()) return v8::Local<Value>();
+ Local<Value> result;
+ has_pending_exception =
+ !ToLocal<Value>(i::Object::GetProperty(obj, name), &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
v8::Local<Value> v8::TryCatch::StackTrace() const {
- if (HasCaught()) {
- i::Object* raw_obj = reinterpret_cast<i::Object*>(exception_);
- if (!raw_obj->IsJSObject()) return v8::Local<Value>();
- i::HandleScope scope(isolate_);
- i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
- i::Handle<i::String> name = isolate_->factory()->stack_string();
- EXCEPTION_PREAMBLE(isolate_);
- Maybe<bool> maybe = i::JSReceiver::HasProperty(obj, name);
- has_pending_exception = !maybe.has_value;
- EXCEPTION_BAILOUT_CHECK(isolate_, v8::Local<Value>());
- if (!maybe.value) return v8::Local<Value>();
- i::Handle<i::Object> value;
- if (!i::Object::GetProperty(obj, name).ToHandle(&value)) {
- return v8::Local<Value>();
- }
- return v8::Utils::ToLocal(scope.CloseAndEscape(value));
- } else {
- return v8::Local<Value>();
- }
+ auto context = reinterpret_cast<v8::Isolate*>(isolate_)->GetCurrentContext();
+ RETURN_TO_LOCAL_UNCHECKED(StackTrace(context), Value);
}
@@ -1985,9 +2256,6 @@
i::Object* the_hole = isolate_->heap()->the_hole_value();
exception_ = the_hole;
message_obj_ = the_hole;
- message_script_ = the_hole;
- message_start_pos_ = 0;
- message_end_pos_ = 0;
}
@@ -2006,7 +2274,6 @@
Local<String> Message::Get() const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Message::Get()", return Local<String>());
ENTER_V8(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
i::Handle<i::Object> obj = Utils::OpenHandle(this);
@@ -2018,165 +2285,151 @@
ScriptOrigin Message::GetScriptOrigin() const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- i::Handle<i::JSMessageObject> message =
- i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
- i::Handle<i::Object> script_wraper =
- i::Handle<i::Object>(message->script(), isolate);
- i::Handle<i::JSValue> script_value =
- i::Handle<i::JSValue>::cast(script_wraper);
+ auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
+ auto script_wraper = i::Handle<i::Object>(message->script(), isolate);
+ auto script_value = i::Handle<i::JSValue>::cast(script_wraper);
i::Handle<i::Script> script(i::Script::cast(script_value->value()));
- i::Handle<i::Object> scriptName(i::Script::GetNameOrSourceURL(script));
- v8::Isolate* v8_isolate =
- reinterpret_cast<v8::Isolate*>(script->GetIsolate());
- v8::ScriptOrigin origin(
- Utils::ToLocal(scriptName),
- v8::Integer::New(v8_isolate, script->line_offset()->value()),
- v8::Integer::New(v8_isolate, script->column_offset()->value()),
- Handle<Boolean>(),
- v8::Integer::New(v8_isolate, script->id()->value()));
- return origin;
+ return GetScriptOriginForScript(isolate, script);
}
-v8::Handle<Value> Message::GetScriptResourceName() const {
+v8::Local<Value> Message::GetScriptResourceName() const {
return GetScriptOrigin().ResourceName();
}
-v8::Handle<v8::StackTrace> Message::GetStackTrace() const {
+v8::Local<v8::StackTrace> Message::GetStackTrace() const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
- i::Handle<i::JSMessageObject> message =
- i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
+ auto message = i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
i::Handle<i::Object> stackFramesObj(message->stack_frames(), isolate);
- if (!stackFramesObj->IsJSArray()) return v8::Handle<v8::StackTrace>();
- i::Handle<i::JSArray> stackTrace =
- i::Handle<i::JSArray>::cast(stackFramesObj);
+ if (!stackFramesObj->IsJSArray()) return v8::Local<v8::StackTrace>();
+ auto stackTrace = i::Handle<i::JSArray>::cast(stackFramesObj);
return scope.Escape(Utils::StackTraceToLocal(stackTrace));
}
-MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
- i::Isolate* isolate, const char* name, i::Handle<i::Object> recv, int argc,
- i::Handle<i::Object> argv[]) {
- i::Handle<i::Object> object_fun =
- i::Object::GetProperty(
- isolate, isolate->js_builtins_object(), name).ToHandleChecked();
- i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(object_fun);
- return i::Execution::Call(isolate, fun, recv, argc, argv);
-}
-
-
-MUST_USE_RESULT static i::MaybeHandle<i::Object> CallV8HeapFunction(
- i::Isolate* isolate, const char* name, i::Handle<i::Object> data) {
- i::Handle<i::Object> argv[] = { data };
- return CallV8HeapFunction(isolate, name, isolate->js_builtins_object(),
- arraysize(argv), argv);
+Maybe<int> Message::GetLineNumber(Local<Context> context) const {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetLineNumber()", int);
+ i::Handle<i::JSFunction> fun = isolate->message_get_line_number();
+ i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
+ i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
+ return Just(static_cast<int>(result->Number()));
}
int Message::GetLineNumber() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Message::GetLineNumber()", return kNoLineNumberInfo);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
-
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result;
- has_pending_exception =
- !CallV8HeapFunction(isolate, "GetLineNumber", Utils::OpenHandle(this))
- .ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, 0);
- return static_cast<int>(result->Number());
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return GetLineNumber(context).FromMaybe(0);
}
int Message::GetStartPosition() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSMessageObject> message =
- i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
- return message->start_position();
+ auto self = Utils::OpenHandle(this);
+ return self->start_position();
}
int Message::GetEndPosition() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSMessageObject> message =
- i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
- return message->end_position();
+ auto self = Utils::OpenHandle(this);
+ return self->end_position();
+}
+
+
+Maybe<int> Message::GetStartColumn(Local<Context> context) const {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetStartColumn()",
+ int);
+ i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
+ i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
+ i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
+ return Just(static_cast<int>(result->Number()));
}
int Message::GetStartColumn() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Message::GetStartColumn()", return kNoColumnInfo);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> start_col_obj;
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ const int default_value = kNoColumnInfo;
+ return GetStartColumn(context).FromMaybe(default_value);
+}
+
+
+Maybe<int> Message::GetEndColumn(Local<Context> context) const {
+ auto self = Utils::OpenHandle(this);
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetEndColumn()", int);
+ i::Handle<i::JSFunction> fun = isolate->message_get_column_number();
+ i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
+ i::Handle<i::Object> args[] = {self};
+ i::Handle<i::Object> result;
has_pending_exception =
- !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
- .ToHandle(&start_col_obj);
- EXCEPTION_BAILOUT_CHECK(isolate, 0);
- return static_cast<int>(start_col_obj->Number());
+ !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int);
+ int start = self->start_position();
+ int end = self->end_position();
+ return Just(static_cast<int>(result->Number()) + (end - start));
}
int Message::GetEndColumn() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Message::GetEndColumn()", return kNoColumnInfo);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> data_obj = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> start_col_obj;
- has_pending_exception =
- !CallV8HeapFunction(isolate, "GetPositionInLine", data_obj)
- .ToHandle(&start_col_obj);
- EXCEPTION_BAILOUT_CHECK(isolate, 0);
- i::Handle<i::JSMessageObject> message =
- i::Handle<i::JSMessageObject>::cast(data_obj);
- int start = message->start_position();
- int end = message->end_position();
- return static_cast<int>(start_col_obj->Number()) + (end - start);
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ const int default_value = kNoColumnInfo;
+ return GetEndColumn(context).FromMaybe(default_value);
}
bool Message::IsSharedCrossOrigin() const {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSMessageObject> message =
- i::Handle<i::JSMessageObject>::cast(Utils::OpenHandle(this));
- i::Handle<i::JSValue> script =
- i::Handle<i::JSValue>::cast(i::Handle<i::Object>(message->script(),
- isolate));
- return i::Script::cast(script->value())->is_shared_cross_origin();
+ auto self = Utils::OpenHandle(this);
+ auto script = i::Handle<i::JSValue>::cast(
+ i::Handle<i::Object>(self->script(), isolate));
+ return i::Script::cast(script->value())
+ ->origin_options()
+ .IsSharedCrossOrigin();
+}
+
+bool Message::IsOpaque() const {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ENTER_V8(isolate);
+ auto self = Utils::OpenHandle(this);
+ auto script = i::Handle<i::JSValue>::cast(
+ i::Handle<i::Object>(self->script(), isolate));
+ return i::Script::cast(script->value())->origin_options().IsOpaque();
+}
+
+
+MaybeLocal<String> Message::GetSourceLine(Local<Context> context) const {
+ PREPARE_FOR_EXECUTION(context, "v8::Message::GetSourceLine()", String);
+ i::Handle<i::JSFunction> fun = isolate->message_get_source_line();
+ i::Handle<i::Object> undefined = isolate->factory()->undefined_value();
+ i::Handle<i::Object> args[] = {Utils::OpenHandle(this)};
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Execution::Call(isolate, fun, undefined, arraysize(args), args)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(String);
+ Local<String> str;
+ if (result->IsString()) {
+ str = Utils::ToLocal(i::Handle<i::String>::cast(result));
+ }
+ RETURN_ESCAPED(str);
}
Local<String> Message::GetSourceLine() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Message::GetSourceLine()", return Local<String>());
- ENTER_V8(isolate);
- EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result;
- has_pending_exception =
- !CallV8HeapFunction(isolate, "GetSourceLine", Utils::OpenHandle(this))
- .ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::String>());
- if (result->IsString()) {
- return scope.Escape(Utils::ToLocal(i::Handle<i::String>::cast(result)));
- } else {
- return Local<String>();
- }
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(GetSourceLine(context), String)
}
@@ -2193,24 +2446,19 @@
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
ENTER_V8(isolate);
EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
- i::Handle<i::JSArray> self = Utils::OpenHandle(this);
- i::Handle<i::Object> obj =
- i::Object::GetElement(isolate, self, index).ToHandleChecked();
- i::Handle<i::JSObject> jsobj = i::Handle<i::JSObject>::cast(obj);
+ auto self = Utils::OpenHandle(this);
+ auto obj = i::Object::GetElement(isolate, self, index).ToHandleChecked();
+ auto jsobj = i::Handle<i::JSObject>::cast(obj);
return scope.Escape(Utils::StackFrameToLocal(jsobj));
}
int StackTrace::GetFrameCount() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
return i::Smi::cast(Utils::OpenHandle(this)->length())->value();
}
Local<Array> StackTrace::AsArray() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
return Utils::ToLocal(Utils::OpenHandle(this));
}
@@ -2306,23 +2554,124 @@
}
-// --- J S O N ---
+// --- N a t i v e W e a k M a p ---
-Local<Value> JSON::Parse(Local<String> json_string) {
- i::Handle<i::String> string = Utils::OpenHandle(*json_string);
- i::Isolate* isolate = string->GetIsolate();
+Local<NativeWeakMap> NativeWeakMap::New(Isolate* v8_isolate) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+ ENTER_V8(isolate);
+ i::Handle<i::JSWeakMap> weakmap = isolate->factory()->NewJSWeakMap();
+ i::JSWeakCollection::Initialize(weakmap, isolate);
+ return Utils::NativeWeakMapToLocal(weakmap);
+}
+
+
+void NativeWeakMap::Set(Local<Value> v8_key, Local<Value> v8_value) {
+ i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
+ i::Isolate* isolate = weak_collection->GetIsolate();
ENTER_V8(isolate);
i::HandleScope scope(isolate);
+ i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
+ i::Handle<i::Object> value = Utils::OpenHandle(*v8_value);
+ if (!key->IsJSReceiver() && !key->IsSymbol()) {
+ DCHECK(false);
+ return;
+ }
+ i::Handle<i::ObjectHashTable> table(
+ i::ObjectHashTable::cast(weak_collection->table()));
+ if (!table->IsKey(*key)) {
+ DCHECK(false);
+ return;
+ }
+ int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
+ i::JSWeakCollection::Set(weak_collection, key, value, hash);
+}
+
+
+Local<Value> NativeWeakMap::Get(Local<Value> v8_key) {
+ i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
+ i::Isolate* isolate = weak_collection->GetIsolate();
+ ENTER_V8(isolate);
+ i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
+ if (!key->IsJSReceiver() && !key->IsSymbol()) {
+ DCHECK(false);
+ return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+ }
+ i::Handle<i::ObjectHashTable> table(
+ i::ObjectHashTable::cast(weak_collection->table()));
+ if (!table->IsKey(*key)) {
+ DCHECK(false);
+ return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+ }
+ i::Handle<i::Object> lookup(table->Lookup(key), isolate);
+ if (lookup->IsTheHole())
+ return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+ return Utils::ToLocal(lookup);
+}
+
+
+bool NativeWeakMap::Has(Local<Value> v8_key) {
+ i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
+ i::Isolate* isolate = weak_collection->GetIsolate();
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
+ if (!key->IsJSReceiver() && !key->IsSymbol()) {
+ DCHECK(false);
+ return false;
+ }
+ i::Handle<i::ObjectHashTable> table(
+ i::ObjectHashTable::cast(weak_collection->table()));
+ if (!table->IsKey(*key)) {
+ DCHECK(false);
+ return false;
+ }
+ i::Handle<i::Object> lookup(table->Lookup(key), isolate);
+ return !lookup->IsTheHole();
+}
+
+
+bool NativeWeakMap::Delete(Local<Value> v8_key) {
+ i::Handle<i::JSWeakMap> weak_collection = Utils::OpenHandle(this);
+ i::Isolate* isolate = weak_collection->GetIsolate();
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ i::Handle<i::Object> key = Utils::OpenHandle(*v8_key);
+ if (!key->IsJSReceiver() && !key->IsSymbol()) {
+ DCHECK(false);
+ return false;
+ }
+ i::Handle<i::ObjectHashTable> table(
+ i::ObjectHashTable::cast(weak_collection->table()));
+ if (!table->IsKey(*key)) {
+ DCHECK(false);
+ return false;
+ }
+ int32_t hash = i::Object::GetOrCreateHash(isolate, key)->value();
+ return i::JSWeakCollection::Delete(weak_collection, key, hash);
+}
+
+
+// --- J S O N ---
+
+MaybeLocal<Value> JSON::Parse(Isolate* v8_isolate, Local<String> json_string) {
+ auto isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+ PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, "JSON::Parse", Value);
+ i::Handle<i::String> string = Utils::OpenHandle(*json_string);
i::Handle<i::String> source = i::String::Flatten(string);
- EXCEPTION_PREAMBLE(isolate);
- i::MaybeHandle<i::Object> maybe_result =
- source->IsSeqOneByteString() ? i::JsonParser<true>::Parse(source)
- : i::JsonParser<false>::Parse(source);
- i::Handle<i::Object> result;
- has_pending_exception = !maybe_result.ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
- return Utils::ToLocal(
- i::Handle<i::Object>::cast(scope.CloseAndEscape(result)));
+ auto maybe = source->IsSeqOneByteString()
+ ? i::JsonParser<true>::Parse(source)
+ : i::JsonParser<false>::Parse(source);
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(maybe, &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<Value> JSON::Parse(Local<String> json_string) {
+ auto isolate = reinterpret_cast<v8::Isolate*>(
+ Utils::OpenHandle(*json_string)->GetIsolate());
+ RETURN_TO_LOCAL_UNCHECKED(Parse(isolate, json_string), Value);
}
@@ -2352,9 +2701,7 @@
}
-bool Value::IsFunction() const {
- return Utils::OpenHandle(this)->IsJSFunction();
-}
+bool Value::IsFunction() const { return Utils::OpenHandle(this)->IsCallable(); }
bool Value::IsName() const {
@@ -2380,7 +2727,8 @@
bool Value::IsArrayBuffer() const {
- return Utils::OpenHandle(this)->IsJSArrayBuffer();
+ i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ return obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared();
}
@@ -2394,13 +2742,14 @@
}
-#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
- bool Value::Is##Type##Array() const { \
- i::Handle<i::Object> obj = Utils::OpenHandle(this); \
- return obj->IsJSTypedArray() && \
- i::JSTypedArray::cast(*obj)->type() == kExternal##Type##Array; \
+#define VALUE_IS_TYPED_ARRAY(Type, typeName, TYPE, ctype, size) \
+ bool Value::Is##Type##Array() const { \
+ i::Handle<i::Object> obj = Utils::OpenHandle(this); \
+ return obj->IsJSTypedArray() && \
+ i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array; \
}
+
TYPED_ARRAYS(VALUE_IS_TYPED_ARRAY)
#undef VALUE_IS_TYPED_ARRAY
@@ -2411,16 +2760,23 @@
}
-bool Value::IsObject() const {
- return Utils::OpenHandle(this)->IsJSObject();
+bool Value::IsSharedArrayBuffer() const {
+ i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ return obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared();
}
+bool Value::IsObject() const { return Utils::OpenHandle(this)->IsJSReceiver(); }
+
+
bool Value::IsNumber() const {
return Utils::OpenHandle(this)->IsNumber();
}
+bool Value::IsProxy() const { return Utils::OpenHandle(this)->IsJSProxy(); }
+
+
#define VALUE_IS_SPECIFIC_TYPE(Type, Class) \
bool Value::Is##Type() const { \
i::Handle<i::Object> obj = Utils::OpenHandle(this); \
@@ -2477,34 +2833,23 @@
}
-static bool CheckConstructor(i::Isolate* isolate,
- i::Handle<i::JSObject> obj,
- const char* class_name) {
- i::Handle<i::Object> constr(obj->map()->constructor(), isolate);
- if (!constr->IsJSFunction()) return false;
- i::Handle<i::JSFunction> func = i::Handle<i::JSFunction>::cast(constr);
- return func->shared()->native() && constr.is_identical_to(
- i::Object::GetProperty(isolate,
- isolate->js_builtins_object(),
- class_name).ToHandleChecked());
-}
-
-
bool Value::IsNativeError() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
- if (obj->IsJSObject()) {
- i::Handle<i::JSObject> js_obj(i::JSObject::cast(*obj));
- i::Isolate* isolate = js_obj->GetIsolate();
- return CheckConstructor(isolate, js_obj, "$Error") ||
- CheckConstructor(isolate, js_obj, "$EvalError") ||
- CheckConstructor(isolate, js_obj, "$RangeError") ||
- CheckConstructor(isolate, js_obj, "$ReferenceError") ||
- CheckConstructor(isolate, js_obj, "$SyntaxError") ||
- CheckConstructor(isolate, js_obj, "$TypeError") ||
- CheckConstructor(isolate, js_obj, "$URIError");
- } else {
- return false;
- }
+ if (!obj->IsJSObject()) return false;
+ i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
+ i::Isolate* isolate = js_obj->GetIsolate();
+ i::Handle<i::Object> constructor(js_obj->map()->GetConstructor(), isolate);
+ if (!constructor->IsJSFunction()) return false;
+ i::Handle<i::JSFunction> function =
+ i::Handle<i::JSFunction>::cast(constructor);
+ if (!function->shared()->native()) return false;
+ return function.is_identical_to(isolate->error_function()) ||
+ function.is_identical_to(isolate->eval_error_function()) ||
+ function.is_identical_to(isolate->range_error_function()) ||
+ function.is_identical_to(isolate->reference_error_function()) ||
+ function.is_identical_to(isolate->syntax_error_function()) ||
+ function.is_identical_to(isolate->type_error_function()) ||
+ function.is_identical_to(isolate->uri_error_function());
}
@@ -2537,108 +2882,146 @@
}
-Local<String> Value::ToString(Isolate* v8_isolate) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> str;
- if (obj->IsString()) {
- str = obj;
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToString");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToString(
- isolate, obj).ToHandle(&str);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
- }
- return ToApiHandle<String>(str);
+bool Value::IsPromise() const {
+ auto self = Utils::OpenHandle(this);
+ return i::Object::IsPromise(self);
}
-Local<String> Value::ToDetailString(Isolate* v8_isolate) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> str;
- if (obj->IsString()) {
- str = obj;
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToDetailString");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToDetailString(
- isolate, obj).ToHandle(&str);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<String>());
- }
- return ToApiHandle<String>(str);
+MaybeLocal<String> Value::ToString(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsString()) return ToApiHandle<String>(obj);
+ PREPARE_FOR_EXECUTION(context, "ToString", String);
+ Local<String> result;
+ has_pending_exception =
+ !ToLocal<String>(i::Object::ToString(isolate, obj), &result);
+ RETURN_ON_FAILED_EXECUTION(String);
+ RETURN_ESCAPED(result);
}
-Local<v8::Object> Value::ToObject(Isolate* v8_isolate) const {
+Local<String> Value::ToString(Isolate* isolate) const {
+ RETURN_TO_LOCAL_UNCHECKED(ToString(isolate->GetCurrentContext()), String);
+}
+
+
+MaybeLocal<String> Value::ToDetailString(Local<Context> context) const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> val;
- if (obj->IsJSObject()) {
- val = obj;
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToObject");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToObject(
- isolate, obj).ToHandle(&val);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
- }
- return ToApiHandle<Object>(val);
+ if (obj->IsString()) return ToApiHandle<String>(obj);
+ PREPARE_FOR_EXECUTION(context, "ToDetailString", String);
+ Local<String> result;
+ i::Handle<i::Object> args[] = {obj};
+ has_pending_exception = !ToLocal<String>(
+ i::Execution::TryCall(isolate, isolate->no_side_effects_to_string_fun(),
+ isolate->factory()->undefined_value(),
+ arraysize(args), args),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(String);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<String> Value::ToDetailString(Isolate* isolate) const {
+ RETURN_TO_LOCAL_UNCHECKED(ToDetailString(isolate->GetCurrentContext()),
+ String);
+}
+
+
+MaybeLocal<Object> Value::ToObject(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsJSObject()) return ToApiHandle<Object>(obj);
+ PREPARE_FOR_EXECUTION(context, "ToObject", Object);
+ Local<Object> result;
+ has_pending_exception =
+ !ToLocal<Object>(i::Execution::ToObject(isolate, obj), &result);
+ RETURN_ON_FAILED_EXECUTION(Object);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<v8::Object> Value::ToObject(Isolate* isolate) const {
+ RETURN_TO_LOCAL_UNCHECKED(ToObject(isolate->GetCurrentContext()), Object);
+}
+
+
+MaybeLocal<Boolean> Value::ToBoolean(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsBoolean()) return ToApiHandle<Boolean>(obj);
+ auto isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
+ auto val = isolate->factory()->ToBoolean(obj->BooleanValue());
+ return ToApiHandle<Boolean>(val);
}
Local<Boolean> Value::ToBoolean(Isolate* v8_isolate) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- if (obj->IsBoolean()) {
- return ToApiHandle<Boolean>(obj);
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToBoolean");
- ENTER_V8(isolate);
- i::Handle<i::Object> val =
- isolate->factory()->ToBoolean(obj->BooleanValue());
- return ToApiHandle<Boolean>(val);
- }
+ return ToBoolean(v8_isolate->GetCurrentContext()).ToLocalChecked();
}
-Local<Number> Value::ToNumber(Isolate* v8_isolate) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> num;
- if (obj->IsNumber()) {
- num = obj;
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToNumber");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToNumber(
- isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Number>());
- }
- return ToApiHandle<Number>(num);
+MaybeLocal<Number> Value::ToNumber(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsNumber()) return ToApiHandle<Number>(obj);
+ PREPARE_FOR_EXECUTION(context, "ToNumber", Number);
+ Local<Number> result;
+ has_pending_exception = !ToLocal<Number>(i::Object::ToNumber(obj), &result);
+ RETURN_ON_FAILED_EXECUTION(Number);
+ RETURN_ESCAPED(result);
}
-Local<Integer> Value::ToInteger(Isolate* v8_isolate) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> num;
- if (obj->IsSmi()) {
- num = obj;
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToInteger");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToInteger(
- isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Integer>());
- }
- return ToApiHandle<Integer>(num);
+Local<Number> Value::ToNumber(Isolate* isolate) const {
+ RETURN_TO_LOCAL_UNCHECKED(ToNumber(isolate->GetCurrentContext()), Number);
+}
+
+
+MaybeLocal<Integer> Value::ToInteger(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsSmi()) return ToApiHandle<Integer>(obj);
+ PREPARE_FOR_EXECUTION(context, "ToInteger", Integer);
+ Local<Integer> result;
+ has_pending_exception =
+ !ToLocal<Integer>(i::Object::ToInteger(isolate, obj), &result);
+ RETURN_ON_FAILED_EXECUTION(Integer);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<Integer> Value::ToInteger(Isolate* isolate) const {
+ RETURN_TO_LOCAL_UNCHECKED(ToInteger(isolate->GetCurrentContext()), Integer);
+}
+
+
+MaybeLocal<Int32> Value::ToInt32(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsSmi()) return ToApiHandle<Int32>(obj);
+ Local<Int32> result;
+ PREPARE_FOR_EXECUTION(context, "ToInt32", Int32);
+ has_pending_exception =
+ !ToLocal<Int32>(i::Object::ToInt32(isolate, obj), &result);
+ RETURN_ON_FAILED_EXECUTION(Int32);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<Int32> Value::ToInt32(Isolate* isolate) const {
+ RETURN_TO_LOCAL_UNCHECKED(ToInt32(isolate->GetCurrentContext()), Int32);
+}
+
+
+MaybeLocal<Uint32> Value::ToUint32(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsSmi()) return ToApiHandle<Uint32>(obj);
+ Local<Uint32> result;
+ PREPARE_FOR_EXECUTION(context, "ToUint32", Uint32);
+ has_pending_exception =
+ !ToLocal<Uint32>(i::Object::ToUint32(isolate, obj), &result);
+ RETURN_ON_FAILED_EXECUTION(Uint32);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<Uint32> Value::ToUint32(Isolate* isolate) const {
+ RETURN_TO_LOCAL_UNCHECKED(ToUint32(isolate->GetCurrentContext()), Uint32);
}
@@ -2660,20 +3043,26 @@
void v8::Object::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsJSObject(),
- "v8::Object::Cast()",
+ Utils::ApiCheck(obj->IsJSReceiver(), "v8::Object::Cast()",
"Could not convert to object");
}
void v8::Function::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsJSFunction(),
- "v8::Function::Cast()",
+ Utils::ApiCheck(obj->IsCallable(), "v8::Function::Cast()",
"Could not convert to function");
}
+void v8::Boolean::CheckCast(v8::Value* that) {
+ i::Handle<i::Object> obj = Utils::OpenHandle(that);
+ Utils::ApiCheck(obj->IsBoolean(),
+ "v8::Boolean::Cast()",
+ "Could not convert to boolean");
+}
+
+
void v8::Name::CheckCast(v8::Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
Utils::ApiCheck(obj->IsName(),
@@ -2714,6 +3103,18 @@
}
+void v8::Int32::CheckCast(v8::Value* that) {
+ Utils::ApiCheck(that->IsInt32(), "v8::Int32::Cast()",
+ "Could not convert to 32-bit signed integer");
+}
+
+
+void v8::Uint32::CheckCast(v8::Value* that) {
+ Utils::ApiCheck(that->IsUint32(), "v8::Uint32::Cast()",
+ "Could not convert to 32-bit unsigned integer");
+}
+
+
void v8::Array::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
Utils::ApiCheck(obj->IsJSArray(),
@@ -2722,6 +3123,20 @@
}
+void v8::Map::CheckCast(Value* that) {
+ i::Handle<i::Object> obj = Utils::OpenHandle(that);
+ Utils::ApiCheck(obj->IsJSMap(), "v8::Map::Cast()",
+ "Could not convert to Map");
+}
+
+
+void v8::Set::CheckCast(Value* that) {
+ i::Handle<i::Object> obj = Utils::OpenHandle(that);
+ Utils::ApiCheck(obj->IsJSSet(), "v8::Set::Cast()",
+ "Could not convert to Set");
+}
+
+
void v8::Promise::CheckCast(Value* that) {
Utils::ApiCheck(that->IsPromise(),
"v8::Promise::Cast()",
@@ -2736,11 +3151,17 @@
}
+void v8::Proxy::CheckCast(Value* that) {
+ Utils::ApiCheck(that->IsProxy(), "v8::Proxy::Cast()",
+ "Could not convert to proxy");
+}
+
+
void v8::ArrayBuffer::CheckCast(Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
- Utils::ApiCheck(obj->IsJSArrayBuffer(),
- "v8::ArrayBuffer::Cast()",
- "Could not convert to ArrayBuffer");
+ Utils::ApiCheck(
+ obj->IsJSArrayBuffer() && !i::JSArrayBuffer::cast(*obj)->is_shared(),
+ "v8::ArrayBuffer::Cast()", "Could not convert to ArrayBuffer");
}
@@ -2763,11 +3184,10 @@
#define CHECK_TYPED_ARRAY_CAST(Type, typeName, TYPE, ctype, size) \
void v8::Type##Array::CheckCast(Value* that) { \
i::Handle<i::Object> obj = Utils::OpenHandle(that); \
- Utils::ApiCheck(obj->IsJSTypedArray() && \
- i::JSTypedArray::cast(*obj)->type() == \
- kExternal##Type##Array, \
- "v8::" #Type "Array::Cast()", \
- "Could not convert to " #Type "Array"); \
+ Utils::ApiCheck( \
+ obj->IsJSTypedArray() && \
+ i::JSTypedArray::cast(*obj)->type() == i::kExternal##Type##Array, \
+ "v8::" #Type "Array::Cast()", "Could not convert to " #Type "Array"); \
}
@@ -2784,6 +3204,15 @@
}
+void v8::SharedArrayBuffer::CheckCast(Value* that) {
+ i::Handle<i::Object> obj = Utils::OpenHandle(that);
+ Utils::ApiCheck(
+ obj->IsJSArrayBuffer() && i::JSArrayBuffer::cast(*obj)->is_shared(),
+ "v8::SharedArrayBuffer::Cast()",
+ "Could not convert to SharedArrayBuffer");
+}
+
+
void v8::Date::CheckCast(v8::Value* that) {
i::Handle<i::Object> obj = Utils::OpenHandle(that);
i::Isolate* isolate = NULL;
@@ -2847,100 +3276,112 @@
}
+Maybe<bool> Value::BooleanValue(Local<Context> context) const {
+ return Just(Utils::OpenHandle(this)->BooleanValue());
+}
+
+
bool Value::BooleanValue() const {
return Utils::OpenHandle(this)->BooleanValue();
}
+Maybe<double> Value::NumberValue(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsNumber()) return Just(obj->Number());
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "NumberValue", double);
+ i::Handle<i::Object> num;
+ has_pending_exception = !i::Object::ToNumber(obj).ToHandle(&num);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(double);
+ return Just(num->Number());
+}
+
+
double Value::NumberValue() const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsNumber()) return obj->Number();
+ return NumberValue(ContextFromHeapObject(obj))
+ .FromMaybe(std::numeric_limits<double>::quiet_NaN());
+}
+
+
+Maybe<int64_t> Value::IntegerValue(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
i::Handle<i::Object> num;
if (obj->IsNumber()) {
num = obj;
} else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
- LOG_API(isolate, "NumberValue");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToNumber(
- isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, base::OS::nan_value());
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "IntegerValue", int64_t);
+ has_pending_exception = !i::Object::ToInteger(isolate, obj).ToHandle(&num);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int64_t);
}
- return num->Number();
+ return Just(num->IsSmi() ? static_cast<int64_t>(i::Smi::cast(*num)->value())
+ : static_cast<int64_t>(num->Number()));
}
int64_t Value::IntegerValue() const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> num;
+ auto obj = Utils::OpenHandle(this);
if (obj->IsNumber()) {
- num = obj;
- } else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
- LOG_API(isolate, "IntegerValue");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToInteger(
- isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, 0);
+ if (obj->IsSmi()) {
+ return i::Smi::cast(*obj)->value();
+ } else {
+ return static_cast<int64_t>(obj->Number());
+ }
}
- if (num->IsSmi()) {
- return i::Smi::cast(*num)->value();
- } else {
- return static_cast<int64_t>(num->Number());
- }
+ return IntegerValue(ContextFromHeapObject(obj)).FromMaybe(0);
}
-Local<Int32> Value::ToInt32(Isolate* v8_isolate) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
+Maybe<int32_t> Value::Int32Value(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsNumber()) return Just(NumberToInt32(*obj));
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Int32Value", int32_t);
i::Handle<i::Object> num;
- if (obj->IsSmi()) {
- num = obj;
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToInt32");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Int32>());
- }
- return ToApiHandle<Int32>(num);
+ has_pending_exception = !i::Object::ToInt32(isolate, obj).ToHandle(&num);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int32_t);
+ return Just(num->IsSmi() ? i::Smi::cast(*num)->value()
+ : static_cast<int32_t>(num->Number()));
}
-Local<Uint32> Value::ToUint32(Isolate* v8_isolate) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
+int32_t Value::Int32Value() const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsNumber()) return NumberToInt32(*obj);
+ return Int32Value(ContextFromHeapObject(obj)).FromMaybe(0);
+}
+
+
+Maybe<uint32_t> Value::Uint32Value(Local<Context> context) const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsNumber()) return Just(NumberToUint32(*obj));
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Uint32Value", uint32_t);
i::Handle<i::Object> num;
- if (obj->IsSmi()) {
- num = obj;
- } else {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "ToUInt32");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToUint32(
- isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
- }
- return ToApiHandle<Uint32>(num);
+ has_pending_exception = !i::Object::ToUint32(isolate, obj).ToHandle(&num);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(uint32_t);
+ return Just(num->IsSmi() ? static_cast<uint32_t>(i::Smi::cast(*num)->value())
+ : static_cast<uint32_t>(num->Number()));
}
-Local<Uint32> Value::ToArrayIndex() const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- if (obj->IsSmi()) {
- if (i::Smi::cast(*obj)->value() >= 0) return Utils::Uint32ToLocal(obj);
+uint32_t Value::Uint32Value() const {
+ auto obj = Utils::OpenHandle(this);
+ if (obj->IsNumber()) return NumberToUint32(*obj);
+ return Uint32Value(ContextFromHeapObject(obj)).FromMaybe(0);
+}
+
+
+MaybeLocal<Uint32> Value::ToArrayIndex(Local<Context> context) const {
+ auto self = Utils::OpenHandle(this);
+ if (self->IsSmi()) {
+ if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
return Local<Uint32>();
}
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
- LOG_API(isolate, "ToArrayIndex");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
+ PREPARE_FOR_EXECUTION(context, "ToArrayIndex", Uint32);
i::Handle<i::Object> string_obj;
- has_pending_exception = !i::Execution::ToString(
- isolate, obj).ToHandle(&string_obj);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Uint32>());
+ has_pending_exception =
+ !i::Object::ToString(isolate, self).ToHandle(&string_obj);
+ RETURN_ON_FAILED_EXECUTION(Uint32);
i::Handle<i::String> str = i::Handle<i::String>::cast(string_obj);
uint32_t index;
if (str->AsArrayIndex(&index)) {
@@ -2950,1300 +3391,1091 @@
} else {
value = isolate->factory()->NewNumber(index);
}
- return Utils::Uint32ToLocal(value);
+ RETURN_ESCAPED(Utils::Uint32ToLocal(value));
}
return Local<Uint32>();
}
-int32_t Value::Int32Value() const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- if (obj->IsSmi()) {
- return i::Smi::cast(*obj)->value();
- } else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
- LOG_API(isolate, "Int32Value (slow)");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> num;
- has_pending_exception = !i::Execution::ToInt32(isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, 0);
- if (num->IsSmi()) {
- return i::Smi::cast(*num)->value();
- } else {
- return static_cast<int32_t>(num->Number());
- }
+Local<Uint32> Value::ToArrayIndex() const {
+ auto self = Utils::OpenHandle(this);
+ if (self->IsSmi()) {
+ if (i::Smi::cast(*self)->value() >= 0) return Utils::Uint32ToLocal(self);
+ return Local<Uint32>();
}
+ auto context = ContextFromHeapObject(self);
+ RETURN_TO_LOCAL_UNCHECKED(ToArrayIndex(context), Uint32);
}
-bool Value::Equals(Handle<Value> that) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
- i::Handle<i::Object> other = Utils::OpenHandle(*that);
- if (obj->IsSmi() && other->IsSmi()) {
- return obj->Number() == other->Number();
- }
- i::Object* ho = obj->IsSmi() ? *other : *obj;
- i::Isolate* isolate = i::HeapObject::cast(ho)->GetIsolate();
- if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
- "v8::Value::Equals()",
- "Reading from empty handle")) {
- return false;
- }
- LOG_API(isolate, "Equals");
- ENTER_V8(isolate);
- // If both obj and other are JSObjects, we'd better compare by identity
- // immediately when going into JS builtin. The reason is Invoke
- // would overwrite global object receiver with global proxy.
- if (obj->IsJSObject() && other->IsJSObject()) {
- return *obj == *other;
- }
- i::Handle<i::Object> args[] = { other };
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result;
- has_pending_exception =
- !CallV8HeapFunction(isolate, "EQUALS", obj, arraysize(args), args)
- .ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return *result == i::Smi::FromInt(i::EQUAL);
+Maybe<bool> Value::Equals(Local<Context> context, Local<Value> that) const {
+ auto self = Utils::OpenHandle(this);
+ auto other = Utils::OpenHandle(*that);
+ return i::Object::Equals(self, other);
}
-bool Value::StrictEquals(Handle<Value> that) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
- i::Handle<i::Object> other = Utils::OpenHandle(*that);
- if (obj->IsSmi()) {
- return other->IsNumber() && obj->Number() == other->Number();
+bool Value::Equals(Local<Value> that) const {
+ auto self = Utils::OpenHandle(this);
+ auto other = Utils::OpenHandle(*that);
+ if (self->IsSmi() && other->IsSmi()) {
+ return self->Number() == other->Number();
}
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
- if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
- "v8::Value::StrictEquals()",
- "Reading from empty handle")) {
- return false;
+ if (self->IsJSObject() && other->IsJSObject()) {
+ return *self == *other;
}
- LOG_API(isolate, "StrictEquals");
- // Must check HeapNumber first, since NaN !== NaN.
- if (obj->IsHeapNumber()) {
- if (!other->IsNumber()) return false;
- double x = obj->Number();
- double y = other->Number();
- // Must check explicitly for NaN:s on Windows, but -0 works fine.
- return x == y && !std::isnan(x) && !std::isnan(y);
- } else if (*obj == *other) { // Also covers Booleans.
- return true;
- } else if (obj->IsSmi()) {
- return other->IsNumber() && obj->Number() == other->Number();
- } else if (obj->IsString()) {
- return other->IsString() &&
- i::String::Equals(i::Handle<i::String>::cast(obj),
- i::Handle<i::String>::cast(other));
- } else if (obj->IsUndefined() || obj->IsUndetectableObject()) {
- return other->IsUndefined() || other->IsUndetectableObject();
- } else {
- return false;
- }
+ auto heap_object = self->IsSmi() ? other : self;
+ auto context = ContextFromHeapObject(heap_object);
+ return Equals(context, that).FromMaybe(false);
}
-bool Value::SameValue(Handle<Value> that) const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this, true);
- if (!Utils::ApiCheck(!obj.is_null() && !that.IsEmpty(),
- "v8::Value::SameValue()",
- "Reading from empty handle")) {
- return false;
- }
- i::Handle<i::Object> other = Utils::OpenHandle(*that);
- return obj->SameValue(*other);
+bool Value::StrictEquals(Local<Value> that) const {
+ auto self = Utils::OpenHandle(this);
+ auto other = Utils::OpenHandle(*that);
+ return self->StrictEquals(*other);
}
-uint32_t Value::Uint32Value() const {
- i::Handle<i::Object> obj = Utils::OpenHandle(this);
- if (obj->IsSmi()) {
- return i::Smi::cast(*obj)->value();
- } else {
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
- LOG_API(isolate, "Uint32Value");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> num;
- has_pending_exception = !i::Execution::ToUint32(
- isolate, obj).ToHandle(&num);
- EXCEPTION_BAILOUT_CHECK(isolate, 0);
- if (num->IsSmi()) {
- return i::Smi::cast(*num)->value();
- } else {
- return static_cast<uint32_t>(num->Number());
- }
- }
+bool Value::SameValue(Local<Value> that) const {
+ auto self = Utils::OpenHandle(this);
+ auto other = Utils::OpenHandle(*that);
+ return self->SameValue(*other);
}
-bool v8::Object::Set(v8::Handle<Value> key, v8::Handle<Value> value) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::Set()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::Object> self = Utils::OpenHandle(this);
- i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
- i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE(isolate);
+Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context,
+ v8::Local<Value> key, v8::Local<Value> value) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
+ auto self = Utils::OpenHandle(this);
+ auto key_obj = Utils::OpenHandle(*key);
+ auto value_obj = Utils::OpenHandle(*value);
has_pending_exception =
i::Runtime::SetObjectProperty(isolate, self, key_obj, value_obj,
i::SLOPPY).is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return true;
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(true);
}
-bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::Set()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+bool v8::Object::Set(v8::Local<Value> key, v8::Local<Value> value) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return Set(context, key, value).FromMaybe(false);
+}
+
+
+Maybe<bool> v8::Object::Set(v8::Local<v8::Context> context, uint32_t index,
+ v8::Local<Value> value) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Set()", bool);
+ auto self = Utils::OpenHandle(this);
+ auto value_obj = Utils::OpenHandle(*value);
+ has_pending_exception = i::Object::SetElement(isolate, self, index, value_obj,
+ i::SLOPPY).is_null();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(true);
+}
+
+
+bool v8::Object::Set(uint32_t index, v8::Local<Value> value) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return Set(context, index, value).FromMaybe(false);
+}
+
+
+Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
+ v8::Local<Name> key,
+ v8::Local<Value> value) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
+ bool);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = i::JSObject::SetElement(
- self, index, value_obj, NONE, i::SLOPPY).is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return true;
+
+ i::LookupIterator it = i::LookupIterator::PropertyOrElement(
+ isolate, self, key_obj, i::LookupIterator::OWN);
+ Maybe<bool> result =
+ i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
}
-bool v8::Object::ForceSet(v8::Handle<Value> key,
- v8::Handle<Value> value,
+Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
+ uint32_t index,
+ v8::Local<Value> value) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
+ bool);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
+
+ i::LookupIterator it(isolate, self, index, i::LookupIterator::OWN);
+ Maybe<bool> result =
+ i::JSReceiver::CreateDataProperty(&it, value_obj, i::Object::DONT_THROW);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
+}
+
+
+Maybe<bool> v8::Object::DefineOwnProperty(v8::Local<v8::Context> context,
+ v8::Local<Name> key,
+ v8::Local<Value> value,
+ v8::PropertyAttribute attributes) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DefineOwnProperty()",
+ bool);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
+ i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
+
+ if (self->IsAccessCheckNeeded() &&
+ !isolate->MayAccess(handle(isolate->context()),
+ i::Handle<i::JSObject>::cast(self))) {
+ isolate->ReportFailedAccessCheck(i::Handle<i::JSObject>::cast(self));
+ return Nothing<bool>();
+ }
+
+ i::PropertyDescriptor desc;
+ desc.set_writable(!(attributes & v8::ReadOnly));
+ desc.set_enumerable(!(attributes & v8::DontEnum));
+ desc.set_configurable(!(attributes & v8::DontDelete));
+ desc.set_value(value_obj);
+ Maybe<bool> success = i::JSReceiver::DefineOwnProperty(
+ isolate, self, key_obj, &desc, i::Object::DONT_THROW);
+ // Even though we said DONT_THROW, there might be accessors that do throw.
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return success;
+}
+
+
+MUST_USE_RESULT
+static i::MaybeHandle<i::Object> DefineObjectProperty(
+ i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
+ i::Handle<i::Object> value, i::PropertyAttributes attrs) {
+ i::Isolate* isolate = js_object->GetIsolate();
+ bool success = false;
+ i::LookupIterator it = i::LookupIterator::PropertyOrElement(
+ isolate, js_object, key, &success, i::LookupIterator::OWN);
+ if (!success) return i::MaybeHandle<i::Object>();
+
+ return i::JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs);
+}
+
+
+Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
+ v8::Local<Value> key, v8::Local<Value> value,
+ v8::PropertyAttribute attribs) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::ForceSet()", bool);
+ auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
+ auto key_obj = Utils::OpenHandle(*key);
+ auto value_obj = Utils::OpenHandle(*value);
+ has_pending_exception =
+ DefineObjectProperty(self, key_obj, value_obj,
+ static_cast<i::PropertyAttributes>(attribs))
+ .is_null();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(true);
+}
+
+
+bool v8::Object::ForceSet(v8::Local<Value> key, v8::Local<Value> value,
v8::PropertyAttribute attribs) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::ForceSet()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ PREPARE_FOR_EXECUTION_GENERIC(isolate, Local<Context>(),
+ "v8::Object::ForceSet", false, i::HandleScope,
+ false);
+ i::Handle<i::JSObject> self =
+ i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = i::Runtime::DefineObjectProperty(
- self,
- key_obj,
- value_obj,
- static_cast<PropertyAttributes>(attribs)).is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, false);
+ has_pending_exception =
+ DefineObjectProperty(self, key_obj, value_obj,
+ static_cast<i::PropertyAttributes>(attribs))
+ .is_null();
+ EXCEPTION_BAILOUT_CHECK_SCOPED(isolate, false);
return true;
}
-bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
- return ForceSet(v8::Handle<Value>(reinterpret_cast<Value*>(*key)),
- value, DontEnum);
+Maybe<bool> v8::Object::SetPrivate(Local<Context> context, Local<Private> key,
+ Local<Value> value) {
+ return DefineOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)),
+ value, DontEnum);
}
-i::MaybeHandle<i::Object> DeleteObjectProperty(
- i::Isolate* isolate, i::Handle<i::JSReceiver> receiver,
- i::Handle<i::Object> key, i::JSReceiver::DeleteMode mode) {
- // Check if the given key is an array index.
- uint32_t index;
- if (key->ToArrayIndex(&index)) {
- // In Firefox/SpiderMonkey, Safari and Opera you can access the
- // characters of a string using [] notation. In the case of a
- // String object we just need to redirect the deletion to the
- // underlying string if the index is in range. Since the
- // underlying string does nothing with the deletion, we can ignore
- // such deletions.
- if (receiver->IsStringObjectWithCharacterAt(index)) {
- return isolate->factory()->true_value();
- }
-
- return i::JSReceiver::DeleteElement(receiver, index, mode);
- }
-
- i::Handle<i::Name> name;
- if (key->IsName()) {
- name = i::Handle<i::Name>::cast(key);
- } else {
- // Call-back into JavaScript to convert the key to a string.
- i::Handle<i::Object> converted;
- if (!i::Execution::ToString(isolate, key).ToHandle(&converted)) {
- return i::MaybeHandle<i::Object>();
- }
- name = i::Handle<i::String>::cast(converted);
- }
-
- if (name->IsString()) {
- name = i::String::Flatten(i::Handle<i::String>::cast(name));
- }
- return i::JSReceiver::DeleteProperty(receiver, name, mode);
-}
-
-
-bool v8::Object::ForceDelete(v8::Handle<Value> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
-
- // When deleting a property on the global object using ForceDelete
- // deoptimize all functions as optimized code does not check for the hole
- // value with DontDelete properties. We have to deoptimize all contexts
- // because of possible cross-context inlined functions.
- if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
- i::Deoptimizer::DeoptimizeAll(isolate);
- }
-
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj;
- has_pending_exception =
- !DeleteObjectProperty(isolate, self, key_obj,
- i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return obj->IsTrue();
-}
-
-
-Local<Value> v8::Object::Get(v8::Handle<Value> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
- ENTER_V8(isolate);
- i::Handle<i::Object> self = Utils::OpenHandle(this);
- i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
- EXCEPTION_PREAMBLE(isolate);
+MaybeLocal<Value> v8::Object::Get(Local<v8::Context> context,
+ Local<Value> key) {
+ PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
+ auto self = Utils::OpenHandle(this);
+ auto key_obj = Utils::OpenHandle(*key);
i::Handle<i::Object> result;
has_pending_exception =
!i::Runtime::GetObjectProperty(isolate, self, key_obj).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
- return Utils::ToLocal(result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(Utils::ToLocal(result));
+}
+
+
+Local<Value> v8::Object::Get(v8::Local<Value> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(Get(context, key), Value);
+}
+
+
+MaybeLocal<Value> v8::Object::Get(Local<Context> context, uint32_t index) {
+ PREPARE_FOR_EXECUTION(context, "v8::Object::Get()", Value);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Object::GetElement(isolate, self, index).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(Utils::ToLocal(result));
}
Local<Value> v8::Object::Get(uint32_t index) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::Get()", return Local<v8::Value>());
- ENTER_V8(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result;
- has_pending_exception =
- !i::Object::GetElement(isolate, self, index).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
- return Utils::ToLocal(result);
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(Get(context, index), Value);
}
-Local<Value> v8::Object::GetPrivate(v8::Handle<Private> key) {
- return Get(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
+MaybeLocal<Value> v8::Object::GetPrivate(Local<Context> context,
+ Local<Private> key) {
+ return Get(context, Local<Value>(reinterpret_cast<Value*>(*key)));
}
-PropertyAttribute v8::Object::GetPropertyAttributes(v8::Handle<Value> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetPropertyAttributes()",
- return static_cast<PropertyAttribute>(NONE));
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
+Maybe<PropertyAttribute> v8::Object::GetPropertyAttributes(
+ Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(
+ context, "v8::Object::GetPropertyAttributes()", PropertyAttribute);
+ auto self = Utils::OpenHandle(this);
+ auto key_obj = Utils::OpenHandle(*key);
if (!key_obj->IsName()) {
- EXCEPTION_PREAMBLE(isolate);
- has_pending_exception = !i::Execution::ToString(
- isolate, key_obj).ToHandle(&key_obj);
- EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
+ has_pending_exception =
+ !i::Object::ToString(isolate, key_obj).ToHandle(&key_obj);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
}
- i::Handle<i::Name> key_name = i::Handle<i::Name>::cast(key_obj);
- EXCEPTION_PREAMBLE(isolate);
- Maybe<PropertyAttributes> result =
- i::JSReceiver::GetPropertyAttributes(self, key_name);
- has_pending_exception = !result.has_value;
- EXCEPTION_BAILOUT_CHECK(isolate, static_cast<PropertyAttribute>(NONE));
- if (result.value == ABSENT) return static_cast<PropertyAttribute>(NONE);
- return static_cast<PropertyAttribute>(result.value);
+ auto key_name = i::Handle<i::Name>::cast(key_obj);
+ auto result = i::JSReceiver::GetPropertyAttributes(self, key_name);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
+ if (result.FromJust() == i::ABSENT) {
+ return Just(static_cast<PropertyAttribute>(i::NONE));
+ }
+ return Just(static_cast<PropertyAttribute>(result.FromJust()));
+}
+
+
+PropertyAttribute v8::Object::GetPropertyAttributes(v8::Local<Value> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return GetPropertyAttributes(context, key)
+ .FromMaybe(static_cast<PropertyAttribute>(i::NONE));
+}
+
+
+MaybeLocal<Value> v8::Object::GetOwnPropertyDescriptor(Local<Context> context,
+ Local<String> key) {
+ PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyDescriptor()",
+ Value);
+ i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
+ i::Handle<i::String> key_name = Utils::OpenHandle(*key);
+
+ i::PropertyDescriptor desc;
+ Maybe<bool> found =
+ i::JSReceiver::GetOwnPropertyDescriptor(isolate, obj, key_name, &desc);
+ has_pending_exception = found.IsNothing();
+ RETURN_ON_FAILED_EXECUTION(Value);
+ if (!found.FromJust()) {
+ return v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate));
+ }
+ RETURN_ESCAPED(Utils::ToLocal(desc.ToObject(isolate)));
}
Local<Value> v8::Object::GetOwnPropertyDescriptor(Local<String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyDescriptor()",
- return Local<Value>());
- ENTER_V8(isolate);
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
- i::Handle<i::Name> key_name = Utils::OpenHandle(*key);
- i::Handle<i::Object> args[] = { obj, key_name };
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result;
- has_pending_exception =
- !CallV8HeapFunction(isolate, "ObjectGetOwnPropertyDescriptor",
- isolate->factory()->undefined_value(),
- arraysize(args), args).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
- return Utils::ToLocal(result);
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyDescriptor(context, key), Value);
}
Local<Value> v8::Object::GetPrototype() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetPrototype()", return Local<v8::Value>());
- ENTER_V8(isolate);
- i::Handle<i::Object> self = Utils::OpenHandle(this);
+ auto isolate = Utils::OpenHandle(this)->GetIsolate();
+ auto self = Utils::OpenHandle(this);
i::PrototypeIterator iter(isolate, self);
return Utils::ToLocal(i::PrototypeIterator::GetCurrent(iter));
}
-bool v8::Object::SetPrototype(Handle<Value> value) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::SetPrototype()", return false);
- ENTER_V8(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
+Maybe<bool> v8::Object::SetPrototype(Local<Context> context,
+ Local<Value> value) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetPrototype()", bool);
+ auto self = Utils::OpenHandle(this);
+ auto value_obj = Utils::OpenHandle(*value);
// We do not allow exceptions thrown while setting the prototype
// to propagate outside.
- TryCatch try_catch;
- EXCEPTION_PREAMBLE(isolate);
- i::MaybeHandle<i::Object> result =
- i::JSObject::SetPrototype(self, value_obj, false);
- has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return true;
+ TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
+ auto result = i::JSReceiver::SetPrototype(self, value_obj, false,
+ i::Object::THROW_ON_ERROR);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(true);
+}
+
+
+bool v8::Object::SetPrototype(Local<Value> value) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return SetPrototype(context, value).FromMaybe(false);
}
Local<Object> v8::Object::FindInstanceInPrototypeChain(
- v8::Handle<FunctionTemplate> tmpl) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate,
- "v8::Object::FindInstanceInPrototypeChain()",
- return Local<v8::Object>());
- ENTER_V8(isolate);
+ v8::Local<FunctionTemplate> tmpl) {
+ auto isolate = Utils::OpenHandle(this)->GetIsolate();
i::PrototypeIterator iter(isolate, *Utils::OpenHandle(this),
i::PrototypeIterator::START_AT_RECEIVER);
- i::FunctionTemplateInfo* tmpl_info = *Utils::OpenHandle(*tmpl);
+ auto tmpl_info = *Utils::OpenHandle(*tmpl);
while (!tmpl_info->IsTemplateFor(iter.GetCurrent())) {
iter.Advance();
if (iter.IsAtEnd()) {
return Local<Object>();
}
}
- return Utils::ToLocal(
- i::handle(i::JSObject::cast(iter.GetCurrent()), isolate));
+ // IsTemplateFor() ensures that iter.GetCurrent() can't be a Proxy here.
+ return Utils::ToLocal(i::handle(iter.GetCurrent<i::JSObject>(), isolate));
+}
+
+
+MaybeLocal<Array> v8::Object::GetPropertyNames(Local<Context> context) {
+ PREPARE_FOR_EXECUTION(context, "v8::Object::GetPropertyNames()", Array);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::FixedArray> value;
+ has_pending_exception =
+ !i::JSReceiver::GetKeys(self, i::JSReceiver::INCLUDE_PROTOS,
+ i::ENUMERABLE_STRINGS)
+ .ToHandle(&value);
+ RETURN_ON_FAILED_EXECUTION(Array);
+ // Because we use caching to speed up enumeration it is important
+ // to never change the result of the basic enumeration function so
+ // we clone the result.
+ auto elms = isolate->factory()->CopyFixedArray(value);
+ auto result = isolate->factory()->NewJSArrayWithElements(elms);
+ RETURN_ESCAPED(Utils::ToLocal(result));
}
Local<Array> v8::Object::GetPropertyNames() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetPropertyNames()",
- return Local<v8::Array>());
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE(isolate);
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(GetPropertyNames(context), Array);
+}
+
+
+MaybeLocal<Array> v8::Object::GetOwnPropertyNames(Local<Context> context) {
+ PREPARE_FOR_EXECUTION(context, "v8::Object::GetOwnPropertyNames()", Array);
+ auto self = Utils::OpenHandle(this);
i::Handle<i::FixedArray> value;
- has_pending_exception = !i::JSReceiver::GetKeys(
- self, i::JSReceiver::INCLUDE_PROTOS).ToHandle(&value);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
+ has_pending_exception = !i::JSReceiver::GetKeys(self, i::JSReceiver::OWN_ONLY,
+ i::ENUMERABLE_STRINGS)
+ .ToHandle(&value);
+ RETURN_ON_FAILED_EXECUTION(Array);
// Because we use caching to speed up enumeration it is important
// to never change the result of the basic enumeration function so
// we clone the result.
- i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
- i::Handle<i::JSArray> result =
- isolate->factory()->NewJSArrayWithElements(elms);
- return Utils::ToLocal(scope.CloseAndEscape(result));
+ auto elms = isolate->factory()->CopyFixedArray(value);
+ auto result = isolate->factory()->NewJSArrayWithElements(elms);
+ RETURN_ESCAPED(Utils::ToLocal(result));
}
Local<Array> v8::Object::GetOwnPropertyNames() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetOwnPropertyNames()",
- return Local<v8::Array>());
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::FixedArray> value;
- has_pending_exception = !i::JSReceiver::GetKeys(
- self, i::JSReceiver::OWN_ONLY).ToHandle(&value);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Array>());
- // Because we use caching to speed up enumeration it is important
- // to never change the result of the basic enumeration function so
- // we clone the result.
- i::Handle<i::FixedArray> elms = isolate->factory()->CopyFixedArray(value);
- i::Handle<i::JSArray> result =
- isolate->factory()->NewJSArrayWithElements(elms);
- return Utils::ToLocal(scope.CloseAndEscape(result));
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(GetOwnPropertyNames(context), Array);
}
-static bool GetPredefinedToString(i::Handle<i::String> tag,
- Local<String>* result) {
- i::Isolate* i_isolate = tag->GetIsolate();
- Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
- i::Factory* factory = i_isolate->factory();
-
- if (i::String::Equals(tag, factory->Arguments_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~Arguments]");
- } else if (i::String::Equals(tag, factory->Array_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~Array]");
- } else if (i::String::Equals(tag, factory->Boolean_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~Boolean]");
- } else if (i::String::Equals(tag, factory->Date_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~Date]");
- } else if (i::String::Equals(tag, factory->Error_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~Error]");
- } else if (i::String::Equals(tag, factory->Function_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~Function]");
- } else if (i::String::Equals(tag, factory->Number_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~Number]");
- } else if (i::String::Equals(tag, factory->RegExp_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~RegExp]");
- } else if (i::String::Equals(tag, factory->String_string())) {
- *result = v8::String::NewFromUtf8(isolate, "[object ~String]");
- } else {
- return false;
- }
- return true;
+MaybeLocal<String> v8::Object::ObjectProtoToString(Local<Context> context) {
+ PREPARE_FOR_EXECUTION(context, "v8::Object::ObjectProtoToString", String);
+ auto obj = Utils::OpenHandle(this);
+ Local<String> result;
+ has_pending_exception =
+ !ToLocal<String>(i::JSObject::ObjectProtoToString(isolate, obj), &result);
+ RETURN_ON_FAILED_EXECUTION(String);
+ RETURN_ESCAPED(result);
}
Local<String> v8::Object::ObjectProtoToString() {
- i::Isolate* i_isolate = Utils::OpenHandle(this)->GetIsolate();
- Isolate* isolate = reinterpret_cast<Isolate*>(i_isolate);
- ON_BAILOUT(i_isolate, "v8::Object::ObjectProtoToString()",
- return Local<v8::String>());
- ENTER_V8(i_isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
-
- i::Handle<i::Object> name(self->class_name(), i_isolate);
- i::Handle<i::Object> tag;
-
- // Native implementation of Object.prototype.toString (v8natives.js):
- // var c = %_ClassOf(this);
- // if (c === 'Arguments') c = 'Object';
- // return "[object " + c + "]";
-
- if (!name->IsString()) {
- return v8::String::NewFromUtf8(isolate, "[object ]");
- } else {
- i::Handle<i::String> class_name = i::Handle<i::String>::cast(name);
- if (i::String::Equals(class_name,
- i_isolate->factory()->Arguments_string())) {
- return v8::String::NewFromUtf8(isolate, "[object Object]");
- } else {
- if (internal::FLAG_harmony_tostring) {
- i::Handle<i::Symbol> toStringTag =
- Utils::OpenHandle(*Symbol::GetToStringTag(isolate));
- EXCEPTION_PREAMBLE(i_isolate);
- has_pending_exception =
- !i::Runtime::GetObjectProperty(i_isolate, self, toStringTag)
- .ToHandle(&tag);
- EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::String>());
-
- if (!tag->IsUndefined()) {
- if (!tag->IsString())
- return v8::String::NewFromUtf8(isolate, "[object ???]");
- i::Handle<i::String> tag_name = i::Handle<i::String>::cast(tag);
- if (!i::String::Equals(class_name, tag_name)) {
- Local<String> result;
- if (GetPredefinedToString(tag_name, &result)) return result;
-
- class_name = tag_name;
- }
- }
- }
- const char* prefix = "[object ";
- Local<String> str = Utils::ToLocal(class_name);
- const char* postfix = "]";
-
- int prefix_len = i::StrLength(prefix);
- int str_len = str->Utf8Length();
- int postfix_len = i::StrLength(postfix);
-
- int buf_len = prefix_len + str_len + postfix_len;
- i::ScopedVector<char> buf(buf_len);
-
- // Write prefix.
- char* ptr = buf.start();
- i::MemCopy(ptr, prefix, prefix_len * v8::internal::kCharSize);
- ptr += prefix_len;
-
- // Write real content.
- str->WriteUtf8(ptr, str_len);
- ptr += str_len;
-
- // Write postfix.
- i::MemCopy(ptr, postfix, postfix_len * v8::internal::kCharSize);
-
- // Copy the buffer into a heap-allocated string and return it.
- Local<String> result = v8::String::NewFromUtf8(
- isolate, buf.start(), String::kNormalString, buf_len);
- return result;
- }
- }
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(ObjectProtoToString(context), String);
}
Local<String> v8::Object::GetConstructorName() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetConstructorName()",
- return Local<v8::String>());
- ENTER_V8(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::String> name(self->constructor_name());
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::String> name = i::JSReceiver::GetConstructorName(self);
return Utils::ToLocal(name);
}
-bool v8::Object::Delete(v8::Handle<Value> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::Delete()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj;
- has_pending_exception =
- !DeleteObjectProperty(isolate, self, key_obj,
- i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return obj->IsTrue();
+Maybe<bool> v8::Object::Delete(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Delete()", bool);
+ auto self = Utils::OpenHandle(this);
+ auto key_obj = Utils::OpenHandle(*key);
+ Maybe<bool> result =
+ i::Runtime::DeleteObjectProperty(isolate, self, key_obj, i::SLOPPY);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
}
-bool v8::Object::DeletePrivate(v8::Handle<Private> key) {
- return Delete(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
+bool v8::Object::Delete(v8::Local<Value> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return Delete(context, key).FromMaybe(false);
}
-bool v8::Object::Has(v8::Handle<Value> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::Has()", return false);
- ENTER_V8(isolate);
- i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
- i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
- EXCEPTION_PREAMBLE(isolate);
- Maybe<bool> maybe;
+Maybe<bool> v8::Object::DeletePrivate(Local<Context> context,
+ Local<Private> key) {
+ return Delete(context, Local<Value>(reinterpret_cast<Value*>(*key)));
+}
+
+
+Maybe<bool> v8::Object::Has(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
+ auto self = Utils::OpenHandle(this);
+ auto key_obj = Utils::OpenHandle(*key);
+ Maybe<bool> maybe = Nothing<bool>();
// Check if the given key is an array index.
- uint32_t index;
+ uint32_t index = 0;
if (key_obj->ToArrayIndex(&index)) {
maybe = i::JSReceiver::HasElement(self, index);
} else {
// Convert the key to a name - possibly by calling back into JavaScript.
i::Handle<i::Name> name;
- if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) {
+ if (i::Object::ToName(isolate, key_obj).ToHandle(&name)) {
maybe = i::JSReceiver::HasProperty(self, name);
}
}
- if (!maybe.has_value) has_pending_exception = true;
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- DCHECK(maybe.has_value);
- return maybe.value;
+ has_pending_exception = maybe.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return maybe;
}
-bool v8::Object::HasPrivate(v8::Handle<Private> key) {
- // TODO(rossberg): this should use HasOwnProperty, but we'd need to
- // generalise that to a (noy yet existant) Name argument first.
- return Has(v8::Handle<Value>(reinterpret_cast<Value*>(*key)));
+bool v8::Object::Has(v8::Local<Value> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return Has(context, key).FromMaybe(false);
+}
+
+
+Maybe<bool> v8::Object::HasPrivate(Local<Context> context, Local<Private> key) {
+ return HasOwnProperty(context, Local<Name>(reinterpret_cast<Name*>(*key)));
+}
+
+
+Maybe<bool> v8::Object::Delete(Local<Context> context, uint32_t index) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::DeleteProperty()",
+ bool);
+ auto self = Utils::OpenHandle(this);
+ Maybe<bool> result = i::JSReceiver::DeleteElement(self, index);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
}
bool v8::Object::Delete(uint32_t index) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::DeleteProperty()",
- return false);
- ENTER_V8(isolate);
- HandleScope scope(reinterpret_cast<Isolate*>(isolate));
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return Delete(context, index).FromMaybe(false);
+}
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj;
- has_pending_exception =
- !i::JSReceiver::DeleteElement(self, index).ToHandle(&obj);
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return obj->IsTrue();
+
+Maybe<bool> v8::Object::Has(Local<Context> context, uint32_t index) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::Get()", bool);
+ auto self = Utils::OpenHandle(this);
+ auto maybe = i::JSReceiver::HasElement(self, index);
+ has_pending_exception = maybe.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return maybe;
}
bool v8::Object::Has(uint32_t index) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::HasProperty()", return false);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE(isolate);
- Maybe<bool> maybe = i::JSReceiver::HasElement(self, index);
- has_pending_exception = !maybe.has_value;
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return maybe.value;
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return Has(context, index).FromMaybe(false);
}
-template<typename Getter, typename Setter, typename Data>
-static inline bool ObjectSetAccessor(Object* obj,
- Handle<Name> name,
- Getter getter,
- Setter setter,
- Data data,
+template <typename Getter, typename Setter, typename Data>
+static Maybe<bool> ObjectSetAccessor(Local<Context> context, Object* self,
+ Local<Name> name, Getter getter,
+ Setter setter, Data data,
AccessControl settings,
PropertyAttribute attributes) {
- i::Isolate* isolate = Utils::OpenHandle(obj)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::SetAccessor()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- v8::Handle<AccessorSignature> signature;
- i::Handle<i::AccessorInfo> info = MakeAccessorInfo(
- name, getter, setter, data, settings, attributes, signature);
- if (info.is_null()) return false;
- bool fast = Utils::OpenHandle(obj)->HasFastProperties();
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::SetAccessor()", bool);
+ if (!Utils::OpenHandle(self)->IsJSObject()) return Just(false);
+ i::Handle<i::JSObject> obj =
+ i::Handle<i::JSObject>::cast(Utils::OpenHandle(self));
+ v8::Local<AccessorSignature> signature;
+ auto info = MakeAccessorInfo(name, getter, setter, data, settings, attributes,
+ signature);
+ if (info.is_null()) return Nothing<bool>();
+ bool fast = obj->HasFastProperties();
i::Handle<i::Object> result;
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate, result,
- i::JSObject::SetAccessor(Utils::OpenHandle(obj), info),
- false);
- if (result->IsUndefined()) return false;
+ has_pending_exception =
+ !i::JSObject::SetAccessor(obj, info).ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ if (result->IsUndefined()) return Nothing<bool>();
if (fast) {
- i::JSObject::MigrateSlowToFast(Utils::OpenHandle(obj), 0, "APISetAccessor");
+ i::JSObject::MigrateSlowToFast(obj, 0, "APISetAccessor");
}
- return true;
+ return Just(true);
}
-bool Object::SetAccessor(Handle<String> name,
- AccessorGetterCallback getter,
- AccessorSetterCallback setter,
- v8::Handle<Value> data,
- AccessControl settings,
- PropertyAttribute attributes) {
- return ObjectSetAccessor(
- this, name, getter, setter, data, settings, attributes);
+Maybe<bool> Object::SetAccessor(Local<Context> context, Local<Name> name,
+ AccessorNameGetterCallback getter,
+ AccessorNameSetterCallback setter,
+ MaybeLocal<Value> data, AccessControl settings,
+ PropertyAttribute attribute) {
+ return ObjectSetAccessor(context, this, name, getter, setter,
+ data.FromMaybe(Local<Value>()), settings, attribute);
}
-bool Object::SetAccessor(Handle<Name> name,
- AccessorNameGetterCallback getter,
+bool Object::SetAccessor(Local<String> name, AccessorGetterCallback getter,
+ AccessorSetterCallback setter, v8::Local<Value> data,
+ AccessControl settings, PropertyAttribute attributes) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
+ attributes).FromMaybe(false);
+}
+
+
+bool Object::SetAccessor(Local<Name> name, AccessorNameGetterCallback getter,
AccessorNameSetterCallback setter,
- v8::Handle<Value> data,
- AccessControl settings,
+ v8::Local<Value> data, AccessControl settings,
PropertyAttribute attributes) {
- return ObjectSetAccessor(
- this, name, getter, setter, data, settings, attributes);
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return ObjectSetAccessor(context, this, name, getter, setter, data, settings,
+ attributes).FromMaybe(false);
}
-bool Object::SetDeclaredAccessor(Local<Name> name,
- Local<DeclaredAccessorDescriptor> descriptor,
- PropertyAttribute attributes,
- AccessControl settings) {
- void* null = NULL;
- return ObjectSetAccessor(
- this, name, descriptor, null, null, settings, attributes);
-}
-
-
-void Object::SetAccessorProperty(Local<Name> name,
- Local<Function> getter,
- Handle<Function> setter,
+void Object::SetAccessorProperty(Local<Name> name, Local<Function> getter,
+ Local<Function> setter,
PropertyAttribute attribute,
AccessControl settings) {
// TODO(verwaest): Remove |settings|.
DCHECK_EQ(v8::DEFAULT, settings);
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::SetAccessorProperty()", return);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return;
i::Handle<i::Object> getter_i = v8::Utils::OpenHandle(*getter);
i::Handle<i::Object> setter_i = v8::Utils::OpenHandle(*setter, true);
if (setter_i.is_null()) setter_i = isolate->factory()->null_value();
- i::JSObject::DefineAccessor(v8::Utils::OpenHandle(this),
- v8::Utils::OpenHandle(*name),
- getter_i,
- setter_i,
- static_cast<PropertyAttributes>(attribute));
+ i::JSObject::DefineAccessor(i::Handle<i::JSObject>::cast(self),
+ v8::Utils::OpenHandle(*name), getter_i, setter_i,
+ static_cast<i::PropertyAttributes>(attribute));
}
-bool v8::Object::HasOwnProperty(Handle<String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::HasOwnProperty()",
- return false);
- EXCEPTION_PREAMBLE(isolate);
- Maybe<bool> maybe = i::JSReceiver::HasOwnProperty(Utils::OpenHandle(this),
- Utils::OpenHandle(*key));
- has_pending_exception = !maybe.has_value;
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return maybe.value;
+Maybe<bool> v8::Object::HasOwnProperty(Local<Context> context,
+ Local<Name> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasOwnProperty()",
+ bool);
+ auto self = Utils::OpenHandle(this);
+ auto key_val = Utils::OpenHandle(*key);
+ auto result = i::JSReceiver::HasOwnProperty(self, key_val);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
}
-bool v8::Object::HasRealNamedProperty(Handle<String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::HasRealNamedProperty()",
- return false);
- EXCEPTION_PREAMBLE(isolate);
- Maybe<bool> maybe = i::JSObject::HasRealNamedProperty(
- Utils::OpenHandle(this), Utils::OpenHandle(*key));
- has_pending_exception = !maybe.has_value;
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return maybe.value;
+bool v8::Object::HasOwnProperty(Local<String> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return HasOwnProperty(context, key).FromMaybe(false);
+}
+
+
+Maybe<bool> v8::Object::HasRealNamedProperty(Local<Context> context,
+ Local<Name> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::HasRealNamedProperty()",
+ bool);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return Just(false);
+ auto key_val = Utils::OpenHandle(*key);
+ auto result = i::JSObject::HasRealNamedProperty(
+ i::Handle<i::JSObject>::cast(self), key_val);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
+}
+
+
+bool v8::Object::HasRealNamedProperty(Local<String> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return HasRealNamedProperty(context, key).FromMaybe(false);
+}
+
+
+Maybe<bool> v8::Object::HasRealIndexedProperty(Local<Context> context,
+ uint32_t index) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context,
+ "v8::Object::HasRealIndexedProperty()", bool);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return Just(false);
+ auto result = i::JSObject::HasRealElementProperty(
+ i::Handle<i::JSObject>::cast(self), index);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
}
bool v8::Object::HasRealIndexedProperty(uint32_t index) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::HasRealIndexedProperty()",
- return false);
- EXCEPTION_PREAMBLE(isolate);
- Maybe<bool> maybe =
- i::JSObject::HasRealElementProperty(Utils::OpenHandle(this), index);
- has_pending_exception = !maybe.has_value;
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return maybe.value;
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return HasRealIndexedProperty(context, index).FromMaybe(false);
}
-bool v8::Object::HasRealNamedCallbackProperty(Handle<String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate,
- "v8::Object::HasRealNamedCallbackProperty()",
- return false);
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- Maybe<bool> maybe = i::JSObject::HasRealNamedCallbackProperty(
- Utils::OpenHandle(this), Utils::OpenHandle(*key));
- has_pending_exception = !maybe.has_value;
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return maybe.value;
+Maybe<bool> v8::Object::HasRealNamedCallbackProperty(Local<Context> context,
+ Local<Name> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(
+ context, "v8::Object::HasRealNamedCallbackProperty()", bool);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return Just(false);
+ auto key_val = Utils::OpenHandle(*key);
+ auto result = i::JSObject::HasRealNamedCallbackProperty(
+ i::Handle<i::JSObject>::cast(self), key_val);
+ has_pending_exception = result.IsNothing();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return result;
+}
+
+
+bool v8::Object::HasRealNamedCallbackProperty(Local<String> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return HasRealNamedCallbackProperty(context, key).FromMaybe(false);
}
bool v8::Object::HasNamedLookupInterceptor() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::HasNamedLookupInterceptor()",
- return false);
- return Utils::OpenHandle(this)->HasNamedInterceptor();
+ auto self = Utils::OpenHandle(this);
+ return self->IsJSObject() &&
+ i::Handle<i::JSObject>::cast(self)->HasNamedInterceptor();
}
bool v8::Object::HasIndexedLookupInterceptor() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::HasIndexedLookupInterceptor()",
- return false);
- return Utils::OpenHandle(this)->HasIndexedInterceptor();
+ auto self = Utils::OpenHandle(this);
+ return self->IsJSObject() &&
+ i::Handle<i::JSObject>::cast(self)->HasIndexedInterceptor();
}
-static Local<Value> GetPropertyByLookup(i::LookupIterator* it) {
- // If the property being looked up is a callback, it can throw an exception.
- EXCEPTION_PREAMBLE(it->isolate());
- i::Handle<i::Object> result;
- has_pending_exception = !i::Object::GetProperty(it).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(it->isolate(), Local<Value>());
-
- if (it->IsFound()) return Utils::ToLocal(result);
- return Local<Value>();
+MaybeLocal<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
+ Local<Context> context, Local<Name> key) {
+ PREPARE_FOR_EXECUTION(
+ context, "v8::Object::GetRealNamedPropertyInPrototypeChain()", Value);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return MaybeLocal<Value>();
+ i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
+ i::PrototypeIterator iter(isolate, self);
+ if (iter.IsAtEnd()) return MaybeLocal<Value>();
+ i::Handle<i::JSReceiver> proto =
+ i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
+ i::LookupIterator it = i::LookupIterator::PropertyOrElement(
+ isolate, self, key_obj, proto,
+ i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ if (!it.IsFound()) return MaybeLocal<Value>();
+ RETURN_ESCAPED(result);
}
Local<Value> v8::Object::GetRealNamedPropertyInPrototypeChain(
- Handle<String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate,
- "v8::Object::GetRealNamedPropertyInPrototypeChain()",
- return Local<Value>());
- ENTER_V8(isolate);
- i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
- i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- i::PrototypeIterator iter(isolate, self_obj);
- if (iter.IsAtEnd()) return Local<Value>();
- i::Handle<i::Object> proto = i::PrototypeIterator::GetCurrent(iter);
- i::LookupIterator it(self_obj, key_obj, i::Handle<i::JSReceiver>::cast(proto),
- i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
- return GetPropertyByLookup(&it);
+ Local<String> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(GetRealNamedPropertyInPrototypeChain(context, key),
+ Value);
}
-Local<Value> v8::Object::GetRealNamedProperty(Handle<String> key) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetRealNamedProperty()",
- return Local<Value>());
- ENTER_V8(isolate);
- i::Handle<i::JSObject> self_obj = Utils::OpenHandle(this);
- i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
- i::LookupIterator it(self_obj, key_obj,
- i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
- return GetPropertyByLookup(&it);
+Maybe<PropertyAttribute>
+v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(
+ Local<Context> context, Local<Name> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(
+ context, "v8::Object::GetRealNamedPropertyAttributesInPrototypeChain()",
+ PropertyAttribute);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return Nothing<PropertyAttribute>();
+ i::Handle<i::Name> key_obj = Utils::OpenHandle(*key);
+ i::PrototypeIterator iter(isolate, self);
+ if (iter.IsAtEnd()) return Nothing<PropertyAttribute>();
+ i::Handle<i::JSReceiver> proto =
+ i::PrototypeIterator::GetCurrent<i::JSReceiver>(iter);
+ i::LookupIterator it = i::LookupIterator::PropertyOrElement(
+ isolate, self, key_obj, proto,
+ i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
+ Maybe<i::PropertyAttributes> result =
+ i::JSReceiver::GetPropertyAttributes(&it);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
+ if (!it.IsFound()) return Nothing<PropertyAttribute>();
+ if (result.FromJust() == i::ABSENT) return Just(None);
+ return Just(static_cast<PropertyAttribute>(result.FromJust()));
}
-// Turns on access checks by copying the map and setting the check flag.
-// Because the object gets a new map, existing inline cache caching
-// the old map of this object will fail.
-void v8::Object::TurnOnAccessCheck() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::TurnOnAccessCheck()", return);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+Maybe<PropertyAttribute>
+v8::Object::GetRealNamedPropertyAttributesInPrototypeChain(Local<String> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return GetRealNamedPropertyAttributesInPrototypeChain(context, key);
+}
- // When turning on access checks for a global object deoptimize all functions
- // as optimized code does not always handle access checks.
- i::Deoptimizer::DeoptimizeGlobalObject(*obj);
- i::Handle<i::Map> new_map =
- i::Map::Copy(i::Handle<i::Map>(obj->map()), "APITurnOnAccessCheck");
- new_map->set_is_access_check_needed(true);
- i::JSObject::MigrateToMap(obj, new_map);
+MaybeLocal<Value> v8::Object::GetRealNamedProperty(Local<Context> context,
+ Local<Name> key) {
+ PREPARE_FOR_EXECUTION(context, "v8::Object::GetRealNamedProperty()", Value);
+ auto self = Utils::OpenHandle(this);
+ auto key_obj = Utils::OpenHandle(*key);
+ i::LookupIterator it = i::LookupIterator::PropertyOrElement(
+ isolate, self, key_obj,
+ i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(i::Object::GetProperty(&it), &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ if (!it.IsFound()) return MaybeLocal<Value>();
+ RETURN_ESCAPED(result);
+}
+
+
+Local<Value> v8::Object::GetRealNamedProperty(Local<String> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(GetRealNamedProperty(context, key), Value);
+}
+
+
+Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
+ Local<Context> context, Local<Name> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(
+ context, "v8::Object::GetRealNamedPropertyAttributes()",
+ PropertyAttribute);
+ auto self = Utils::OpenHandle(this);
+ auto key_obj = Utils::OpenHandle(*key);
+ i::LookupIterator it = i::LookupIterator::PropertyOrElement(
+ isolate, self, key_obj,
+ i::LookupIterator::PROTOTYPE_CHAIN_SKIP_INTERCEPTOR);
+ auto result = i::JSReceiver::GetPropertyAttributes(&it);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(PropertyAttribute);
+ if (!it.IsFound()) return Nothing<PropertyAttribute>();
+ if (result.FromJust() == i::ABSENT) {
+ return Just(static_cast<PropertyAttribute>(i::NONE));
+ }
+ return Just<PropertyAttribute>(
+ static_cast<PropertyAttribute>(result.FromJust()));
+}
+
+
+Maybe<PropertyAttribute> v8::Object::GetRealNamedPropertyAttributes(
+ Local<String> key) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ return GetRealNamedPropertyAttributes(context, key);
}
Local<v8::Object> v8::Object::Clone() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::Clone()", return Local<Object>());
+ auto self = i::Handle<i::JSObject>::cast(Utils::OpenHandle(this));
+ auto isolate = self->GetIsolate();
ENTER_V8(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::JSObject> result = isolate->factory()->CopyJSObject(self);
- has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
+ auto result = isolate->factory()->CopyJSObject(self);
+ CHECK(!result.is_null());
return Utils::ToLocal(result);
}
Local<v8::Context> v8::Object::CreationContext() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate,
- "v8::Object::CreationContext()", return Local<v8::Context>());
- ENTER_V8(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- i::Context* context = self->GetCreationContext();
- return Utils::ToLocal(i::Handle<i::Context>(context));
+ auto self = Utils::OpenHandle(this);
+ auto context = handle(self->GetCreationContext());
+ return Utils::ToLocal(context);
}
int v8::Object::GetIdentityHash() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetIdentityHash()", return 0);
- ENTER_V8(isolate);
+ auto isolate = Utils::OpenHandle(this)->GetIsolate();
i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ auto self = Utils::OpenHandle(this);
return i::JSReceiver::GetOrCreateIdentityHash(self)->value();
}
-bool v8::Object::SetHiddenValue(v8::Handle<v8::String> key,
- v8::Handle<v8::Value> value) {
+bool v8::Object::SetHiddenValue(v8::Local<v8::String> key,
+ v8::Local<v8::Value> value) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::SetHiddenValue()", return false);
- if (value.IsEmpty()) return DeleteHiddenValue(key);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return false;
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::Handle<i::String> key_string =
isolate->factory()->InternalizeString(key_obj);
+ if (value.IsEmpty()) {
+ i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
+ key_string);
+ return true;
+ }
i::Handle<i::Object> value_obj = Utils::OpenHandle(*value);
- i::Handle<i::Object> result =
- i::JSObject::SetHiddenProperty(self, key_string, value_obj);
+ i::Handle<i::Object> result = i::JSObject::SetHiddenProperty(
+ i::Handle<i::JSObject>::cast(self), key_string, value_obj);
return *result == *self;
}
-v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Handle<v8::String> key) {
+v8::Local<v8::Value> v8::Object::GetHiddenValue(v8::Local<v8::String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::GetHiddenValue()",
- return Local<v8::Value>());
ENTER_V8(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return v8::Local<v8::Value>();
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::Handle<i::String> key_string =
isolate->factory()->InternalizeString(key_obj);
- i::Handle<i::Object> result(self->GetHiddenProperty(key_string), isolate);
+ i::Handle<i::Object> result(
+ i::Handle<i::JSObject>::cast(self)->GetHiddenProperty(key_string),
+ isolate);
if (result->IsTheHole()) return v8::Local<v8::Value>();
return Utils::ToLocal(result);
}
-bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
+bool v8::Object::DeleteHiddenValue(v8::Local<v8::String> key) {
i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::DeleteHiddenValue()", return false);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return false;
i::Handle<i::String> key_obj = Utils::OpenHandle(*key);
i::Handle<i::String> key_string =
isolate->factory()->InternalizeString(key_obj);
- i::JSObject::DeleteHiddenProperty(self, key_string);
+ i::JSObject::DeleteHiddenProperty(i::Handle<i::JSObject>::cast(self),
+ key_string);
return true;
}
-namespace {
-
-static i::ElementsKind GetElementsKindFromExternalArrayType(
- ExternalArrayType array_type) {
- switch (array_type) {
-#define ARRAY_TYPE_TO_ELEMENTS_KIND(Type, type, TYPE, ctype, size) \
- case kExternal##Type##Array: \
- return i::EXTERNAL_##TYPE##_ELEMENTS;
-
- TYPED_ARRAYS(ARRAY_TYPE_TO_ELEMENTS_KIND)
-#undef ARRAY_TYPE_TO_ELEMENTS_KIND
- }
- UNREACHABLE();
- return i::DICTIONARY_ELEMENTS;
-}
-
-
-void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
- void* data,
- ExternalArrayType array_type,
- int length) {
- i::Isolate* isolate = object->GetIsolate();
- i::Handle<i::ExternalArray> array =
- isolate->factory()->NewExternalArray(length, array_type, data);
-
- i::Handle<i::Map> external_array_map =
- i::JSObject::GetElementsTransitionMap(
- object,
- GetElementsKindFromExternalArrayType(array_type));
-
- i::JSObject::SetMapAndElements(object, external_array_map, array);
-}
-
-} // namespace
-
-
-void v8::Object::SetIndexedPropertiesToPixelData(uint8_t* data, int length) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::SetElementsToPixelData()", return);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- if (!Utils::ApiCheck(length >= 0 &&
- length <= i::ExternalUint8ClampedArray::kMaxLength,
- "v8::Object::SetIndexedPropertiesToPixelData()",
- "length exceeds max acceptable value")) {
- return;
- }
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- if (!Utils::ApiCheck(!self->IsJSArray(),
- "v8::Object::SetIndexedPropertiesToPixelData()",
- "JSArray is not supported")) {
- return;
- }
- PrepareExternalArrayElements(self, data, kExternalUint8ClampedArray, length);
-}
-
-
-bool v8::Object::HasIndexedPropertiesInPixelData() {
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- ON_BAILOUT(self->GetIsolate(), "v8::HasIndexedPropertiesInPixelData()",
- return false);
- return self->HasExternalUint8ClampedElements();
-}
-
-
-uint8_t* v8::Object::GetIndexedPropertiesPixelData() {
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelData()",
- return NULL);
- if (self->HasExternalUint8ClampedElements()) {
- return i::ExternalUint8ClampedArray::cast(self->elements())->
- external_uint8_clamped_pointer();
- } else {
- return NULL;
- }
-}
-
-
-int v8::Object::GetIndexedPropertiesPixelDataLength() {
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- ON_BAILOUT(self->GetIsolate(), "v8::GetIndexedPropertiesPixelDataLength()",
- return -1);
- if (self->HasExternalUint8ClampedElements()) {
- return i::ExternalUint8ClampedArray::cast(self->elements())->length();
- } else {
- return -1;
- }
-}
-
-
-void v8::Object::SetIndexedPropertiesToExternalArrayData(
- void* data,
- ExternalArrayType array_type,
- int length) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::SetIndexedPropertiesToExternalArrayData()", return);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- if (!Utils::ApiCheck(length >= 0 && length <= i::ExternalArray::kMaxLength,
- "v8::Object::SetIndexedPropertiesToExternalArrayData()",
- "length exceeds max acceptable value")) {
- return;
- }
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- if (!Utils::ApiCheck(!self->IsJSArray(),
- "v8::Object::SetIndexedPropertiesToExternalArrayData()",
- "JSArray is not supported")) {
- return;
- }
- PrepareExternalArrayElements(self, data, array_type, length);
-}
-
-
-bool v8::Object::HasIndexedPropertiesInExternalArrayData() {
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- ON_BAILOUT(self->GetIsolate(),
- "v8::HasIndexedPropertiesInExternalArrayData()",
- return false);
- return self->HasExternalArrayElements();
-}
-
-
-void* v8::Object::GetIndexedPropertiesExternalArrayData() {
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- ON_BAILOUT(self->GetIsolate(),
- "v8::GetIndexedPropertiesExternalArrayData()",
- return NULL);
- if (self->HasExternalArrayElements()) {
- return i::ExternalArray::cast(self->elements())->external_pointer();
- } else {
- return NULL;
- }
-}
-
-
-ExternalArrayType v8::Object::GetIndexedPropertiesExternalArrayDataType() {
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- ON_BAILOUT(self->GetIsolate(),
- "v8::GetIndexedPropertiesExternalArrayDataType()",
- return static_cast<ExternalArrayType>(-1));
- switch (self->elements()->map()->instance_type()) {
-#define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \
- case i::EXTERNAL_##TYPE##_ARRAY_TYPE: \
- return kExternal##Type##Array;
- TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
-#undef INSTANCE_TYPE_TO_ARRAY_TYPE
- default:
- return static_cast<ExternalArrayType>(-1);
- }
-}
-
-
-int v8::Object::GetIndexedPropertiesExternalArrayDataLength() {
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- ON_BAILOUT(self->GetIsolate(),
- "v8::GetIndexedPropertiesExternalArrayDataLength()",
- return 0);
- if (self->HasExternalArrayElements()) {
- return i::ExternalArray::cast(self->elements())->length();
- } else {
- return -1;
- }
-}
-
-
bool v8::Object::IsCallable() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::IsCallable()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
- return obj->IsCallable();
+ auto self = Utils::OpenHandle(this);
+ return self->IsCallable();
}
-Local<v8::Value> Object::CallAsFunction(v8::Handle<v8::Value> recv,
- int argc,
- v8::Handle<v8::Value> argv[]) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::CallAsFunction()",
- return Local<v8::Value>());
- LOG_API(isolate, "Object::CallAsFunction");
- ENTER_V8(isolate);
+MaybeLocal<Value> Object::CallAsFunction(Local<Context> context,
+ Local<Value> recv, int argc,
+ Local<Value> argv[]) {
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Object::CallAsFunction()",
+ Value);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
- i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
- STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
+ auto self = Utils::OpenHandle(this);
+ auto recv_obj = Utils::OpenHandle(*recv);
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
- i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>();
- if (obj->IsJSFunction()) {
- fun = i::Handle<i::JSFunction>::cast(obj);
- } else {
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> delegate;
- has_pending_exception = !i::Execution::TryGetFunctionDelegate(
- isolate, obj).ToHandle(&delegate);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
- fun = i::Handle<i::JSFunction>::cast(delegate);
- recv_obj = obj;
- }
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned;
- has_pending_exception = !i::Execution::Call(
- isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Value>());
- return Utils::ToLocal(scope.CloseAndEscape(returned));
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(
+ i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<v8::Value> Object::CallAsFunction(v8::Local<v8::Value> recv, int argc,
+ v8::Local<v8::Value> argv[]) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
+ RETURN_TO_LOCAL_UNCHECKED(CallAsFunction(context, recv, argc, argv_cast),
+ Value);
+}
+
+
+MaybeLocal<Value> Object::CallAsConstructor(Local<Context> context, int argc,
+ Local<Value> argv[]) {
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context,
+ "v8::Object::CallAsConstructor()", Value);
+ i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
+ auto self = Utils::OpenHandle(this);
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
+ i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(
+ i::Execution::New(isolate, self, self, argc, args), &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
}
Local<v8::Value> Object::CallAsConstructor(int argc,
- v8::Handle<v8::Value> argv[]) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Object::CallAsConstructor()",
- return Local<v8::Object>());
- LOG_API(isolate, "Object::CallAsConstructor");
- ENTER_V8(isolate);
- i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
- STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
- i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
- if (obj->IsJSFunction()) {
- i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(obj);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned;
- has_pending_exception = !i::Execution::New(
- fun, argc, args).ToHandle(&returned);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
- return Utils::ToLocal(scope.CloseAndEscape(
- i::Handle<i::JSObject>::cast(returned)));
- }
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> delegate;
- has_pending_exception = !i::Execution::TryGetConstructorDelegate(
- isolate, obj).ToHandle(&delegate);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
- if (!delegate->IsUndefined()) {
- i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(delegate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned;
- has_pending_exception = !i::Execution::Call(
- isolate, fun, obj, argc, args).ToHandle(&returned);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
- DCHECK(!delegate->IsUndefined());
- return Utils::ToLocal(scope.CloseAndEscape(returned));
- }
- return Local<v8::Object>();
+ v8::Local<v8::Value> argv[]) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ Local<Value>* argv_cast = reinterpret_cast<Local<Value>*>(argv);
+ RETURN_TO_LOCAL_UNCHECKED(CallAsConstructor(context, argc, argv_cast), Value);
}
-Local<Function> Function::New(Isolate* v8_isolate,
- FunctionCallback callback,
- Local<Value> data,
- int length) {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+MaybeLocal<Function> Function::New(Local<Context> context,
+ FunctionCallback callback, Local<Value> data,
+ int length) {
+ i::Isolate* isolate = Utils::OpenHandle(*context)->GetIsolate();
LOG_API(isolate, "Function::New");
ENTER_V8(isolate);
- return FunctionTemplateNew(
- isolate, callback, data, Local<Signature>(), length, true)->
- GetFunction();
+ return FunctionTemplateNew(isolate, callback, nullptr, data,
+ Local<Signature>(), length, true)
+ ->GetFunction(context);
+}
+
+
+Local<Function> Function::New(Isolate* v8_isolate, FunctionCallback callback,
+ Local<Value> data, int length) {
+ return Function::New(v8_isolate->GetCurrentContext(), callback, data, length)
+ .FromMaybe(Local<Function>());
}
Local<v8::Object> Function::NewInstance() const {
- return NewInstance(0, NULL);
+ return NewInstance(Isolate::GetCurrent()->GetCurrentContext(), 0, NULL)
+ .FromMaybe(Local<Object>());
+}
+
+
+MaybeLocal<Object> Function::NewInstance(Local<Context> context, int argc,
+ v8::Local<v8::Value> argv[]) const {
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::NewInstance()",
+ Object);
+ i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
+ auto self = Utils::OpenHandle(this);
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
+ i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
+ Local<Object> result;
+ has_pending_exception = !ToLocal<Object>(
+ i::Execution::New(isolate, self, self, argc, args), &result);
+ RETURN_ON_FAILED_EXECUTION(Object);
+ RETURN_ESCAPED(result);
}
Local<v8::Object> Function::NewInstance(int argc,
- v8::Handle<v8::Value> argv[]) const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Function::NewInstance()",
- return Local<v8::Object>());
- LOG_API(isolate, "Function::NewInstance");
- ENTER_V8(isolate);
- i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
- i::Handle<i::JSFunction> function = Utils::OpenHandle(this);
- STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
- i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned;
- has_pending_exception = !i::Execution::New(
- function, argc, args).ToHandle(&returned);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<v8::Object>());
- return scope.Escape(Utils::ToLocal(i::Handle<i::JSObject>::cast(returned)));
+ v8::Local<v8::Value> argv[]) const {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(NewInstance(context, argc, argv), Object);
}
-Local<v8::Value> Function::Call(v8::Handle<v8::Value> recv, int argc,
- v8::Handle<v8::Value> argv[]) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Function::Call()", return Local<v8::Value>());
- LOG_API(isolate, "Function::Call");
- ENTER_V8(isolate);
+MaybeLocal<v8::Value> Function::Call(Local<Context> context,
+ v8::Local<v8::Value> recv, int argc,
+ v8::Local<v8::Value> argv[]) {
+ PREPARE_FOR_EXECUTION_WITH_CALLBACK(context, "v8::Function::Call()", Value);
i::TimerEventScope<i::TimerEventExecute> timer_scope(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::JSFunction> fun = Utils::OpenHandle(this);
+ auto self = Utils::OpenHandle(this);
i::Handle<i::Object> recv_obj = Utils::OpenHandle(*recv);
- STATIC_ASSERT(sizeof(v8::Handle<v8::Value>) == sizeof(i::Object**));
+ STATIC_ASSERT(sizeof(v8::Local<v8::Value>) == sizeof(i::Object**));
i::Handle<i::Object>* args = reinterpret_cast<i::Handle<i::Object>*>(argv);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> returned;
- has_pending_exception = !i::Execution::Call(
- isolate, fun, recv_obj, argc, args, true).ToHandle(&returned);
- EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, Local<Object>());
- return Utils::ToLocal(scope.CloseAndEscape(returned));
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(
+ i::Execution::Call(isolate, self, recv_obj, argc, args), &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
}
-void Function::SetName(v8::Handle<v8::String> name) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ENTER_V8(isolate);
- USE(isolate);
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+Local<v8::Value> Function::Call(v8::Local<v8::Value> recv, int argc,
+ v8::Local<v8::Value> argv[]) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(Call(context, recv, argc, argv), Value);
+}
+
+
+void Function::SetName(v8::Local<v8::String> name) {
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) return;
+ auto func = i::Handle<i::JSFunction>::cast(self);
func->shared()->set_name(*Utils::OpenHandle(*name));
}
-Handle<Value> Function::GetName() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
- return Utils::ToLocal(i::Handle<i::Object>(func->shared()->name(),
- func->GetIsolate()));
+Local<Value> Function::GetName() const {
+ auto self = Utils::OpenHandle(this);
+ if (self->IsJSBoundFunction()) {
+ auto func = i::Handle<i::JSBoundFunction>::cast(self);
+ return Utils::ToLocal(handle(func->name(), func->GetIsolate()));
+ }
+ if (self->IsJSFunction()) {
+ auto func = i::Handle<i::JSFunction>::cast(self);
+ return Utils::ToLocal(handle(func->shared()->name(), func->GetIsolate()));
+ }
+ return ToApiHandle<Primitive>(
+ self->GetIsolate()->factory()->undefined_value());
}
-Handle<Value> Function::GetInferredName() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+Local<Value> Function::GetInferredName() const {
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return ToApiHandle<Primitive>(
+ self->GetIsolate()->factory()->undefined_value());
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
return Utils::ToLocal(i::Handle<i::Object>(func->shared()->inferred_name(),
func->GetIsolate()));
}
-Handle<Value> Function::GetDisplayName() const {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Function::GetDisplayName()",
- return ToApiHandle<Primitive>(
- isolate->factory()->undefined_value()));
- ENTER_V8(isolate);
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
- i::Handle<i::String> property_name =
- isolate->factory()->InternalizeOneByteString(
- STATIC_CHAR_VECTOR("displayName"));
+Local<Value> Function::GetDebugName() const {
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return ToApiHandle<Primitive>(
+ self->GetIsolate()->factory()->undefined_value());
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
+ i::Handle<i::String> name = i::JSFunction::GetDebugName(func);
+ return Utils::ToLocal(i::Handle<i::Object>(*name, name->GetIsolate()));
+}
+
+Local<Value> Function::GetDisplayName() const {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ ENTER_V8(isolate);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
+ i::Handle<i::String> property_name =
+ isolate->factory()->NewStringFromStaticChars("displayName");
i::Handle<i::Object> value =
- i::JSObject::GetDataProperty(func, property_name);
+ i::JSReceiver::GetDataProperty(func, property_name);
if (value->IsString()) {
i::Handle<i::String> name = i::Handle<i::String>::cast(value);
if (name->length() > 0) return Utils::ToLocal(name);
}
-
return ToApiHandle<Primitive>(isolate->factory()->undefined_value());
}
ScriptOrigin Function::GetScriptOrigin() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return v8::ScriptOrigin(Local<Value>());
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
if (func->shared()->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
- i::Handle<i::Object> scriptName = i::Script::GetNameOrSourceURL(script);
- v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(func->GetIsolate());
- v8::ScriptOrigin origin(
- Utils::ToLocal(scriptName),
- v8::Integer::New(isolate, script->line_offset()->value()),
- v8::Integer::New(isolate, script->column_offset()->value()));
- return origin;
+ return GetScriptOriginForScript(func->GetIsolate(), script);
}
- return v8::ScriptOrigin(Handle<Value>());
+ return v8::ScriptOrigin(Local<Value>());
}
@@ -4251,7 +4483,11 @@
int Function::GetScriptLineNumber() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return kLineOffsetNotFound;
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
if (func->shared()->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
return i::Script::GetLineNumber(script, func->shared()->start_position());
@@ -4261,7 +4497,11 @@
int Function::GetScriptColumnNumber() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return kLineOffsetNotFound;
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
if (func->shared()->script()->IsScript()) {
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
return i::Script::GetColumnNumber(script, func->shared()->start_position());
@@ -4271,41 +4511,43 @@
bool Function::IsBuiltin() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
- return func->IsBuiltin();
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return false;
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
+ return func->shared()->IsBuiltin();
}
int Function::ScriptId() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
+ auto self = Utils::OpenHandle(this);
+ if (!self->IsJSFunction()) {
+ return v8::UnboundScript::kNoScriptId;
+ }
+ auto func = i::Handle<i::JSFunction>::cast(self);
if (!func->shared()->script()->IsScript()) {
return v8::UnboundScript::kNoScriptId;
}
i::Handle<i::Script> script(i::Script::cast(func->shared()->script()));
- return script->id()->value();
+ return script->id();
}
Local<v8::Value> Function::GetBoundFunction() const {
- i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
- if (!func->shared()->bound()) {
- return v8::Undefined(reinterpret_cast<v8::Isolate*>(func->GetIsolate()));
+ auto self = Utils::OpenHandle(this);
+ if (self->IsJSBoundFunction()) {
+ auto bound_function = i::Handle<i::JSBoundFunction>::cast(self);
+ auto bound_target_function = i::handle(
+ bound_function->bound_target_function(), bound_function->GetIsolate());
+ return Utils::CallableToLocal(bound_target_function);
}
- i::Handle<i::FixedArray> bound_args = i::Handle<i::FixedArray>(
- i::FixedArray::cast(func->function_bindings()));
- i::Handle<i::Object> original(
- bound_args->get(i::JSFunction::kBoundFunctionIndex),
- func->GetIsolate());
- return Utils::ToLocal(i::Handle<i::JSFunction>::cast(original));
+ return v8::Undefined(reinterpret_cast<v8::Isolate*>(self->GetIsolate()));
}
int Name::GetIdentityHash() {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Name::GetIdentityHash()", return 0);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::Name> self = Utils::OpenHandle(this);
+ auto self = Utils::OpenHandle(this);
return static_cast<int>(self->Hash());
}
@@ -4560,7 +4802,7 @@
}
static int Calculate(i::ConsString* current, uint8_t* state_out) {
- using namespace internal;
+ using internal::ConsString;
int total_length = 0;
uint8_t state = kInitialState;
while (true) {
@@ -4660,26 +4902,22 @@
int remaining,
char* const buffer,
bool replace_invalid_utf8) {
- using namespace unibrow;
- DCHECK(remaining > 0);
+ DCHECK_GT(remaining, 0);
// We can't use a local buffer here because Encode needs to modify
// previous characters in the stream. We know, however, that
// exactly one character will be advanced.
- if (Utf16::IsSurrogatePair(last_character, character)) {
- int written = Utf8::Encode(buffer,
- character,
- last_character,
- replace_invalid_utf8);
- DCHECK(written == 1);
+ if (unibrow::Utf16::IsSurrogatePair(last_character, character)) {
+ int written = unibrow::Utf8::Encode(buffer, character, last_character,
+ replace_invalid_utf8);
+ DCHECK_EQ(written, 1);
return written;
}
// Use a scratch buffer to check the required characters.
- char temp_buffer[Utf8::kMaxEncodedSize];
+ char temp_buffer[unibrow::Utf8::kMaxEncodedSize];
// Can't encode using last_character as gcc has array bounds issues.
- int written = Utf8::Encode(temp_buffer,
- character,
- Utf16::kNoPreviousCharacter,
- replace_invalid_utf8);
+ int written = unibrow::Utf8::Encode(temp_buffer, character,
+ unibrow::Utf16::kNoPreviousCharacter,
+ replace_invalid_utf8);
// Won't fit.
if (written > remaining) return 0;
// Copy over the character from temp_buffer.
@@ -4701,13 +4939,13 @@
// unit, or all units have been written out.
template<typename Char>
void Visit(const Char* chars, const int length) {
- using namespace unibrow;
DCHECK(!early_termination_);
if (length == 0) return;
// Copy state to stack.
char* buffer = buffer_;
- int last_character =
- sizeof(Char) == 1 ? Utf16::kNoPreviousCharacter : last_character_;
+ int last_character = sizeof(Char) == 1
+ ? unibrow::Utf16::kNoPreviousCharacter
+ : last_character_;
int i = 0;
// Do a fast loop where there is no exit capacity check.
while (true) {
@@ -4717,7 +4955,8 @@
} else {
int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
// Need enough space to write everything but one character.
- STATIC_ASSERT(Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit == 3);
+ STATIC_ASSERT(unibrow::Utf16::kMaxExtraUtf8BytesForOneUtf16CodeUnit ==
+ 3);
int max_size_per_char = sizeof(Char) == 1 ? 2 : 3;
int writable_length =
(remaining_capacity - max_size_per_char)/max_size_per_char;
@@ -4729,17 +4968,15 @@
// Write the characters to the stream.
if (sizeof(Char) == 1) {
for (; i < fast_length; i++) {
- buffer +=
- Utf8::EncodeOneByte(buffer, static_cast<uint8_t>(*chars++));
+ buffer += unibrow::Utf8::EncodeOneByte(
+ buffer, static_cast<uint8_t>(*chars++));
DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
}
} else {
for (; i < fast_length; i++) {
uint16_t character = *chars++;
- buffer += Utf8::Encode(buffer,
- character,
- last_character,
- replace_invalid_utf8_);
+ buffer += unibrow::Utf8::Encode(buffer, character, last_character,
+ replace_invalid_utf8_);
last_character = character;
DCHECK(capacity_ == -1 || (buffer - start_) <= capacity_);
}
@@ -4756,12 +4993,12 @@
DCHECK(!skip_capacity_check_);
// Slow loop. Must check capacity on each iteration.
int remaining_capacity = capacity_ - static_cast<int>(buffer - start_);
- DCHECK(remaining_capacity >= 0);
+ DCHECK_GE(remaining_capacity, 0);
for (; i < length && remaining_capacity > 0; i++) {
uint16_t character = *chars++;
// remaining_capacity is <= 3 bytes at this point, so we do not write out
// an umatched lead surrogate.
- if (replace_invalid_utf8_ && Utf16::IsLeadSurrogate(character)) {
+ if (replace_invalid_utf8_ && unibrow::Utf16::IsLeadSurrogate(character)) {
early_termination_ = true;
break;
}
@@ -4905,7 +5142,6 @@
ENTER_V8(isolate);
DCHECK(start >= 0 && length >= -1);
i::Handle<i::String> str = Utils::OpenHandle(string);
- isolate->string_tracker()->RecordWrite(str);
if (options & String::HINT_MANY_WRITES_EXPECTED) {
// Flatten the string for efficiency. This applies whether we are
// using StringCharacterStream or Get(i) to access the characters.
@@ -5058,52 +5294,56 @@
int v8::Object::InternalFieldCount() {
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
- return obj->GetInternalFieldCount();
+ i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
+ if (!self->IsJSObject()) return 0;
+ return i::Handle<i::JSObject>::cast(self)->GetInternalFieldCount();
}
-static bool InternalFieldOK(i::Handle<i::JSObject> obj,
- int index,
+static bool InternalFieldOK(i::Handle<i::JSReceiver> obj, int index,
const char* location) {
- return Utils::ApiCheck(index < obj->GetInternalFieldCount(),
- location,
- "Internal field out of bounds");
+ return Utils::ApiCheck(
+ obj->IsJSObject() &&
+ (index < i::Handle<i::JSObject>::cast(obj)->GetInternalFieldCount()),
+ location, "Internal field out of bounds");
}
Local<Value> v8::Object::SlowGetInternalField(int index) {
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::GetInternalField()";
if (!InternalFieldOK(obj, index, location)) return Local<Value>();
- i::Handle<i::Object> value(obj->GetInternalField(index), obj->GetIsolate());
+ i::Handle<i::Object> value(
+ i::Handle<i::JSObject>::cast(obj)->GetInternalField(index),
+ obj->GetIsolate());
return Utils::ToLocal(value);
}
-void v8::Object::SetInternalField(int index, v8::Handle<Value> value) {
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+void v8::Object::SetInternalField(int index, v8::Local<Value> value) {
+ i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::SetInternalField()";
if (!InternalFieldOK(obj, index, location)) return;
i::Handle<i::Object> val = Utils::OpenHandle(*value);
- obj->SetInternalField(index, *val);
- DCHECK_EQ(value, GetInternalField(index));
+ i::Handle<i::JSObject>::cast(obj)->SetInternalField(index, *val);
}
void* v8::Object::SlowGetAlignedPointerFromInternalField(int index) {
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::GetAlignedPointerFromInternalField()";
if (!InternalFieldOK(obj, index, location)) return NULL;
- return DecodeSmiToAligned(obj->GetInternalField(index), location);
+ return DecodeSmiToAligned(
+ i::Handle<i::JSObject>::cast(obj)->GetInternalField(index), location);
}
void v8::Object::SetAlignedPointerInInternalField(int index, void* value) {
- i::Handle<i::JSObject> obj = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> obj = Utils::OpenHandle(this);
const char* location = "v8::Object::SetAlignedPointerInInternalField()";
if (!InternalFieldOK(obj, index, location)) return;
- obj->SetInternalField(index, EncodeAlignedAsSmi(value, location));
+ i::Handle<i::JSObject>::cast(obj)
+ ->SetInternalField(index, EncodeAlignedAsSmi(value, location));
DCHECK_EQ(value, GetAlignedPointerFromInternalField(index));
}
@@ -5128,12 +5368,12 @@
i::V8::ShutdownPlatform();
}
-v8::Platform* v8::V8::GetCurrentPlatform() {
- return i::V8::GetCurrentPlatform();
-}
bool v8::V8::Initialize() {
i::V8::Initialize();
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ i::ReadNatives();
+#endif
return true;
}
@@ -5145,21 +5385,15 @@
void v8::V8::SetReturnAddressLocationResolver(
ReturnAddressLocationResolver return_address_resolver) {
- i::V8::SetReturnAddressLocationResolver(return_address_resolver);
-}
-
-void v8::V8::SetArrayBufferAllocator(
- ArrayBuffer::Allocator* allocator) {
- if (!Utils::ApiCheck(i::V8::ArrayBufferAllocator() == NULL,
- "v8::V8::SetArrayBufferAllocator",
- "ArrayBufferAllocator might only be set once"))
- return;
- i::V8::SetArrayBufferAllocator(allocator);
+ i::StackFrame::SetReturnAddressLocationResolver(return_address_resolver);
}
bool v8::V8::Dispose() {
i::V8::TearDown();
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ i::DisposeNatives();
+#endif
return true;
}
@@ -5171,27 +5405,51 @@
heap_size_limit_(0) { }
+HeapSpaceStatistics::HeapSpaceStatistics(): space_name_(0),
+ space_size_(0),
+ space_used_size_(0),
+ space_available_size_(0),
+ physical_space_size_(0) { }
+
+
+HeapObjectStatistics::HeapObjectStatistics()
+ : object_type_(nullptr),
+ object_sub_type_(nullptr),
+ object_count_(0),
+ object_size_(0) {}
+
+
bool v8::V8::InitializeICU(const char* icu_data_file) {
return i::InitializeICU(icu_data_file);
}
+void v8::V8::InitializeExternalStartupData(const char* directory_path) {
+ i::InitializeExternalStartupData(directory_path);
+}
+
+
+void v8::V8::InitializeExternalStartupData(const char* natives_blob,
+ const char* snapshot_blob) {
+ i::InitializeExternalStartupData(natives_blob, snapshot_blob);
+}
+
+
const char* v8::V8::GetVersion() {
return i::Version::GetVersion();
}
static i::Handle<i::Context> CreateEnvironment(
- i::Isolate* isolate,
- v8::ExtensionConfiguration* extensions,
- v8::Handle<ObjectTemplate> global_template,
- v8::Handle<Value> maybe_global_proxy) {
+ i::Isolate* isolate, v8::ExtensionConfiguration* extensions,
+ v8::Local<ObjectTemplate> global_template,
+ v8::Local<Value> maybe_global_proxy) {
i::Handle<i::Context> env;
// Enter V8 via an ENTER_V8 scope.
{
ENTER_V8(isolate);
- v8::Handle<ObjectTemplate> proxy_template = global_template;
+ v8::Local<ObjectTemplate> proxy_template = global_template;
i::Handle<i::FunctionTemplateInfo> proxy_constructor;
i::Handle<i::FunctionTemplateInfo> global_constructor;
@@ -5247,28 +5505,29 @@
return env;
}
-Local<Context> v8::Context::New(
- v8::Isolate* external_isolate,
- v8::ExtensionConfiguration* extensions,
- v8::Handle<ObjectTemplate> global_template,
- v8::Handle<Value> global_object) {
+Local<Context> v8::Context::New(v8::Isolate* external_isolate,
+ v8::ExtensionConfiguration* extensions,
+ v8::Local<ObjectTemplate> global_template,
+ v8::Local<Value> global_object) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(external_isolate);
LOG_API(isolate, "Context::New");
- ON_BAILOUT(isolate, "v8::Context::New()", return Local<Context>());
i::HandleScope scope(isolate);
ExtensionConfiguration no_extensions;
if (extensions == NULL) extensions = &no_extensions;
i::Handle<i::Context> env =
CreateEnvironment(isolate, extensions, global_template, global_object);
- if (env.is_null()) return Local<Context>();
+ if (env.is_null()) {
+ if (isolate->has_pending_exception()) {
+ isolate->OptionalRescheduleException(true);
+ }
+ return Local<Context>();
+ }
return Utils::ToLocal(scope.CloseAndEscape(env));
}
-void v8::Context::SetSecurityToken(Handle<Value> token) {
+void v8::Context::SetSecurityToken(Local<Value> token) {
i::Handle<i::Context> env = Utils::OpenHandle(this);
- i::Isolate* isolate = env->GetIsolate();
- ENTER_V8(isolate);
i::Handle<i::Object> token_handle = Utils::OpenHandle(*token);
env->set_security_token(*token_handle);
}
@@ -5276,13 +5535,11 @@
void v8::Context::UseDefaultSecurityToken() {
i::Handle<i::Context> env = Utils::OpenHandle(this);
- i::Isolate* isolate = env->GetIsolate();
- ENTER_V8(isolate);
env->set_security_token(env->global_object());
}
-Handle<Value> v8::Context::GetSecurityToken() {
+Local<Value> v8::Context::GetSecurityToken() {
i::Handle<i::Context> env = Utils::OpenHandle(this);
i::Isolate* isolate = env->GetIsolate();
i::Object* security_token = env->security_token();
@@ -5319,6 +5576,14 @@
}
+Local<v8::Object> Context::GetExtrasBindingObject() {
+ i::Handle<i::Context> context = Utils::OpenHandle(this);
+ i::Isolate* isolate = context->GetIsolate();
+ i::Handle<i::JSObject> binding(context->extras_binding_object(), isolate);
+ return Utils::ToLocal(binding);
+}
+
+
void Context::AllowCodeGenerationFromStrings(bool allow) {
i::Handle<i::Context> context = Utils::OpenHandle(this);
i::Isolate* isolate = context->GetIsolate();
@@ -5334,51 +5599,58 @@
}
-void Context::SetErrorMessageForCodeGenerationFromStrings(
- Handle<String> error) {
+void Context::SetErrorMessageForCodeGenerationFromStrings(Local<String> error) {
i::Handle<i::Context> context = Utils::OpenHandle(this);
i::Handle<i::String> error_handle = Utils::OpenHandle(*error);
context->set_error_message_for_code_gen_from_strings(*error_handle);
}
+size_t Context::EstimatedSize() {
+ return static_cast<size_t>(
+ i::ContextMeasure(*Utils::OpenHandle(this)).Size());
+}
+
+
+MaybeLocal<v8::Object> ObjectTemplate::NewInstance(Local<Context> context) {
+ PREPARE_FOR_EXECUTION(context, "v8::ObjectTemplate::NewInstance()", Object);
+ auto self = Utils::OpenHandle(this);
+ Local<Object> result;
+ has_pending_exception =
+ !ToLocal<Object>(i::ApiNatives::InstantiateObject(self), &result);
+ RETURN_ON_FAILED_EXECUTION(Object);
+ RETURN_ESCAPED(result);
+}
+
+
Local<v8::Object> ObjectTemplate::NewInstance() {
- i::Handle<i::ObjectTemplateInfo> info = Utils::OpenHandle(this);
- i::Isolate* isolate = info->GetIsolate();
- ON_BAILOUT(isolate, "v8::ObjectTemplate::NewInstance()",
- return Local<v8::Object>());
- LOG_API(isolate, "ObjectTemplate::NewInstance");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj;
- has_pending_exception = !i::Execution::InstantiateObject(info).ToHandle(&obj);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Object>());
- return Utils::ToLocal(i::Handle<i::JSObject>::cast(obj));
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(NewInstance(context), Object);
+}
+
+
+MaybeLocal<v8::Function> FunctionTemplate::GetFunction(Local<Context> context) {
+ PREPARE_FOR_EXECUTION(context, "v8::FunctionTemplate::GetFunction()",
+ Function);
+ auto self = Utils::OpenHandle(this);
+ Local<Function> result;
+ has_pending_exception =
+ !ToLocal<Function>(i::ApiNatives::InstantiateFunction(self), &result);
+ RETURN_ON_FAILED_EXECUTION(Function);
+ RETURN_ESCAPED(result);
}
Local<v8::Function> FunctionTemplate::GetFunction() {
- i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
- i::Isolate* isolate = info->GetIsolate();
- ON_BAILOUT(isolate, "v8::FunctionTemplate::GetFunction()",
- return Local<v8::Function>());
- LOG_API(isolate, "FunctionTemplate::GetFunction");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> obj;
- has_pending_exception =
- !i::Execution::InstantiateFunction(info).ToHandle(&obj);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::Function>());
- return Utils::ToLocal(i::Handle<i::JSFunction>::cast(obj));
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(GetFunction(context), Function);
}
-bool FunctionTemplate::HasInstance(v8::Handle<v8::Value> value) {
- i::Handle<i::FunctionTemplateInfo> info = Utils::OpenHandle(this);
- i::Isolate* isolate = info->GetIsolate();
- ON_BAILOUT(isolate, "v8::FunctionTemplate::HasInstanceOf()", return false);
- i::Object* obj = *Utils::OpenHandle(*value);
- return info->IsTemplateFor(obj);
+bool FunctionTemplate::HasInstance(v8::Local<v8::Value> value) {
+ auto self = Utils::OpenHandle(this);
+ auto obj = Utils::OpenHandle(*value);
+ return self->IsTemplateFor(*obj);
}
@@ -5420,9 +5692,9 @@
MUST_USE_RESULT
inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
+ v8::NewStringType type,
i::Vector<const char> string) {
- if (type == String::kInternalizedString) {
+ if (type == v8::NewStringType::kInternalized) {
return factory->InternalizeUtf8String(string);
}
return factory->NewStringFromUtf8(string);
@@ -5431,9 +5703,9 @@
MUST_USE_RESULT
inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
+ v8::NewStringType type,
i::Vector<const uint8_t> string) {
- if (type == String::kInternalizedString) {
+ if (type == v8::NewStringType::kInternalized) {
return factory->InternalizeOneByteString(string);
}
return factory->NewStringFromOneByte(string);
@@ -5442,37 +5714,32 @@
MUST_USE_RESULT
inline i::MaybeHandle<i::String> NewString(i::Factory* factory,
- String::NewStringType type,
+ v8::NewStringType type,
i::Vector<const uint16_t> string) {
- if (type == String::kInternalizedString) {
+ if (type == v8::NewStringType::kInternalized) {
return factory->InternalizeTwoByteString(string);
}
return factory->NewStringFromTwoByte(string);
}
-template<typename Char>
-inline Local<String> NewString(Isolate* v8_isolate,
- const char* location,
- const char* env,
- const Char* data,
- String::NewStringType type,
- int length) {
+STATIC_ASSERT(v8::String::kMaxLength == i::String::kMaxLength);
+
+
+template <typename Char>
+inline MaybeLocal<String> NewString(Isolate* v8_isolate, const char* location,
+ const char* env, const Char* data,
+ v8::NewStringType type, int length) {
i::Isolate* isolate = reinterpret_cast<internal::Isolate*>(v8_isolate);
- LOG_API(isolate, env);
- if (length == 0 && type != String::kUndetectableString) {
- return String::Empty(v8_isolate);
- }
+ if (length == 0) return String::Empty(v8_isolate);
+ // TODO(dcarney): throw a context free exception.
+ if (length > i::String::kMaxLength) return MaybeLocal<String>();
ENTER_V8(isolate);
- if (length == -1) length = StringLength(data);
- // We do not expect this to fail. Change this if it does.
- i::Handle<i::String> result = NewString(
- isolate->factory(),
- type,
- i::Vector<const Char>(data, length)).ToHandleChecked();
- if (type == String::kUndetectableString) {
- result->MarkAsUndetectable();
- }
+ LOG_API(isolate, env);
+ if (length < 0) length = StringLength(data);
+ i::Handle<i::String> result =
+ NewString(isolate->factory(), type, i::Vector<const Char>(data, length))
+ .ToHandleChecked();
return Utils::ToLocal(result);
}
@@ -5483,12 +5750,17 @@
const char* data,
NewStringType type,
int length) {
- return NewString(isolate,
- "v8::String::NewFromUtf8()",
- "String::NewFromUtf8",
- data,
- type,
- length);
+ RETURN_TO_LOCAL_UNCHECKED(
+ NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
+ data, static_cast<v8::NewStringType>(type), length),
+ String);
+}
+
+
+MaybeLocal<String> String::NewFromUtf8(Isolate* isolate, const char* data,
+ v8::NewStringType type, int length) {
+ return NewString(isolate, "v8::String::NewFromUtf8()", "String::NewFromUtf8",
+ data, type, length);
}
@@ -5496,12 +5768,18 @@
const uint8_t* data,
NewStringType type,
int length) {
- return NewString(isolate,
- "v8::String::NewFromOneByte()",
- "String::NewFromOneByte",
- data,
- type,
- length);
+ RETURN_TO_LOCAL_UNCHECKED(
+ NewString(isolate, "v8::String::NewFromOneByte()",
+ "String::NewFromOneByte", data,
+ static_cast<v8::NewStringType>(type), length),
+ String);
+}
+
+
+MaybeLocal<String> String::NewFromOneByte(Isolate* isolate, const uint8_t* data,
+ v8::NewStringType type, int length) {
+ return NewString(isolate, "v8::String::NewFromOneByte()",
+ "String::NewFromOneByte", data, type, length);
}
@@ -5509,20 +5787,27 @@
const uint16_t* data,
NewStringType type,
int length) {
- return NewString(isolate,
- "v8::String::NewFromTwoByte()",
- "String::NewFromTwoByte",
- data,
- type,
- length);
+ RETURN_TO_LOCAL_UNCHECKED(
+ NewString(isolate, "v8::String::NewFromTwoByte()",
+ "String::NewFromTwoByte", data,
+ static_cast<v8::NewStringType>(type), length),
+ String);
}
-Local<String> v8::String::Concat(Handle<String> left, Handle<String> right) {
+MaybeLocal<String> String::NewFromTwoByte(Isolate* isolate,
+ const uint16_t* data,
+ v8::NewStringType type, int length) {
+ return NewString(isolate, "v8::String::NewFromTwoByte()",
+ "String::NewFromTwoByte", data, type, length);
+}
+
+
+Local<String> v8::String::Concat(Local<String> left, Local<String> right) {
i::Handle<i::String> left_string = Utils::OpenHandle(*left);
i::Isolate* isolate = left_string->GetIsolate();
- LOG_API(isolate, "String::New(char)");
ENTER_V8(isolate);
+ LOG_API(isolate, "v8::String::Concat");
i::Handle<i::String> right_string = Utils::OpenHandle(*right);
// If we are steering towards a range error, do not wait for the error to be
// thrown, and return the null handle instead.
@@ -5535,35 +5820,54 @@
}
-static i::MaybeHandle<i::String> NewExternalStringHandle(
- i::Isolate* isolate, v8::String::ExternalStringResource* resource) {
- return isolate->factory()->NewExternalStringFromTwoByte(resource);
-}
-
-
-static i::MaybeHandle<i::String> NewExternalOneByteStringHandle(
- i::Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
- return isolate->factory()->NewExternalStringFromOneByte(resource);
+MaybeLocal<String> v8::String::NewExternalTwoByte(
+ Isolate* isolate, v8::String::ExternalStringResource* resource) {
+ CHECK(resource && resource->data());
+ // TODO(dcarney): throw a context free exception.
+ if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
+ return MaybeLocal<String>();
+ }
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ LOG_API(i_isolate, "String::NewExternalTwoByte");
+ i::Handle<i::String> string = i_isolate->factory()
+ ->NewExternalStringFromTwoByte(resource)
+ .ToHandleChecked();
+ i_isolate->heap()->RegisterExternalString(*string);
+ return Utils::ToLocal(string);
}
Local<String> v8::String::NewExternal(
- Isolate* isolate,
- v8::String::ExternalStringResource* resource) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "String::NewExternal");
- ENTER_V8(i_isolate);
+ Isolate* isolate, v8::String::ExternalStringResource* resource) {
+ RETURN_TO_LOCAL_UNCHECKED(NewExternalTwoByte(isolate, resource), String);
+}
+
+
+MaybeLocal<String> v8::String::NewExternalOneByte(
+ Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
CHECK(resource && resource->data());
- EXCEPTION_PREAMBLE(i_isolate);
- i::Handle<i::String> string;
- has_pending_exception =
- !NewExternalStringHandle(i_isolate, resource).ToHandle(&string);
- EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
- i_isolate->heap()->external_string_table()->AddString(*string);
+ // TODO(dcarney): throw a context free exception.
+ if (resource->length() > static_cast<size_t>(i::String::kMaxLength)) {
+ return MaybeLocal<String>();
+ }
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ LOG_API(i_isolate, "String::NewExternalOneByte");
+ i::Handle<i::String> string = i_isolate->factory()
+ ->NewExternalStringFromOneByte(resource)
+ .ToHandleChecked();
+ i_isolate->heap()->RegisterExternalString(*string);
return Utils::ToLocal(string);
}
+Local<String> v8::String::NewExternal(
+ Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
+ RETURN_TO_LOCAL_UNCHECKED(NewExternalOneByte(isolate, resource), String);
+}
+
+
bool v8::String::MakeExternal(v8::String::ExternalStringResource* resource) {
i::Handle<i::String> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
@@ -5571,9 +5875,6 @@
return false; // Already an external string.
}
ENTER_V8(isolate);
- if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
- return false;
- }
if (isolate->heap()->IsInGCPostProcessing()) {
return false;
}
@@ -5584,28 +5885,12 @@
DCHECK(!CanMakeExternal() || result);
if (result) {
DCHECK(obj->IsExternalString());
- isolate->heap()->external_string_table()->AddString(*obj);
+ isolate->heap()->RegisterExternalString(*obj);
}
return result;
}
-Local<String> v8::String::NewExternal(
- Isolate* isolate, v8::String::ExternalOneByteStringResource* resource) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "String::NewExternal");
- ENTER_V8(i_isolate);
- CHECK(resource && resource->data());
- EXCEPTION_PREAMBLE(i_isolate);
- i::Handle<i::String> string;
- has_pending_exception =
- !NewExternalOneByteStringHandle(i_isolate, resource).ToHandle(&string);
- EXCEPTION_BAILOUT_CHECK(i_isolate, Local<String>());
- i_isolate->heap()->external_string_table()->AddString(*string);
- return Utils::ToLocal(string);
-}
-
-
bool v8::String::MakeExternal(
v8::String::ExternalOneByteStringResource* resource) {
i::Handle<i::String> obj = Utils::OpenHandle(this);
@@ -5614,9 +5899,6 @@
return false; // Already an external string.
}
ENTER_V8(isolate);
- if (isolate->string_tracker()->IsFreshUnusedString(obj)) {
- return false;
- }
if (isolate->heap()->IsInGCPostProcessing()) {
return false;
}
@@ -5627,7 +5909,7 @@
DCHECK(!CanMakeExternal() || result);
if (result) {
DCHECK(obj->IsExternalString());
- isolate->heap()->external_string_table()->AddString(*obj);
+ isolate->heap()->RegisterExternalString(*obj);
}
return result;
}
@@ -5637,9 +5919,10 @@
i::Handle<i::String> obj = Utils::OpenHandle(this);
i::Isolate* isolate = obj->GetIsolate();
- if (isolate->string_tracker()->IsFreshUnusedString(obj)) return false;
+ // Old space strings should be externalized.
+ if (!isolate->heap()->new_space()->Contains(*obj)) return true;
int size = obj->Size(); // Byte size of the original string.
- if (size < i::ExternalString::kShortSize) return false;
+ if (size <= i::ExternalString::kShortSize) return false;
i::StringShape shape(*obj);
return !shape.IsExternal();
}
@@ -5681,20 +5964,24 @@
}
-Local<v8::Value> v8::BooleanObject::New(bool value) {
- i::Isolate* isolate = i::Isolate::Current();
- LOG_API(isolate, "BooleanObject::New");
- ENTER_V8(isolate);
- i::Handle<i::Object> boolean(value
- ? isolate->heap()->true_value()
- : isolate->heap()->false_value(),
- isolate);
+Local<v8::Value> v8::BooleanObject::New(Isolate* isolate, bool value) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ LOG_API(i_isolate, "BooleanObject::New");
+ ENTER_V8(i_isolate);
+ i::Handle<i::Object> boolean(value ? i_isolate->heap()->true_value()
+ : i_isolate->heap()->false_value(),
+ i_isolate);
i::Handle<i::Object> obj =
- i::Object::ToObject(isolate, boolean).ToHandleChecked();
+ i::Object::ToObject(i_isolate, boolean).ToHandleChecked();
return Utils::ToLocal(obj);
}
+Local<v8::Value> v8::BooleanObject::New(bool value) {
+ return New(Isolate::GetCurrent(), value);
+}
+
+
bool v8::BooleanObject::ValueOf() const {
i::Handle<i::Object> obj = Utils::OpenHandle(this);
i::Handle<i::JSValue> jsvalue = i::Handle<i::JSValue>::cast(obj);
@@ -5704,7 +5991,7 @@
}
-Local<v8::Value> v8::StringObject::New(Handle<String> value) {
+Local<v8::Value> v8::StringObject::New(Local<String> value) {
i::Handle<i::String> string = Utils::OpenHandle(*value);
i::Isolate* isolate = string->GetIsolate();
LOG_API(isolate, "StringObject::New");
@@ -5725,7 +6012,7 @@
}
-Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Handle<Symbol> value) {
+Local<v8::Value> v8::SymbolObject::New(Isolate* isolate, Local<Symbol> value) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "SymbolObject::New");
ENTER_V8(i_isolate);
@@ -5745,20 +6032,24 @@
}
-Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- LOG_API(i_isolate, "Date::New");
+MaybeLocal<v8::Value> v8::Date::New(Local<Context> context, double time) {
if (std::isnan(time)) {
// Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
- time = base::OS::nan_value();
+ time = std::numeric_limits<double>::quiet_NaN();
}
- ENTER_V8(i_isolate);
- EXCEPTION_PREAMBLE(i_isolate);
- i::Handle<i::Object> obj;
- has_pending_exception = !i::Execution::NewDate(
- i_isolate, time).ToHandle(&obj);
- EXCEPTION_BAILOUT_CHECK(i_isolate, Local<v8::Value>());
- return Utils::ToLocal(obj);
+ PREPARE_FOR_EXECUTION(context, "Date::New", Value);
+ Local<Value> result;
+ has_pending_exception = !ToLocal<Value>(
+ i::JSDate::New(isolate->date_function(), isolate->date_function(), time),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<v8::Value> v8::Date::New(Isolate* isolate, double time) {
+ auto context = isolate->GetCurrentContext();
+ RETURN_TO_LOCAL_UNCHECKED(New(context, time), Value);
}
@@ -5773,13 +6064,9 @@
void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
- return);
LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
ENTER_V8(i_isolate);
-
i_isolate->date_cache()->ResetDateCache();
-
if (!i_isolate->eternal_handles()->Exists(
i::EternalHandles::DATE_CACHE_VERSION)) {
return;
@@ -5795,31 +6082,24 @@
}
-static i::Handle<i::String> RegExpFlagsToString(RegExp::Flags flags) {
- i::Isolate* isolate = i::Isolate::Current();
- uint8_t flags_buf[3];
- int num_flags = 0;
- if ((flags & RegExp::kGlobal) != 0) flags_buf[num_flags++] = 'g';
- if ((flags & RegExp::kMultiline) != 0) flags_buf[num_flags++] = 'm';
- if ((flags & RegExp::kIgnoreCase) != 0) flags_buf[num_flags++] = 'i';
- DCHECK(num_flags <= static_cast<int>(arraysize(flags_buf)));
- return isolate->factory()->InternalizeOneByteString(
- i::Vector<const uint8_t>(flags_buf, num_flags));
+MaybeLocal<v8::RegExp> v8::RegExp::New(Local<Context> context,
+ Local<String> pattern, Flags flags) {
+ PREPARE_FOR_EXECUTION(context, "RegExp::New", RegExp);
+ Local<v8::RegExp> result;
+ has_pending_exception =
+ !ToLocal<RegExp>(i::JSRegExp::New(Utils::OpenHandle(*pattern),
+ static_cast<i::JSRegExp::Flags>(flags)),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(RegExp);
+ RETURN_ESCAPED(result);
}
-Local<v8::RegExp> v8::RegExp::New(Handle<String> pattern,
- Flags flags) {
- i::Isolate* isolate = Utils::OpenHandle(*pattern)->GetIsolate();
- LOG_API(isolate, "RegExp::New");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::JSRegExp> obj;
- has_pending_exception = !i::Execution::NewJSRegExp(
- Utils::OpenHandle(*pattern),
- RegExpFlagsToString(flags)).ToHandle(&obj);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<v8::RegExp>());
- return Utils::ToLocal(i::Handle<i::JSRegExp>::cast(obj));
+Local<v8::RegExp> v8::RegExp::New(Local<String> pattern, Flags flags) {
+ auto isolate =
+ reinterpret_cast<Isolate*>(Utils::OpenHandle(*pattern)->GetIsolate());
+ auto context = isolate->GetCurrentContext();
+ RETURN_TO_LOCAL_UNCHECKED(New(context, pattern, flags), RegExp);
}
@@ -5830,18 +6110,20 @@
// Assert that the static flags cast in GetFlags is valid.
-#define REGEXP_FLAG_ASSERT_EQ(api_flag, internal_flag) \
- STATIC_ASSERT(static_cast<int>(v8::RegExp::api_flag) == \
- static_cast<int>(i::JSRegExp::internal_flag))
-REGEXP_FLAG_ASSERT_EQ(kNone, NONE);
-REGEXP_FLAG_ASSERT_EQ(kGlobal, GLOBAL);
-REGEXP_FLAG_ASSERT_EQ(kIgnoreCase, IGNORE_CASE);
-REGEXP_FLAG_ASSERT_EQ(kMultiline, MULTILINE);
+#define REGEXP_FLAG_ASSERT_EQ(flag) \
+ STATIC_ASSERT(static_cast<int>(v8::RegExp::flag) == \
+ static_cast<int>(i::JSRegExp::flag))
+REGEXP_FLAG_ASSERT_EQ(kNone);
+REGEXP_FLAG_ASSERT_EQ(kGlobal);
+REGEXP_FLAG_ASSERT_EQ(kIgnoreCase);
+REGEXP_FLAG_ASSERT_EQ(kMultiline);
+REGEXP_FLAG_ASSERT_EQ(kSticky);
+REGEXP_FLAG_ASSERT_EQ(kUnicode);
#undef REGEXP_FLAG_ASSERT_EQ
v8::RegExp::Flags v8::RegExp::GetFlags() const {
i::Handle<i::JSRegExp> obj = Utils::OpenHandle(this);
- return static_cast<RegExp::Flags>(obj->GetFlags().value());
+ return RegExp::Flags(static_cast<int>(obj->GetFlags()));
}
@@ -5869,174 +6151,395 @@
}
-Local<Object> Array::CloneElementAt(uint32_t index) {
- i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
- ON_BAILOUT(isolate, "v8::Array::CloneElementAt()", return Local<Object>());
- i::Handle<i::JSObject> self = Utils::OpenHandle(this);
- if (!self->HasFastObjectElements()) {
- return Local<Object>();
- }
+MaybeLocal<Object> Array::CloneElementAt(Local<Context> context,
+ uint32_t index) {
+ PREPARE_FOR_EXECUTION(context, "v8::Array::CloneElementAt()", Object);
+ auto self = Utils::OpenHandle(this);
+ if (!self->HasFastObjectElements()) return Local<Object>();
i::FixedArray* elms = i::FixedArray::cast(self->elements());
i::Object* paragon = elms->get(index);
- if (!paragon->IsJSObject()) {
- return Local<Object>();
- }
+ if (!paragon->IsJSObject()) return Local<Object>();
i::Handle<i::JSObject> paragon_handle(i::JSObject::cast(paragon));
- EXCEPTION_PREAMBLE(isolate);
- ENTER_V8(isolate);
- i::Handle<i::JSObject> result =
- isolate->factory()->CopyJSObject(paragon_handle);
- has_pending_exception = result.is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Object>());
- return Utils::ToLocal(result);
+ Local<Object> result;
+ has_pending_exception =
+ !ToLocal<Object>(isolate->factory()->CopyJSObject(paragon_handle),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(Object);
+ RETURN_ESCAPED(result);
}
-bool Value::IsPromise() const {
- i::Handle<i::Object> val = Utils::OpenHandle(this);
- if (!val->IsJSObject()) return false;
- i::Handle<i::JSObject> obj = i::Handle<i::JSObject>::cast(val);
- i::Isolate* isolate = obj->GetIsolate();
- LOG_API(isolate, "IsPromise");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> argv[] = { obj };
- i::Handle<i::Object> b;
- has_pending_exception = !i::Execution::Call(
- isolate,
- isolate->is_promise(),
- isolate->factory()->undefined_value(),
- arraysize(argv), argv,
- false).ToHandle(&b);
- EXCEPTION_BAILOUT_CHECK(isolate, false);
- return b->BooleanValue();
+Local<Object> Array::CloneElementAt(uint32_t index) { return Local<Object>(); }
+
+
+Local<v8::Map> v8::Map::New(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ LOG_API(i_isolate, "Map::New");
+ ENTER_V8(i_isolate);
+ i::Handle<i::JSMap> obj = i_isolate->factory()->NewJSMap();
+ return Utils::ToLocal(obj);
}
-Local<Promise::Resolver> Promise::Resolver::New(Isolate* v8_isolate) {
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
- LOG_API(isolate, "Promise::Resolver::New");
+size_t v8::Map::Size() const {
+ i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
+ return i::OrderedHashMap::cast(obj->table())->NumberOfElements();
+}
+
+
+void Map::Clear() {
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ LOG_API(isolate, "Map::Clear");
ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
+ i::JSMap::Clear(self);
+}
+
+
+MaybeLocal<Value> Map::Get(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION(context, "Map::Get", Value);
+ auto self = Utils::OpenHandle(this);
+ Local<Value> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception =
+ !ToLocal<Value>(i::Execution::Call(isolate, isolate->map_get(), self,
+ arraysize(argv), argv),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
+MaybeLocal<Map> Map::Set(Local<Context> context, Local<Value> key,
+ Local<Value> value) {
+ PREPARE_FOR_EXECUTION(context, "Map::Set", Map);
+ auto self = Utils::OpenHandle(this);
i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(
- isolate,
- isolate->promise_create(),
- isolate->factory()->undefined_value(),
- 0, NULL,
- false).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise::Resolver>());
- return Local<Promise::Resolver>::Cast(Utils::ToLocal(result));
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key),
+ Utils::OpenHandle(*value)};
+ has_pending_exception = !i::Execution::Call(isolate, isolate->map_set(), self,
+ arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Map);
+ RETURN_ESCAPED(Local<Map>::Cast(Utils::ToLocal(result)));
+}
+
+
+Maybe<bool> Map::Has(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Has", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception = !i::Execution::Call(isolate, isolate->map_has(), self,
+ arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
+Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Map::Delete", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception = !i::Execution::Call(isolate, isolate->map_delete(),
+ self, arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
+Local<Array> Map::AsArray() const {
+ i::Handle<i::JSMap> obj = Utils::OpenHandle(this);
+ i::Isolate* isolate = obj->GetIsolate();
+ i::Factory* factory = isolate->factory();
+ LOG_API(isolate, "Map::AsArray");
+ ENTER_V8(isolate);
+ i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(obj->table()));
+ int size = table->NumberOfElements();
+ int length = size * 2;
+ i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
+ for (int i = 0; i < size; ++i) {
+ if (table->KeyAt(i)->IsTheHole()) continue;
+ result->set(i * 2, table->KeyAt(i));
+ result->set(i * 2 + 1, table->ValueAt(i));
+ }
+ i::Handle<i::JSArray> result_array =
+ factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
+ return Utils::ToLocal(result_array);
+}
+
+
+Local<v8::Set> v8::Set::New(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ LOG_API(i_isolate, "Set::New");
+ ENTER_V8(i_isolate);
+ i::Handle<i::JSSet> obj = i_isolate->factory()->NewJSSet();
+ return Utils::ToLocal(obj);
+}
+
+
+size_t v8::Set::Size() const {
+ i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
+ return i::OrderedHashSet::cast(obj->table())->NumberOfElements();
+}
+
+
+void Set::Clear() {
+ auto self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ LOG_API(isolate, "Set::Clear");
+ ENTER_V8(isolate);
+ i::JSSet::Clear(self);
+}
+
+
+MaybeLocal<Set> Set::Add(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION(context, "Set::Add", Set);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception = !i::Execution::Call(isolate, isolate->set_add(), self,
+ arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Set);
+ RETURN_ESCAPED(Local<Set>::Cast(Utils::ToLocal(result)));
+}
+
+
+Maybe<bool> Set::Has(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Has", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception = !i::Execution::Call(isolate, isolate->set_has(), self,
+ arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
+Maybe<bool> Set::Delete(Local<Context> context, Local<Value> key) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Set::Delete", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> result;
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*key)};
+ has_pending_exception = !i::Execution::Call(isolate, isolate->set_delete(),
+ self, arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(result->IsTrue());
+}
+
+
+Local<Array> Set::AsArray() const {
+ i::Handle<i::JSSet> obj = Utils::OpenHandle(this);
+ i::Isolate* isolate = obj->GetIsolate();
+ i::Factory* factory = isolate->factory();
+ LOG_API(isolate, "Set::AsArray");
+ ENTER_V8(isolate);
+ i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(obj->table()));
+ int length = table->NumberOfElements();
+ i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
+ for (int i = 0; i < length; ++i) {
+ i::Object* key = table->KeyAt(i);
+ if (!key->IsTheHole()) {
+ result->set(i, key);
+ }
+ }
+ i::Handle<i::JSArray> result_array =
+ factory->NewJSArrayWithElements(result, i::FAST_ELEMENTS, length);
+ return Utils::ToLocal(result_array);
+}
+
+
+MaybeLocal<Promise::Resolver> Promise::Resolver::New(Local<Context> context) {
+ PREPARE_FOR_EXECUTION(context, "Promise::Resolver::New", Resolver);
+ i::Handle<i::Object> result;
+ has_pending_exception =
+ !i::Execution::Call(isolate, isolate->promise_create(),
+ isolate->factory()->undefined_value(), 0, NULL)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Promise::Resolver);
+ RETURN_ESCAPED(Local<Promise::Resolver>::Cast(Utils::ToLocal(result)));
+}
+
+
+Local<Promise::Resolver> Promise::Resolver::New(Isolate* isolate) {
+ RETURN_TO_LOCAL_UNCHECKED(New(isolate->GetCurrentContext()),
+ Promise::Resolver);
}
Local<Promise> Promise::Resolver::GetPromise() {
- i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
return Local<Promise>::Cast(Utils::ToLocal(promise));
}
-void Promise::Resolver::Resolve(Handle<Value> value) {
- i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
- i::Isolate* isolate = promise->GetIsolate();
- LOG_API(isolate, "Promise::Resolver::Resolve");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
- has_pending_exception = i::Execution::Call(
- isolate,
- isolate->promise_resolve(),
- isolate->factory()->undefined_value(),
- arraysize(argv), argv,
- false).is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
+Maybe<bool> Promise::Resolver::Resolve(Local<Context> context,
+ Local<Value> value) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
+ has_pending_exception =
+ i::Execution::Call(isolate, isolate->promise_resolve(),
+ isolate->factory()->undefined_value(), arraysize(argv),
+ argv)
+ .is_null();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(true);
}
-void Promise::Resolver::Reject(Handle<Value> value) {
- i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
- i::Isolate* isolate = promise->GetIsolate();
- LOG_API(isolate, "Promise::Resolver::Reject");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> argv[] = { promise, Utils::OpenHandle(*value) };
- has_pending_exception = i::Execution::Call(
- isolate,
- isolate->promise_reject(),
- isolate->factory()->undefined_value(),
- arraysize(argv), argv,
- false).is_null();
- EXCEPTION_BAILOUT_CHECK(isolate, /* void */ ;);
+void Promise::Resolver::Resolve(Local<Value> value) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ USE(Resolve(context, value));
}
-Local<Promise> Promise::Chain(Handle<Function> handler) {
- i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
- i::Isolate* isolate = promise->GetIsolate();
- LOG_API(isolate, "Promise::Chain");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
+Maybe<bool> Promise::Resolver::Reject(Local<Context> context,
+ Local<Value> value) {
+ PREPARE_FOR_EXECUTION_PRIMITIVE(context, "Promise::Resolver::Resolve", bool);
+ auto self = Utils::OpenHandle(this);
+ i::Handle<i::Object> argv[] = {self, Utils::OpenHandle(*value)};
+ has_pending_exception =
+ i::Execution::Call(isolate, isolate->promise_reject(),
+ isolate->factory()->undefined_value(), arraysize(argv),
+ argv)
+ .is_null();
+ RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
+ return Just(true);
+}
+
+
+void Promise::Resolver::Reject(Local<Value> value) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ USE(Reject(context, value));
+}
+
+
+namespace {
+
+MaybeLocal<Promise> DoChain(Value* value, Local<Context> context,
+ Local<Function> handler) {
+ PREPARE_FOR_EXECUTION(context, "Promise::Chain", Promise);
+ auto self = Utils::OpenHandle(value);
+ i::Handle<i::Object> argv[] = {Utils::OpenHandle(*handler)};
+ i::Handle<i::Object> result;
+ has_pending_exception = !i::Execution::Call(isolate, isolate->promise_chain(),
+ self, arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Promise);
+ RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
+}
+
+} // namespace
+
+
+MaybeLocal<Promise> Promise::Chain(Local<Context> context,
+ Local<Function> handler) {
+ return DoChain(this, context, handler);
+}
+
+
+Local<Promise> Promise::Chain(Local<Function> handler) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(DoChain(this, context, handler), Promise);
+}
+
+
+MaybeLocal<Promise> Promise::Catch(Local<Context> context,
+ Local<Function> handler) {
+ PREPARE_FOR_EXECUTION(context, "Promise::Catch", Promise);
+ auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(
- isolate,
- isolate->promise_chain(),
- promise,
- arraysize(argv), argv,
- false).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
- return Local<Promise>::Cast(Utils::ToLocal(result));
+ has_pending_exception = !i::Execution::Call(isolate, isolate->promise_catch(),
+ self, arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Promise);
+ RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
}
-Local<Promise> Promise::Catch(Handle<Function> handler) {
- i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
- i::Isolate* isolate = promise->GetIsolate();
- LOG_API(isolate, "Promise::Catch");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
- i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(
- isolate,
- isolate->promise_catch(),
- promise,
- arraysize(argv), argv,
- false).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
- return Local<Promise>::Cast(Utils::ToLocal(result));
+Local<Promise> Promise::Catch(Local<Function> handler) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(Catch(context, handler), Promise);
}
-Local<Promise> Promise::Then(Handle<Function> handler) {
- i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
- i::Isolate* isolate = promise->GetIsolate();
- LOG_API(isolate, "Promise::Then");
- ENTER_V8(isolate);
- EXCEPTION_PREAMBLE(isolate);
+MaybeLocal<Promise> Promise::Then(Local<Context> context,
+ Local<Function> handler) {
+ PREPARE_FOR_EXECUTION(context, "Promise::Then", Promise);
+ auto self = Utils::OpenHandle(this);
i::Handle<i::Object> argv[] = { Utils::OpenHandle(*handler) };
i::Handle<i::Object> result;
- has_pending_exception = !i::Execution::Call(
- isolate,
- isolate->promise_then(),
- promise,
- arraysize(argv), argv,
- false).ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Promise>());
- return Local<Promise>::Cast(Utils::ToLocal(result));
+ has_pending_exception = !i::Execution::Call(isolate, isolate->promise_then(),
+ self, arraysize(argv), argv)
+ .ToHandle(&result);
+ RETURN_ON_FAILED_EXECUTION(Promise);
+ RETURN_ESCAPED(Local<Promise>::Cast(Utils::ToLocal(result)));
+}
+
+
+Local<Promise> Promise::Then(Local<Function> handler) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(this));
+ RETURN_TO_LOCAL_UNCHECKED(Then(context, handler), Promise);
}
bool Promise::HasHandler() {
- i::Handle<i::JSObject> promise = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> promise = Utils::OpenHandle(this);
i::Isolate* isolate = promise->GetIsolate();
LOG_API(isolate, "Promise::HasRejectHandler");
ENTER_V8(isolate);
i::Handle<i::Symbol> key = isolate->factory()->promise_has_handler_symbol();
- return i::JSObject::GetDataProperty(promise, key)->IsTrue();
+ return i::JSReceiver::GetDataProperty(promise, key)->IsTrue();
}
+Local<Object> Proxy::GetTarget() {
+ i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
+ i::Handle<i::JSReceiver> target(self->target());
+ return Utils::ToLocal(target);
+}
+
+
+Local<Value> Proxy::GetHandler() {
+ i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
+ i::Handle<i::Object> handler(self->handler(), self->GetIsolate());
+ return Utils::ToLocal(handler);
+}
+
+
+bool Proxy::IsRevoked() {
+ i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
+ return self->IsRevoked();
+}
+
+
+void Proxy::Revoke() {
+ i::Handle<i::JSProxy> self = Utils::OpenHandle(this);
+ i::JSProxy::Revoke(self);
+}
+
+
+MaybeLocal<Proxy> Proxy::New(Local<Context> context, Local<Object> local_target,
+ Local<Object> local_handler) {
+ PREPARE_FOR_EXECUTION(context, "Proxy::New", Proxy);
+ i::Handle<i::JSReceiver> target = Utils::OpenHandle(*local_target);
+ i::Handle<i::JSReceiver> handler = Utils::OpenHandle(*local_handler);
+ Local<Proxy> result;
+ has_pending_exception =
+ !ToLocal<Proxy>(i::JSProxy::New(isolate, target, handler), &result);
+ RETURN_ON_FAILED_EXECUTION(Proxy);
+ RETURN_ESCAPED(result);
+}
+
bool v8::ArrayBuffer::IsExternal() const {
return Utils::OpenHandle(this)->is_external();
}
@@ -6048,14 +6551,22 @@
v8::ArrayBuffer::Contents v8::ArrayBuffer::Externalize() {
- i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
- Utils::ApiCheck(!obj->is_external(),
- "v8::ArrayBuffer::Externalize",
+ i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ Utils::ApiCheck(!self->is_external(), "v8::ArrayBuffer::Externalize",
"ArrayBuffer already externalized");
- obj->set_is_external(true);
- size_t byte_length = static_cast<size_t>(obj->byte_length()->Number());
+ self->set_is_external(true);
+ isolate->heap()->UnregisterArrayBuffer(*self);
+
+ return GetContents();
+}
+
+
+v8::ArrayBuffer::Contents v8::ArrayBuffer::GetContents() {
+ i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
+ size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
Contents contents;
- contents.data_ = obj->backing_store();
+ contents.data_ = self->backing_store();
contents.byte_length_ = byte_length;
return contents;
}
@@ -6071,7 +6582,7 @@
"Only neuterable ArrayBuffers can be neutered");
LOG_API(obj->GetIsolate(), "v8::ArrayBuffer::Neuter()");
ENTER_V8(isolate);
- i::Runtime::NeuterArrayBuffer(obj);
+ obj->Neuter();
}
@@ -6086,20 +6597,25 @@
LOG_API(i_isolate, "v8::ArrayBuffer::New(size_t)");
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
- i_isolate->factory()->NewJSArrayBuffer();
- i::Runtime::SetupArrayBufferAllocatingData(i_isolate, obj, byte_length);
+ i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
+ i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length);
return Utils::ToLocal(obj);
}
Local<ArrayBuffer> v8::ArrayBuffer::New(Isolate* isolate, void* data,
- size_t byte_length) {
+ size_t byte_length,
+ ArrayBufferCreationMode mode) {
+ // Embedders must guarantee that the external backing store is valid.
+ CHECK(byte_length == 0 || data != NULL);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "v8::ArrayBuffer::New(void*, size_t)");
ENTER_V8(i_isolate);
i::Handle<i::JSArrayBuffer> obj =
- i_isolate->factory()->NewJSArrayBuffer();
- i::Runtime::SetupArrayBuffer(i_isolate, obj, true, data, byte_length);
+ i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kNotShared);
+ i::JSArrayBuffer::Setup(obj, i_isolate,
+ mode == ArrayBufferCreationMode::kExternalized, data,
+ byte_length);
return Utils::ToLocal(obj);
}
@@ -6119,6 +6635,36 @@
}
+size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) {
+ i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ size_t byte_offset = i::NumberToSize(isolate, self->byte_offset());
+ size_t bytes_to_copy =
+ i::Min(byte_length, i::NumberToSize(isolate, self->byte_length()));
+ if (bytes_to_copy) {
+ i::DisallowHeapAllocation no_gc;
+ i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
+ const char* source = reinterpret_cast<char*>(buffer->backing_store());
+ if (source == nullptr) {
+ DCHECK(self->IsJSTypedArray());
+ i::Handle<i::JSTypedArray> typed_array(i::JSTypedArray::cast(*self));
+ i::Handle<i::FixedTypedArrayBase> fixed_array(
+ i::FixedTypedArrayBase::cast(typed_array->elements()));
+ source = reinterpret_cast<char*>(fixed_array->DataPtr());
+ }
+ memcpy(dest, source + byte_offset, bytes_to_copy);
+ }
+ return bytes_to_copy;
+}
+
+
+bool v8::ArrayBufferView::HasBuffer() const {
+ i::Handle<i::JSArrayBufferView> self = Utils::OpenHandle(this);
+ i::Handle<i::JSArrayBuffer> buffer(i::JSArrayBuffer::cast(self->buffer()));
+ return buffer->backing_store() != nullptr;
+}
+
+
size_t v8::ArrayBufferView::ByteOffset() {
i::Handle<i::JSArrayBufferView> obj = Utils::OpenHandle(this);
return static_cast<size_t>(obj->byte_offset()->Number());
@@ -6133,38 +6679,60 @@
size_t v8::TypedArray::Length() {
i::Handle<i::JSTypedArray> obj = Utils::OpenHandle(this);
- return static_cast<size_t>(obj->length()->Number());
+ return static_cast<size_t>(obj->length_value());
}
-#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
- Local<Type##Array> Type##Array::New(Handle<ArrayBuffer> array_buffer, \
- size_t byte_offset, size_t length) { \
- i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
- LOG_API(isolate, \
- "v8::" #Type "Array::New(Handle<ArrayBuffer>, size_t, size_t)"); \
- ENTER_V8(isolate); \
- if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
- "v8::" #Type \
- "Array::New(Handle<ArrayBuffer>, size_t, size_t)", \
- "length exceeds max allowed value")) { \
- return Local<Type##Array>(); \
- } \
- i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
- i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
- v8::kExternal##Type##Array, buffer, byte_offset, length); \
- return Utils::ToLocal##Type##Array(obj); \
+#define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \
+ Local<Type##Array> Type##Array::New(Local<ArrayBuffer> array_buffer, \
+ size_t byte_offset, size_t length) { \
+ i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \
+ LOG_API(isolate, \
+ "v8::" #Type "Array::New(Local<ArrayBuffer>, size_t, size_t)"); \
+ ENTER_V8(isolate); \
+ if (!Utils::ApiCheck(length <= static_cast<size_t>(i::Smi::kMaxValue), \
+ "v8::" #Type \
+ "Array::New(Local<ArrayBuffer>, size_t, size_t)", \
+ "length exceeds max allowed value")) { \
+ return Local<Type##Array>(); \
+ } \
+ i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer); \
+ i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
+ i::kExternal##Type##Array, buffer, byte_offset, length); \
+ return Utils::ToLocal##Type##Array(obj); \
+ } \
+ Local<Type##Array> Type##Array::New( \
+ Local<SharedArrayBuffer> shared_array_buffer, size_t byte_offset, \
+ size_t length) { \
+ CHECK(i::FLAG_harmony_sharedarraybuffer); \
+ i::Isolate* isolate = \
+ Utils::OpenHandle(*shared_array_buffer)->GetIsolate(); \
+ LOG_API(isolate, "v8::" #Type \
+ "Array::New(Local<SharedArrayBuffer>, size_t, size_t)"); \
+ ENTER_V8(isolate); \
+ if (!Utils::ApiCheck( \
+ length <= static_cast<size_t>(i::Smi::kMaxValue), \
+ "v8::" #Type \
+ "Array::New(Local<SharedArrayBuffer>, size_t, size_t)", \
+ "length exceeds max allowed value")) { \
+ return Local<Type##Array>(); \
+ } \
+ i::Handle<i::JSArrayBuffer> buffer = \
+ Utils::OpenHandle(*shared_array_buffer); \
+ i::Handle<i::JSTypedArray> obj = isolate->factory()->NewJSTypedArray( \
+ i::kExternal##Type##Array, buffer, byte_offset, length); \
+ return Utils::ToLocal##Type##Array(obj); \
}
TYPED_ARRAYS(TYPED_ARRAY_NEW)
#undef TYPED_ARRAY_NEW
-Local<DataView> DataView::New(Handle<ArrayBuffer> array_buffer,
+Local<DataView> DataView::New(Local<ArrayBuffer> array_buffer,
size_t byte_offset, size_t byte_length) {
i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*array_buffer);
i::Isolate* isolate = buffer->GetIsolate();
- LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)");
+ LOG_API(isolate, "v8::DataView::New(Local<ArrayBuffer>, size_t, size_t)");
ENTER_V8(isolate);
i::Handle<i::JSDataView> obj =
isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
@@ -6172,6 +6740,84 @@
}
+Local<DataView> DataView::New(Local<SharedArrayBuffer> shared_array_buffer,
+ size_t byte_offset, size_t byte_length) {
+ CHECK(i::FLAG_harmony_sharedarraybuffer);
+ i::Handle<i::JSArrayBuffer> buffer = Utils::OpenHandle(*shared_array_buffer);
+ i::Isolate* isolate = buffer->GetIsolate();
+ LOG_API(isolate,
+ "v8::DataView::New(Local<SharedArrayBuffer>, size_t, size_t)");
+ ENTER_V8(isolate);
+ i::Handle<i::JSDataView> obj =
+ isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length);
+ return Utils::ToLocal(obj);
+}
+
+
+bool v8::SharedArrayBuffer::IsExternal() const {
+ return Utils::OpenHandle(this)->is_external();
+}
+
+
+v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::Externalize() {
+ i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
+ i::Isolate* isolate = self->GetIsolate();
+ Utils::ApiCheck(!self->is_external(), "v8::SharedArrayBuffer::Externalize",
+ "SharedArrayBuffer already externalized");
+ self->set_is_external(true);
+ isolate->heap()->UnregisterArrayBuffer(*self);
+ return GetContents();
+}
+
+
+v8::SharedArrayBuffer::Contents v8::SharedArrayBuffer::GetContents() {
+ i::Handle<i::JSArrayBuffer> self = Utils::OpenHandle(this);
+ size_t byte_length = static_cast<size_t>(self->byte_length()->Number());
+ Contents contents;
+ contents.data_ = self->backing_store();
+ contents.byte_length_ = byte_length;
+ return contents;
+}
+
+
+size_t v8::SharedArrayBuffer::ByteLength() const {
+ i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(this);
+ return static_cast<size_t>(obj->byte_length()->Number());
+}
+
+
+Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(Isolate* isolate,
+ size_t byte_length) {
+ CHECK(i::FLAG_harmony_sharedarraybuffer);
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ LOG_API(i_isolate, "v8::SharedArrayBuffer::New(size_t)");
+ ENTER_V8(i_isolate);
+ i::Handle<i::JSArrayBuffer> obj =
+ i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
+ i::JSArrayBuffer::SetupAllocatingData(obj, i_isolate, byte_length, true,
+ i::SharedFlag::kShared);
+ return Utils::ToLocalShared(obj);
+}
+
+
+Local<SharedArrayBuffer> v8::SharedArrayBuffer::New(
+ Isolate* isolate, void* data, size_t byte_length,
+ ArrayBufferCreationMode mode) {
+ CHECK(i::FLAG_harmony_sharedarraybuffer);
+ // Embedders must guarantee that the external backing store is valid.
+ CHECK(byte_length == 0 || data != NULL);
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ LOG_API(i_isolate, "v8::SharedArrayBuffer::New(void*, size_t)");
+ ENTER_V8(i_isolate);
+ i::Handle<i::JSArrayBuffer> obj =
+ i_isolate->factory()->NewJSArrayBuffer(i::SharedFlag::kShared);
+ i::JSArrayBuffer::Setup(obj, i_isolate,
+ mode == ArrayBufferCreationMode::kExternalized, data,
+ byte_length, i::SharedFlag::kShared);
+ return Utils::ToLocalShared(obj);
+}
+
+
Local<Symbol> v8::Symbol::New(Isolate* isolate, Local<String> name) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "Symbol::New()");
@@ -6184,7 +6830,8 @@
static i::Handle<i::Symbol> SymbolFor(i::Isolate* isolate,
i::Handle<i::String> name,
- i::Handle<i::String> part) {
+ i::Handle<i::String> part,
+ bool private_symbol) {
i::Handle<i::JSObject> registry = isolate->GetSymbolRegistry();
i::Handle<i::JSObject> symbols =
i::Handle<i::JSObject>::cast(
@@ -6193,7 +6840,10 @@
i::Object::GetPropertyOrElement(symbols, name).ToHandleChecked();
if (!symbol->IsSymbol()) {
DCHECK(symbol->IsUndefined());
- symbol = isolate->factory()->NewSymbol();
+ if (private_symbol)
+ symbol = isolate->factory()->NewPrivateSymbol();
+ else
+ symbol = isolate->factory()->NewSymbol();
i::Handle<i::Symbol>::cast(symbol)->set_name(*name);
i::JSObject::SetProperty(symbols, name, symbol, i::STRICT).Assert();
}
@@ -6205,7 +6855,7 @@
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::String> i_name = Utils::OpenHandle(*name);
i::Handle<i::String> part = i_isolate->factory()->for_string();
- return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
+ return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false));
}
@@ -6213,7 +6863,7 @@
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::String> i_name = Utils::OpenHandle(*name);
i::Handle<i::String> part = i_isolate->factory()->for_api_string();
- return Utils::ToLocal(SymbolFor(i_isolate, i_name, part));
+ return Utils::ToLocal(SymbolFor(i_isolate, i_name, part, false));
}
@@ -6235,6 +6885,12 @@
}
+Local<Symbol> v8::Symbol::GetIsConcatSpreadable(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ return Utils::ToLocal(i_isolate->factory()->is_concat_spreadable_symbol());
+}
+
+
Local<Private> v8::Private::New(Isolate* isolate, Local<String> name) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
LOG_API(i_isolate, "Private::New()");
@@ -6242,28 +6898,17 @@
i::Handle<i::Symbol> symbol = i_isolate->factory()->NewPrivateSymbol();
if (!name.IsEmpty()) symbol->set_name(*Utils::OpenHandle(*name));
Local<Symbol> result = Utils::ToLocal(symbol);
- return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
+ return v8::Local<Private>(reinterpret_cast<Private*>(*result));
}
Local<Private> v8::Private::ForApi(Isolate* isolate, Local<String> name) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
i::Handle<i::String> i_name = Utils::OpenHandle(*name);
- i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->private_api_string();
- i::Handle<i::JSObject> privates =
- i::Handle<i::JSObject>::cast(
- i::Object::GetPropertyOrElement(registry, part).ToHandleChecked());
- i::Handle<i::Object> symbol =
- i::Object::GetPropertyOrElement(privates, i_name).ToHandleChecked();
- if (!symbol->IsSymbol()) {
- DCHECK(symbol->IsUndefined());
- symbol = i_isolate->factory()->NewPrivateSymbol();
- i::Handle<i::Symbol>::cast(symbol)->set_name(*i_name);
- i::JSObject::SetProperty(privates, i_name, symbol, i::STRICT).Assert();
- }
- Local<Symbol> result = Utils::ToLocal(i::Handle<i::Symbol>::cast(symbol));
- return v8::Handle<Private>(reinterpret_cast<Private*>(*result));
+ Local<Symbol> result =
+ Utils::ToLocal(SymbolFor(i_isolate, i_name, part, true));
+ return v8::Local<Private>(reinterpret_cast<Private*>(*result));
}
@@ -6271,7 +6916,7 @@
i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
if (std::isnan(value)) {
// Introduce only canonical NaN value into the VM, to avoid signaling NaNs.
- value = base::OS::nan_value();
+ value = std::numeric_limits<double>::quiet_NaN();
}
ENTER_V8(internal_isolate);
i::Handle<i::Object> result = internal_isolate->factory()->NewNumber(value);
@@ -6303,9 +6948,11 @@
}
-void Isolate::CollectAllGarbage(const char* gc_reason) {
- reinterpret_cast<i::Isolate*>(this)->heap()->CollectAllGarbage(
- i::Heap::kNoGCFlags, gc_reason);
+void Isolate::ReportExternalAllocationLimitReached() {
+ i::Heap* heap = reinterpret_cast<i::Isolate*>(this)->heap();
+ if (heap->gc_state() != i::Heap::NOT_IN_GC) return;
+ heap->ReportExternalMemoryPressure(
+ "external memory allocation limit reached.");
}
@@ -6397,47 +7044,41 @@
}
-void Isolate::AddGCPrologueCallback(GCPrologueCallback callback,
- GCType gc_type) {
+void Isolate::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->heap()->AddGCPrologueCallback(callback, gc_type);
}
-void Isolate::RemoveGCPrologueCallback(GCPrologueCallback callback) {
+void Isolate::RemoveGCPrologueCallback(GCCallback callback) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->heap()->RemoveGCPrologueCallback(callback);
}
-void Isolate::AddGCEpilogueCallback(GCEpilogueCallback callback,
- GCType gc_type) {
+void Isolate::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->heap()->AddGCEpilogueCallback(callback, gc_type);
}
-void Isolate::RemoveGCEpilogueCallback(GCEpilogueCallback callback) {
+void Isolate::RemoveGCEpilogueCallback(GCCallback callback) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->heap()->RemoveGCEpilogueCallback(callback);
}
-void V8::AddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type) {
+void V8::AddGCPrologueCallback(GCCallback callback, GCType gc_type) {
i::Isolate* isolate = i::Isolate::Current();
isolate->heap()->AddGCPrologueCallback(
- reinterpret_cast<v8::Isolate::GCPrologueCallback>(callback),
- gc_type,
- false);
+ reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
}
-void V8::AddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type) {
+void V8::AddGCEpilogueCallback(GCCallback callback, GCType gc_type) {
i::Isolate* isolate = i::Isolate::Current();
isolate->heap()->AddGCEpilogueCallback(
- reinterpret_cast<v8::Isolate::GCEpilogueCallback>(callback),
- gc_type,
- false);
+ reinterpret_cast<v8::Isolate::GCCallback>(callback), gc_type, false);
}
@@ -6483,10 +7124,6 @@
}
-void Isolate::ClearInterrupt() {
-}
-
-
void Isolate::RequestGarbageCollectionForTesting(GarbageCollectionType type) {
CHECK(i::FLAG_expose_gc);
if (type == kMinorGarbageCollection) {
@@ -6509,8 +7146,15 @@
Isolate* Isolate::New(const Isolate::CreateParams& params) {
- i::Isolate* isolate = new i::Isolate(params.enable_serializer);
+ i::Isolate* isolate = new i::Isolate(false);
Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
+ CHECK(params.array_buffer_allocator != NULL);
+ isolate->set_array_buffer_allocator(params.array_buffer_allocator);
+ if (params.snapshot_blob != NULL) {
+ isolate->set_snapshot_blob(params.snapshot_blob);
+ } else {
+ isolate->set_snapshot_blob(i::Snapshot::DefaultSnapshotBlob());
+ }
if (params.entry_hook) {
isolate->set_function_entry_hook(params.entry_hook);
}
@@ -6519,12 +7163,30 @@
isolate->logger()->SetCodeEventHandler(kJitCodeEventDefault,
params.code_event_handler);
}
+ if (params.counter_lookup_callback) {
+ v8_isolate->SetCounterFunction(params.counter_lookup_callback);
+ }
+
+ if (params.create_histogram_callback) {
+ v8_isolate->SetCreateHistogramFunction(params.create_histogram_callback);
+ }
+
+ if (params.add_histogram_sample_callback) {
+ v8_isolate->SetAddHistogramSampleFunction(
+ params.add_histogram_sample_callback);
+ }
SetResourceConstraints(isolate, params.constraints);
// TODO(jochen): Once we got rid of Isolate::Current(), we can remove this.
Isolate::Scope isolate_scope(v8_isolate);
if (params.entry_hook || !i::Snapshot::Initialize(isolate)) {
// If the isolate has a function entry hook, it needs to re-build all its
// code stubs with entry hooks embedded, so don't deserialize a snapshot.
+ if (i::Snapshot::EmbedsScript(isolate)) {
+ // If the snapshot embeds a script, we cannot initialize the isolate
+ // without the snapshot as a fallback. This is unlikely to happen though.
+ V8_Fatal(__FILE__, __LINE__,
+ "Initializing isolate from custom startup snapshot failed");
+ }
isolate->Init(NULL);
}
return v8_isolate;
@@ -6542,6 +7204,12 @@
}
+void Isolate::DiscardThreadSpecificMetadata() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->DiscardPerThreadDataForThisThread();
+}
+
+
void Isolate::Enter() {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->Enter();
@@ -6554,6 +7222,13 @@
}
+void Isolate::SetAbortOnUncaughtExceptionCallback(
+ AbortOnUncaughtExceptionCallback callback) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ isolate->SetAbortOnUncaughtExceptionCallback(callback);
+}
+
+
Isolate::DisallowJavascriptExecutionScope::DisallowJavascriptExecutionScope(
Isolate* isolate,
Isolate::DisallowJavascriptExecutionScope::OnFailure on_failure)
@@ -6614,8 +7289,69 @@
heap_statistics->total_heap_size_executable_ =
heap->CommittedMemoryExecutable();
heap_statistics->total_physical_size_ = heap->CommittedPhysicalMemory();
+ heap_statistics->total_available_size_ = heap->Available();
heap_statistics->used_heap_size_ = heap->SizeOfObjects();
heap_statistics->heap_size_limit_ = heap->MaxReserved();
+ heap_statistics->does_zap_garbage_ = heap->ShouldZapGarbage();
+}
+
+
+size_t Isolate::NumberOfHeapSpaces() {
+ return i::LAST_SPACE - i::FIRST_SPACE + 1;
+}
+
+
+bool Isolate::GetHeapSpaceStatistics(HeapSpaceStatistics* space_statistics,
+ size_t index) {
+ if (!space_statistics) return false;
+ if (!i::Heap::IsValidAllocationSpace(static_cast<i::AllocationSpace>(index)))
+ return false;
+
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::Heap* heap = isolate->heap();
+ i::Space* space = heap->space(static_cast<int>(index));
+
+ space_statistics->space_name_ = heap->GetSpaceName(static_cast<int>(index));
+ space_statistics->space_size_ = space->CommittedMemory();
+ space_statistics->space_used_size_ = space->SizeOfObjects();
+ space_statistics->space_available_size_ = space->Available();
+ space_statistics->physical_space_size_ = space->CommittedPhysicalMemory();
+ return true;
+}
+
+
+size_t Isolate::NumberOfTrackedHeapObjectTypes() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::Heap* heap = isolate->heap();
+ return heap->NumberOfTrackedHeapObjectTypes();
+}
+
+
+bool Isolate::GetHeapObjectStatisticsAtLastGC(
+ HeapObjectStatistics* object_statistics, size_t type_index) {
+ if (!object_statistics) return false;
+ if (!i::FLAG_track_gc_object_stats) return false;
+
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::Heap* heap = isolate->heap();
+ if (type_index >= heap->NumberOfTrackedHeapObjectTypes()) return false;
+
+ const char* object_type;
+ const char* object_sub_type;
+ size_t object_count = heap->ObjectCountAtLastGC(type_index);
+ size_t object_size = heap->ObjectSizeAtLastGC(type_index);
+ if (!heap->GetObjectTypeName(type_index, &object_type, &object_sub_type)) {
+ // There should be no objects counted when the type is unknown.
+ DCHECK_EQ(object_count, 0U);
+ DCHECK_EQ(object_size, 0U);
+ return false;
+ }
+
+ object_statistics->object_type_ = object_type;
+ object_statistics->object_sub_type_ = object_sub_type;
+ object_statistics->object_count_ = object_count;
+ object_statistics->object_size_ = object_size;
+ return true;
}
@@ -6660,7 +7396,7 @@
}
-void Isolate::EnqueueMicrotask(Handle<Function> microtask) {
+void Isolate::EnqueueMicrotask(Local<Function> microtask) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
isolate->EnqueueMicrotask(Utils::OpenHandle(*microtask));
}
@@ -6751,6 +7487,18 @@
}
+void Isolate::IsolateInForegroundNotification() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ return isolate->heap()->SetOptimizeForLatency();
+}
+
+
+void Isolate::IsolateInBackgroundNotification() {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ return isolate->heap()->SetOptimizeForMemoryUsage();
+}
+
+
void Isolate::SetJitCodeEventHandler(JitCodeEventOptions options,
JitCodeEventHandler event_handler) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
@@ -6798,9 +7546,8 @@
}
-bool Isolate::AddMessageListener(MessageCallback that, Handle<Value> data) {
+bool Isolate::AddMessageListener(MessageCallback that, Local<Value> data) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- ON_BAILOUT(isolate, "v8::V8::AddMessageListener()", return false);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
NeanderArray listeners(isolate->factory()->message_listeners());
@@ -6815,7 +7562,6 @@
void Isolate::RemoveMessageListeners(MessageCallback that) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
- ON_BAILOUT(isolate, "v8::V8::RemoveMessageListeners()", return);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
NeanderArray listeners(isolate->factory()->message_listeners());
@@ -6856,10 +7602,10 @@
public:
explicit VisitorAdapter(PersistentHandleVisitor* visitor)
: visitor_(visitor) {}
- virtual void VisitPointers(i::Object** start, i::Object** end) {
+ void VisitPointers(i::Object** start, i::Object** end) override {
UNREACHABLE();
}
- virtual void VisitEmbedderReference(i::Object** p, uint16_t class_id) {
+ void VisitEmbedderReference(i::Object** p, uint16_t class_id) override {
Value* value = ToApi<Value>(i::Handle<i::Object>(p));
visitor_->VisitPersistentHandle(
reinterpret_cast<Persistent<Value>*>(&value), class_id);
@@ -6888,15 +7634,26 @@
}
-String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj)
+void Isolate::VisitWeakHandles(PersistentHandleVisitor* visitor) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(this);
+ i::DisallowHeapAllocation no_allocation;
+ VisitorAdapter visitor_adapter(visitor);
+ isolate->global_handles()->IterateWeakRootsInNewSpaceWithClassIds(
+ &visitor_adapter);
+}
+
+
+String::Utf8Value::Utf8Value(v8::Local<v8::Value> obj)
: str_(NULL), length_(0) {
- i::Isolate* isolate = i::Isolate::Current();
if (obj.IsEmpty()) return;
+ i::Isolate* isolate = i::Isolate::Current();
+ Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- TryCatch try_catch;
- Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
- if (str.IsEmpty()) return;
+ Local<Context> context = v8_isolate->GetCurrentContext();
+ TryCatch try_catch(v8_isolate);
+ Local<String> str;
+ if (!obj->ToString(context).ToLocal(&str)) return;
i::Handle<i::String> i_str = Utils::OpenHandle(*str);
length_ = v8::Utf8Length(*i_str, isolate);
str_ = i::NewArray<char>(length_ + 1);
@@ -6909,15 +7666,16 @@
}
-String::Value::Value(v8::Handle<v8::Value> obj)
- : str_(NULL), length_(0) {
- i::Isolate* isolate = i::Isolate::Current();
+String::Value::Value(v8::Local<v8::Value> obj) : str_(NULL), length_(0) {
if (obj.IsEmpty()) return;
+ i::Isolate* isolate = i::Isolate::Current();
+ Isolate* v8_isolate = reinterpret_cast<Isolate*>(isolate);
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- TryCatch try_catch;
- Handle<String> str = obj->ToString(reinterpret_cast<v8::Isolate*>(isolate));
- if (str.IsEmpty()) return;
+ Local<Context> context = v8_isolate->GetCurrentContext();
+ TryCatch try_catch(v8_isolate);
+ Local<String> str;
+ if (!obj->ToString(context).ToLocal(&str)) return;
length_ = str->Length();
str_ = i::NewArray<uint16_t>(length_ + 1);
str->Write(str_);
@@ -6929,51 +7687,51 @@
}
-#define DEFINE_ERROR(NAME) \
- Local<Value> Exception::NAME(v8::Handle<v8::String> raw_message) { \
- i::Isolate* isolate = i::Isolate::Current(); \
- LOG_API(isolate, #NAME); \
- ON_BAILOUT(isolate, "v8::Exception::" #NAME "()", return Local<Value>()); \
- ENTER_V8(isolate); \
- i::Object* error; \
- { \
- i::HandleScope scope(isolate); \
- i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
- i::Handle<i::Object> result; \
- EXCEPTION_PREAMBLE(isolate); \
- i::MaybeHandle<i::Object> maybe_result = \
- isolate->factory()->New##NAME(message); \
- has_pending_exception = !maybe_result.ToHandle(&result); \
- /* TODO(yangguo): crbug/403509. Return empty handle instead. */ \
- EXCEPTION_BAILOUT_CHECK( \
- isolate, v8::Undefined(reinterpret_cast<v8::Isolate*>(isolate))); \
- error = *result; \
- } \
- i::Handle<i::Object> result(error, isolate); \
- return Utils::ToLocal(result); \
+#define DEFINE_ERROR(NAME, name) \
+ Local<Value> Exception::NAME(v8::Local<v8::String> raw_message) { \
+ i::Isolate* isolate = i::Isolate::Current(); \
+ LOG_API(isolate, #NAME); \
+ ENTER_V8(isolate); \
+ i::Object* error; \
+ { \
+ i::HandleScope scope(isolate); \
+ i::Handle<i::String> message = Utils::OpenHandle(*raw_message); \
+ i::Handle<i::JSFunction> constructor = isolate->name##_function(); \
+ error = *isolate->factory()->NewError(constructor, message); \
+ } \
+ i::Handle<i::Object> result(error, isolate); \
+ return Utils::ToLocal(result); \
}
-DEFINE_ERROR(RangeError)
-DEFINE_ERROR(ReferenceError)
-DEFINE_ERROR(SyntaxError)
-DEFINE_ERROR(TypeError)
-DEFINE_ERROR(Error)
+DEFINE_ERROR(RangeError, range_error)
+DEFINE_ERROR(ReferenceError, reference_error)
+DEFINE_ERROR(SyntaxError, syntax_error)
+DEFINE_ERROR(TypeError, type_error)
+DEFINE_ERROR(Error, error)
#undef DEFINE_ERROR
-Local<Message> Exception::CreateMessage(Handle<Value> exception) {
+Local<Message> Exception::CreateMessage(Isolate* isolate,
+ Local<Value> exception) {
i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
- if (!obj->IsHeapObject()) return Local<Message>();
- i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ i::HandleScope scope(i_isolate);
return Utils::MessageToLocal(
- scope.CloseAndEscape(isolate->CreateMessage(obj, NULL)));
+ scope.CloseAndEscape(i_isolate->CreateMessage(obj, NULL)));
}
-Local<StackTrace> Exception::GetStackTrace(Handle<Value> exception) {
+Local<Message> Exception::CreateMessage(Local<Value> exception) {
+ i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
+ if (!obj->IsHeapObject()) return Local<Message>();
+ i::Isolate* isolate = i::HeapObject::cast(*obj)->GetIsolate();
+ return CreateMessage(reinterpret_cast<Isolate*>(isolate), exception);
+}
+
+
+Local<StackTrace> Exception::GetStackTrace(Local<Value> exception) {
i::Handle<i::Object> obj = Utils::OpenHandle(*exception);
if (!obj->IsJSObject()) return Local<StackTrace>();
i::Handle<i::JSObject> js_obj = i::Handle<i::JSObject>::cast(obj);
@@ -6985,21 +7743,26 @@
// --- D e b u g S u p p o r t ---
-bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
+bool Debug::SetDebugEventListener(Isolate* isolate, EventCallback that,
+ Local<Value> data) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ i::HandleScope scope(i_isolate);
+ i::Handle<i::Object> foreign = i_isolate->factory()->undefined_value();
if (that != NULL) {
- foreign = isolate->factory()->NewForeign(FUNCTION_ADDR(that));
+ foreign = i_isolate->factory()->NewForeign(FUNCTION_ADDR(that));
}
- isolate->debug()->SetEventListener(foreign,
- Utils::OpenHandle(*data, true));
+ i_isolate->debug()->SetEventListener(foreign, Utils::OpenHandle(*data, true));
return true;
}
+bool Debug::SetDebugEventListener(EventCallback that, Local<Value> data) {
+ return SetDebugEventListener(
+ reinterpret_cast<Isolate*>(i::Isolate::Current()), that, data);
+}
+
+
void Debug::DebugBreak(Isolate* isolate) {
reinterpret_cast<i::Isolate*>(isolate)->stack_guard()->RequestDebugBreak();
}
@@ -7017,16 +7780,16 @@
}
-void Debug::DebugBreakForCommand(Isolate* isolate, ClientData* data) {
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
- internal_isolate->debug()->EnqueueDebugCommand(data);
+void Debug::SetMessageHandler(Isolate* isolate,
+ v8::Debug::MessageHandler handler) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ i_isolate->debug()->SetMessageHandler(handler);
}
void Debug::SetMessageHandler(v8::Debug::MessageHandler handler) {
- i::Isolate* isolate = i::Isolate::Current();
- ENTER_V8(isolate);
- isolate->debug()->SetMessageHandler(handler);
+ SetMessageHandler(reinterpret_cast<Isolate*>(i::Isolate::Current()), handler);
}
@@ -7040,64 +7803,77 @@
}
-Local<Value> Debug::Call(v8::Handle<v8::Function> fun,
- v8::Handle<v8::Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::Debug::Call()", return Local<Value>());
- ENTER_V8(isolate);
- i::MaybeHandle<i::Object> maybe_result;
- EXCEPTION_PREAMBLE(isolate);
+MaybeLocal<Value> Debug::Call(Local<Context> context,
+ v8::Local<v8::Function> fun,
+ v8::Local<v8::Value> data) {
+ PREPARE_FOR_EXECUTION(context, "v8::Debug::Call()", Value);
+ i::Handle<i::Object> data_obj;
if (data.IsEmpty()) {
- maybe_result = isolate->debug()->Call(
- Utils::OpenHandle(*fun), isolate->factory()->undefined_value());
+ data_obj = isolate->factory()->undefined_value();
} else {
- maybe_result = isolate->debug()->Call(
- Utils::OpenHandle(*fun), Utils::OpenHandle(*data));
+ data_obj = Utils::OpenHandle(*data);
}
- i::Handle<i::Object> result;
- has_pending_exception = !maybe_result.ToHandle(&result);
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
- return Utils::ToLocal(result);
+ Local<Value> result;
+ has_pending_exception =
+ !ToLocal<Value>(isolate->debug()->Call(Utils::OpenHandle(*fun), data_obj),
+ &result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
}
-Local<Value> Debug::GetMirror(v8::Handle<v8::Value> obj) {
- i::Isolate* isolate = i::Isolate::Current();
- ON_BAILOUT(isolate, "v8::Debug::GetMirror()", return Local<Value>());
- ENTER_V8(isolate);
- v8::EscapableHandleScope scope(reinterpret_cast<Isolate*>(isolate));
+Local<Value> Debug::Call(v8::Local<v8::Function> fun,
+ v8::Local<v8::Value> data) {
+ auto context = ContextFromHeapObject(Utils::OpenHandle(*fun));
+ RETURN_TO_LOCAL_UNCHECKED(Call(context, fun, data), Value);
+}
+
+
+MaybeLocal<Value> Debug::GetMirror(Local<Context> context,
+ v8::Local<v8::Value> obj) {
+ PREPARE_FOR_EXECUTION(context, "v8::Debug::GetMirror()", Value);
i::Debug* isolate_debug = isolate->debug();
- EXCEPTION_PREAMBLE(isolate);
has_pending_exception = !isolate_debug->Load();
- v8::Local<v8::Value> result;
- if (!has_pending_exception) {
- i::Handle<i::JSObject> debug(
- isolate_debug->debug_context()->global_object());
- i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
- STATIC_CHAR_VECTOR("MakeMirror"));
- i::Handle<i::Object> fun_obj =
- i::Object::GetProperty(debug, name).ToHandleChecked();
- i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
- v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
- const int kArgc = 1;
- v8::Handle<v8::Value> argv[kArgc] = { obj };
- result = v8_fun->Call(Utils::ToLocal(debug), kArgc, argv);
- has_pending_exception = result.IsEmpty();
- }
- EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
- return scope.Escape(result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
+ auto name = isolate->factory()->NewStringFromStaticChars("MakeMirror");
+ auto fun_obj = i::Object::GetProperty(debug, name).ToHandleChecked();
+ auto v8_fun = Utils::CallableToLocal(i::Handle<i::JSFunction>::cast(fun_obj));
+ const int kArgc = 1;
+ v8::Local<v8::Value> argv[kArgc] = {obj};
+ Local<Value> result;
+ has_pending_exception =
+ !v8_fun->Call(context, Utils::ToLocal(debug), kArgc, argv)
+ .ToLocal(&result);
+ RETURN_ON_FAILED_EXECUTION(Value);
+ RETURN_ESCAPED(result);
+}
+
+
+Local<Value> Debug::GetMirror(v8::Local<v8::Value> obj) {
+ RETURN_TO_LOCAL_UNCHECKED(GetMirror(Local<Context>(), obj), Value);
+}
+
+
+void Debug::ProcessDebugMessages(Isolate* isolate) {
+ reinterpret_cast<i::Isolate*>(isolate)->debug()->ProcessDebugMessages(true);
}
void Debug::ProcessDebugMessages() {
- i::Isolate::Current()->debug()->ProcessDebugMessages(true);
+ ProcessDebugMessages(reinterpret_cast<Isolate*>(i::Isolate::Current()));
+}
+
+
+Local<Context> Debug::GetDebugContext(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ ENTER_V8(i_isolate);
+ return Utils::ToLocal(i_isolate->debug()->GetDebugContext());
}
Local<Context> Debug::GetDebugContext() {
- i::Isolate* isolate = i::Isolate::Current();
- ENTER_V8(isolate);
- return Utils::ToLocal(i::Isolate::Current()->debug()->GetDebugContext());
+ return GetDebugContext(reinterpret_cast<Isolate*>(i::Isolate::Current()));
}
@@ -7107,9 +7883,21 @@
}
-Handle<String> CpuProfileNode::GetFunctionName() const {
- i::Isolate* isolate = i::Isolate::Current();
+MaybeLocal<Array> Debug::GetInternalProperties(Isolate* v8_isolate,
+ Local<Value> value) {
+ i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
+ ENTER_V8(isolate);
+ i::Handle<i::Object> val = Utils::OpenHandle(*value);
+ i::Handle<i::JSArray> result;
+ if (!i::Runtime::GetInternalProperties(isolate, val).ToHandle(&result))
+ return MaybeLocal<Array>();
+ return Utils::ToLocal(result);
+}
+
+
+Local<String> CpuProfileNode::GetFunctionName() const {
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+ i::Isolate* isolate = node->isolate();
const i::CodeEntry* entry = node->entry();
i::Handle<i::String> name =
isolate->factory()->InternalizeUtf8String(entry->name());
@@ -7132,9 +7920,9 @@
}
-Handle<String> CpuProfileNode::GetScriptResourceName() const {
- i::Isolate* isolate = i::Isolate::Current();
+Local<String> CpuProfileNode::GetScriptResourceName() const {
const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+ i::Isolate* isolate = node->isolate();
return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
node->entry()->resource_name()));
}
@@ -7176,7 +7964,7 @@
unsigned CpuProfileNode::GetCallUid() const {
- return reinterpret_cast<const i::ProfileNode*>(this)->entry()->GetCallUid();
+ return reinterpret_cast<const i::ProfileNode*>(this)->function_id();
}
@@ -7197,17 +7985,24 @@
}
-void CpuProfile::Delete() {
- i::Isolate* isolate = i::Isolate::Current();
- i::CpuProfiler* profiler = isolate->cpu_profiler();
- DCHECK(profiler != NULL);
- profiler->DeleteProfile(reinterpret_cast<i::CpuProfile*>(this));
+const std::vector<CpuProfileDeoptInfo>& CpuProfileNode::GetDeoptInfos() const {
+ const i::ProfileNode* node = reinterpret_cast<const i::ProfileNode*>(this);
+ return node->deopt_infos();
}
-Handle<String> CpuProfile::GetTitle() const {
- i::Isolate* isolate = i::Isolate::Current();
+void CpuProfile::Delete() {
+ i::CpuProfile* profile = reinterpret_cast<i::CpuProfile*>(this);
+ i::Isolate* isolate = profile->top_down()->isolate();
+ i::CpuProfiler* profiler = isolate->cpu_profiler();
+ DCHECK(profiler != NULL);
+ profiler->DeleteProfile(profile);
+}
+
+
+Local<String> CpuProfile::GetTitle() const {
const i::CpuProfile* profile = reinterpret_cast<const i::CpuProfile*>(this);
+ i::Isolate* isolate = profile->top_down()->isolate();
return ToApiHandle<String>(isolate->factory()->InternalizeUtf8String(
profile->title()));
}
@@ -7250,35 +8045,25 @@
void CpuProfiler::SetSamplingInterval(int us) {
- DCHECK(us >= 0);
+ DCHECK_GE(us, 0);
return reinterpret_cast<i::CpuProfiler*>(this)->set_sampling_interval(
base::TimeDelta::FromMicroseconds(us));
}
-void CpuProfiler::StartProfiling(Handle<String> title, bool record_samples) {
+void CpuProfiler::StartProfiling(Local<String> title, bool record_samples) {
reinterpret_cast<i::CpuProfiler*>(this)->StartProfiling(
*Utils::OpenHandle(*title), record_samples);
}
-void CpuProfiler::StartCpuProfiling(Handle<String> title, bool record_samples) {
- StartProfiling(title, record_samples);
-}
-
-
-CpuProfile* CpuProfiler::StopProfiling(Handle<String> title) {
+CpuProfile* CpuProfiler::StopProfiling(Local<String> title) {
return reinterpret_cast<CpuProfile*>(
reinterpret_cast<i::CpuProfiler*>(this)->StopProfiling(
*Utils::OpenHandle(*title)));
}
-const CpuProfile* CpuProfiler::StopCpuProfiling(Handle<String> title) {
- return StopProfiling(title);
-}
-
-
void CpuProfiler::SetIdle(bool is_idle) {
i::Isolate* isolate = reinterpret_cast<i::CpuProfiler*>(this)->isolate();
v8::StateTag state = isolate->current_vm_state();
@@ -7303,9 +8088,9 @@
}
-Handle<Value> HeapGraphEdge::GetName() const {
- i::Isolate* isolate = i::Isolate::Current();
+Local<Value> HeapGraphEdge::GetName() const {
i::HeapGraphEdge* edge = ToInternal(this);
+ i::Isolate* isolate = edge->isolate();
switch (edge->type()) {
case i::HeapGraphEdge::kContextVariable:
case i::HeapGraphEdge::kInternal:
@@ -7347,8 +8132,8 @@
}
-Handle<String> HeapGraphNode::GetName() const {
- i::Isolate* isolate = i::Isolate::Current();
+Local<String> HeapGraphNode::GetName() const {
+ i::Isolate* isolate = ToInternal(this)->isolate();
return ToApiHandle<String>(
isolate->factory()->InternalizeUtf8String(ToInternal(this)->name()));
}
@@ -7359,13 +8144,6 @@
}
-int HeapGraphNode::GetSelfSize() const {
- size_t size = ToInternal(this)->self_size();
- CHECK(size <= static_cast<size_t>(internal::kMaxInt));
- return static_cast<int>(size);
-}
-
-
size_t HeapGraphNode::GetShallowSize() const {
return ToInternal(this)->self_size();
}
@@ -7389,7 +8167,7 @@
void HeapSnapshot::Delete() {
- i::Isolate* isolate = i::Isolate::Current();
+ i::Isolate* isolate = ToInternal(this)->profiler()->isolate();
if (isolate->heap_profiler()->GetSnapshotsCount() > 1) {
ToInternal(this)->Delete();
} else {
@@ -7399,18 +8177,6 @@
}
-unsigned HeapSnapshot::GetUid() const {
- return ToInternal(this)->uid();
-}
-
-
-Handle<String> HeapSnapshot::GetTitle() const {
- i::Isolate* isolate = i::Isolate::Current();
- return ToApiHandle<String>(
- isolate->factory()->InternalizeUtf8String(ToInternal(this)->title()));
-}
-
-
const HeapGraphNode* HeapSnapshot::GetRoot() const {
return reinterpret_cast<const HeapGraphNode*>(ToInternal(this)->root());
}
@@ -7451,6 +8217,11 @@
}
+// static
+STATIC_CONST_MEMBER_DEFINITION const SnapshotObjectId
+ HeapProfiler::kUnknownObjectId;
+
+
int HeapProfiler::GetSnapshotCount() {
return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotsCount();
}
@@ -7462,13 +8233,13 @@
}
-SnapshotObjectId HeapProfiler::GetObjectId(Handle<Value> value) {
+SnapshotObjectId HeapProfiler::GetObjectId(Local<Value> value) {
i::Handle<i::Object> obj = Utils::OpenHandle(*value);
return reinterpret_cast<i::HeapProfiler*>(this)->GetSnapshotObjectId(obj);
}
-Handle<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
+Local<Value> HeapProfiler::FindObjectById(SnapshotObjectId id) {
i::Handle<i::Object> obj =
reinterpret_cast<i::HeapProfiler*>(this)->FindHeapObjectById(id);
if (obj.is_null()) return Local<Value>();
@@ -7482,12 +8253,10 @@
const HeapSnapshot* HeapProfiler::TakeHeapSnapshot(
- Handle<String> title,
- ActivityControl* control,
- ObjectNameResolver* resolver) {
+ ActivityControl* control, ObjectNameResolver* resolver) {
return reinterpret_cast<const HeapSnapshot*>(
- reinterpret_cast<i::HeapProfiler*>(this)->TakeSnapshot(
- *Utils::OpenHandle(*title), control, resolver));
+ reinterpret_cast<i::HeapProfiler*>(this)
+ ->TakeSnapshot(control, resolver));
}
@@ -7502,8 +8271,10 @@
}
-SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream) {
- return reinterpret_cast<i::HeapProfiler*>(this)->PushHeapObjectsStats(stream);
+SnapshotObjectId HeapProfiler::GetHeapStats(OutputStream* stream,
+ int64_t* timestamp_us) {
+ i::HeapProfiler* heap_profiler = reinterpret_cast<i::HeapProfiler*>(this);
+ return heap_profiler->PushHeapObjectsStats(stream, timestamp_us);
}
@@ -7592,11 +8363,10 @@
}
-// TODO(svenpanne) Deprecate this.
-void Testing::DeoptimizeAll() {
- i::Isolate* isolate = i::Isolate::Current();
- i::HandleScope scope(isolate);
- internal::Deoptimizer::DeoptimizeAll(isolate);
+void Testing::DeoptimizeAll(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i::HandleScope scope(i_isolate);
+ internal::Deoptimizer::DeoptimizeAll(i_isolate);
}
@@ -7769,4 +8539,5 @@
}
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8