HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Kitkat
|
4.4.4_r1
下载
查看原文件
收藏
根目录
external
chromium_org
v8
src
api.cc
// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "api.h" #include
// For memcpy, strlen. #include
// For isnan. #include "../include/v8-debug.h" #include "../include/v8-profiler.h" #include "../include/v8-testing.h" #include "assert-scope.h" #include "bootstrapper.h" #include "code-stubs.h" #include "compiler.h" #include "conversions-inl.h" #include "counters.h" #include "cpu-profiler.h" #include "debug.h" #include "deoptimizer.h" #include "execution.h" #include "global-handles.h" #include "heap-profiler.h" #include "heap-snapshot-generator-inl.h" #include "icu_util.h" #include "json-parser.h" #include "messages.h" #ifdef COMPRESS_STARTUP_DATA_BZ2 #include "natives.h" #endif #include "parser.h" #include "platform.h" #include "platform/time.h" #include "profile-generator-inl.h" #include "property-details.h" #include "property.h" #include "runtime.h" #include "runtime-profiler.h" #include "scanner-character-streams.h" #include "snapshot.h" #include "unicode-inl.h" #include "utils/random-number-generator.h" #include "v8threads.h" #include "version.h" #include "vm-state-inl.h" #define LOG_API(isolate, expr) LOG(isolate, ApiEntryCall(expr)) #define ENTER_V8(isolate) \ ASSERT((isolate)->IsInitialized()); \ i::VMState
__state__((isolate)) namespace v8 { #define ON_BAILOUT(isolate, location, code) \ if (IsExecutionTerminatingCheck(isolate)) { \ code; \ UNREACHABLE(); \ } #define EXCEPTION_PREAMBLE(isolate) \ (isolate)->handle_scope_implementer()->IncrementCallDepth(); \ ASSERT(!(isolate)->external_caught_exception()); \ 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) { \ if (handle_scope_implementer->CallDepthIsZero() && \ (isolate)->is_out_of_memory()) { \ if (!(isolate)->ignore_out_of_memory()) \ i::V8::FatalProcessOutOfMemory(NULL); \ } \ bool call_depth_is_zero = handle_scope_implementer->CallDepthIsZero(); \ (isolate)->OptionalRescheduleException(call_depth_is_zero); \ do_callback \ return value; \ } \ do_callback \ } while (false) #define EXCEPTION_BAILOUT_CHECK_DO_CALLBACK(isolate, value) \ EXCEPTION_BAILOUT_CHECK_GENERIC( \ isolate, value, i::V8::FireCallCompletedCallback(isolate);) #define EXCEPTION_BAILOUT_CHECK(isolate, value) \ EXCEPTION_BAILOUT_CHECK_GENERIC(isolate, value, ;) #define API_ENTRY_CHECK(isolate, msg) \ do { \ if (v8::Locker::IsActive()) { \ ApiCheck(isolate->thread_manager()->IsLockedByCurrentThread(), \ msg, \ "Entering the V8 API without proper locking in place"); \ } \ } while (false) // --- E x c e p t i o n B e h a v i o r --- static void DefaultFatalErrorHandler(const char* location, const char* message) { i::Isolate* isolate = i::Isolate::Current(); if (isolate->IsInitialized()) { i::VMState
state(isolate); API_Fatal(location, message); } else { API_Fatal(location, message); } } static FatalErrorCallback GetFatalErrorHandler() { i::Isolate* isolate = i::Isolate::Current(); if (isolate->exception_behavior() == NULL) { isolate->set_exception_behavior(DefaultFatalErrorHandler); } return isolate->exception_behavior(); } void i::FatalProcessOutOfMemory(const char* location) { i::V8::FatalProcessOutOfMemory(location, false); } // 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::HeapStats heap_stats; int start_marker; heap_stats.start_marker = &start_marker; int new_space_size; 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 code_space_size; heap_stats.code_space_size = &code_space_size; intptr_t code_space_capacity; heap_stats.code_space_capacity = &code_space_capacity; intptr_t map_space_size; 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; heap_stats.global_handle_count = &global_handle_count; int weak_global_handle_count; heap_stats.weak_global_handle_count = &weak_global_handle_count; int pending_global_handle_count; heap_stats.pending_global_handle_count = &pending_global_handle_count; int near_death_global_handle_count; heap_stats.near_death_global_handle_count = &near_death_global_handle_count; int free_global_handle_count; heap_stats.free_global_handle_count = &free_global_handle_count; intptr_t memory_allocator_size; heap_stats.memory_allocator_size = &memory_allocator_size; intptr_t memory_allocator_capacity; heap_stats.memory_allocator_capacity = &memory_allocator_capacity; int objects_per_type[LAST_TYPE + 1] = {0}; heap_stats.objects_per_type = objects_per_type; int size_per_type[LAST_TYPE + 1] = {0}; heap_stats.size_per_type = size_per_type; int os_error; heap_stats.os_error = &os_error; 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); } isolate->SignalFatalError(); FatalErrorCallback callback = GetFatalErrorHandler(); const char* message = "Allocation failed - process out of memory"; callback(location, message); // If the callback returns, we stop execution. FATAL("API fatal error handler returned after process out of memory"); } bool Utils::ReportApiFailure(const char* location, const char* message) { FatalErrorCallback callback = GetFatalErrorHandler(); callback(location, message); i::Isolate* isolate = i::Isolate::Current(); isolate->SignalFatalError(); return false; } bool V8::IsDead() { i::Isolate* isolate = i::Isolate::Current(); return isolate->IsDead(); } static inline bool ApiCheck(bool condition, const char* location, const char* message) { return condition ? true : Utils::ReportApiFailure(location, message); } static bool ReportEmptyHandle(const char* location) { FatalErrorCallback callback = GetFatalErrorHandler(); callback(location, "Reading from empty handle"); return true; } static inline bool IsExecutionTerminatingCheck(i::Isolate* isolate) { if (!isolate->IsInitialized()) return false; if (isolate->has_scheduled_exception()) { return isolate->scheduled_exception() == isolate->heap()->termination_exception(); } return false; } static inline bool EmptyCheck(const char* location, v8::Handle
obj) { return obj.IsEmpty() ? ReportEmptyHandle(location) : false; } static inline bool EmptyCheck(const char* location, const v8::Data* obj) { return (obj == 0) ? ReportEmptyHandle(location) : false; } // --- S t a t i c s --- static bool InitializeHelper(i::Isolate* isolate) { // If the isolate has a function entry hook, it needs to re-build all its // code stubs with entry hooks embedded, so let's deserialize a snapshot. if (isolate == NULL || isolate->function_entry_hook() == NULL) { if (i::Snapshot::Initialize()) return true; } return i::V8::Initialize(NULL); } static inline bool EnsureInitializedForIsolate(i::Isolate* isolate, const char* location) { if (isolate != NULL) { if (isolate->IsInitialized()) return true; } ASSERT(isolate == i::Isolate::Current()); return ApiCheck(InitializeHelper(isolate), location, "Error initializing V8"); } // Some initializing API functions are called early and may be // called on a thread different from static initializer thread. // If Isolate API is used, Isolate::Enter() will initialize TLS so // Isolate::Current() works. If it's a legacy case, then the thread // may not have TLS initialized yet. However, in initializing APIs it // may be too early to call EnsureInitialized() - some pre-init // parameters still have to be configured. static inline i::Isolate* EnterIsolateIfNeeded() { i::Isolate* isolate = i::Isolate::UncheckedCurrent(); if (isolate != NULL) return isolate; i::Isolate::EnterDefaultIsolate(); isolate = i::Isolate::Current(); return isolate; } StartupDataDecompressor::StartupDataDecompressor() : raw_data(i::NewArray
(V8::GetCompressedStartupDataCount())) { for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) { raw_data[i] = NULL; } } StartupDataDecompressor::~StartupDataDecompressor() { for (int i = 0; i < V8::GetCompressedStartupDataCount(); ++i) { i::DeleteArray(raw_data[i]); } i::DeleteArray(raw_data); } int StartupDataDecompressor::Decompress() { int compressed_data_count = V8::GetCompressedStartupDataCount(); StartupData* compressed_data = i::NewArray
(compressed_data_count); V8::GetCompressedStartupData(compressed_data); for (int i = 0; i < compressed_data_count; ++i) { char* decompressed = raw_data[i] = i::NewArray
(compressed_data[i].raw_size); if (compressed_data[i].compressed_size != 0) { int result = DecompressData(decompressed, &compressed_data[i].raw_size, compressed_data[i].data, compressed_data[i].compressed_size); if (result != 0) return result; } else { ASSERT_EQ(0, compressed_data[i].raw_size); } compressed_data[i].data = decompressed; } V8::SetDecompressedStartupData(compressed_data); i::DeleteArray(compressed_data); return 0; } StartupData::CompressionAlgorithm V8::GetCompressedStartupDataAlgorithm() { #ifdef COMPRESS_STARTUP_DATA_BZ2 return StartupData::kBZip2; #else return StartupData::kUncompressed; #endif } enum CompressedStartupDataItems { kSnapshot = 0, kSnapshotContext, kLibraries, kExperimentalLibraries, kCompressedStartupDataCount }; int V8::GetCompressedStartupDataCount() { #ifdef COMPRESS_STARTUP_DATA_BZ2 return kCompressedStartupDataCount; #else return 0; #endif } void V8::GetCompressedStartupData(StartupData* compressed_data) { #ifdef COMPRESS_STARTUP_DATA_BZ2 compressed_data[kSnapshot].data = reinterpret_cast
(i::Snapshot::data()); compressed_data[kSnapshot].compressed_size = i::Snapshot::size(); compressed_data[kSnapshot].raw_size = i::Snapshot::raw_size(); compressed_data[kSnapshotContext].data = reinterpret_cast
(i::Snapshot::context_data()); compressed_data[kSnapshotContext].compressed_size = i::Snapshot::context_size(); compressed_data[kSnapshotContext].raw_size = i::Snapshot::context_raw_size(); i::Vector
libraries_source = i::Natives::GetScriptsSource(); compressed_data[kLibraries].data = reinterpret_cast
(libraries_source.start()); compressed_data[kLibraries].compressed_size = libraries_source.length(); compressed_data[kLibraries].raw_size = i::Natives::GetRawScriptsSize(); i::Vector
exp_libraries_source = i::ExperimentalNatives::GetScriptsSource(); compressed_data[kExperimentalLibraries].data = reinterpret_cast
(exp_libraries_source.start()); compressed_data[kExperimentalLibraries].compressed_size = exp_libraries_source.length(); compressed_data[kExperimentalLibraries].raw_size = i::ExperimentalNatives::GetRawScriptsSize(); #endif } void V8::SetDecompressedStartupData(StartupData* decompressed_data) { #ifdef COMPRESS_STARTUP_DATA_BZ2 ASSERT_EQ(i::Snapshot::raw_size(), decompressed_data[kSnapshot].raw_size); i::Snapshot::set_raw_data( reinterpret_cast
(decompressed_data[kSnapshot].data)); ASSERT_EQ(i::Snapshot::context_raw_size(), decompressed_data[kSnapshotContext].raw_size); i::Snapshot::set_context_raw_data( reinterpret_cast
( decompressed_data[kSnapshotContext].data)); ASSERT_EQ(i::Natives::GetRawScriptsSize(), decompressed_data[kLibraries].raw_size); i::Vector
libraries_source( decompressed_data[kLibraries].data, decompressed_data[kLibraries].raw_size); i::Natives::SetRawScriptsSource(libraries_source); ASSERT_EQ(i::ExperimentalNatives::GetRawScriptsSize(), decompressed_data[kExperimentalLibraries].raw_size); i::Vector
exp_libraries_source( decompressed_data[kExperimentalLibraries].data, decompressed_data[kExperimentalLibraries].raw_size); i::ExperimentalNatives::SetRawScriptsSource(exp_libraries_source); #endif } void V8::SetFatalErrorHandler(FatalErrorCallback that) { i::Isolate* isolate = EnterIsolateIfNeeded(); isolate->set_exception_behavior(that); } void V8::SetAllowCodeGenerationFromStringsCallback( AllowCodeGenerationFromStringsCallback callback) { i::Isolate* isolate = EnterIsolateIfNeeded(); isolate->set_allow_code_gen_callback(callback); } void V8::SetFlagsFromString(const char* str, int length) { i::FlagList::SetFlagsFromString(str, length); } void V8::SetFlagsFromCommandLine(int* argc, char** argv, bool remove_flags) { i::FlagList::SetFlagsFromCommandLine(argc, argv, remove_flags); } v8::Handle
ThrowException(v8::Handle
value) { return v8::Isolate::GetCurrent()->ThrowException(value); } RegisteredExtension* RegisteredExtension::first_extension_ = NULL; RegisteredExtension::RegisteredExtension(Extension* extension) : extension_(extension) { } void RegisteredExtension::Register(RegisteredExtension* that) { that->next_ = first_extension_; first_extension_ = that; } void RegisteredExtension::UnregisterAll() { RegisteredExtension* re = first_extension_; while (re != NULL) { RegisteredExtension* next = re->next(); delete re; re = next; } } void RegisterExtension(Extension* that) { RegisteredExtension* extension = new RegisteredExtension(that); RegisteredExtension::Register(extension); } Extension::Extension(const char* name, const char* source, int dep_count, const char** deps, int source_length) : name_(name), source_length_(source_length >= 0 ? source_length : (source ? static_cast
(strlen(source)) : 0)), source_(source, source_length_), dep_count_(dep_count), deps_(deps), auto_enable_(false) { CHECK(source != NULL || source_length_ == 0); } v8::Handle
Undefined() { i::Isolate* isolate = i::Isolate::Current(); if (!EnsureInitializedForIsolate(isolate, "v8::Undefined()")) { return v8::Handle
(); } return ToApiHandle
(isolate->factory()->undefined_value()); } v8::Handle
Null() { i::Isolate* isolate = i::Isolate::Current(); if (!EnsureInitializedForIsolate(isolate, "v8::Null()")) { return v8::Handle
(); } return ToApiHandle
(isolate->factory()->null_value()); } v8::Handle
True() { i::Isolate* isolate = i::Isolate::Current(); if (!EnsureInitializedForIsolate(isolate, "v8::True()")) { return v8::Handle
(); } return ToApiHandle
(isolate->factory()->true_value()); } v8::Handle
False() { i::Isolate* isolate = i::Isolate::Current(); if (!EnsureInitializedForIsolate(isolate, "v8::False()")) { return v8::Handle
(); } return ToApiHandle
(isolate->factory()->false_value()); } ResourceConstraints::ResourceConstraints() : max_young_space_size_(0), max_old_space_size_(0), max_executable_size_(0), stack_limit_(NULL), max_available_threads_(0) { } void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory, uint32_t number_of_processors) { const int lump_of_memory = (i::kPointerSize / 4) * i::MB; #if V8_OS_ANDROID // Android has higher physical memory requirements before raising the maximum // heap size limits since it has no swap space. const uint64_t low_limit = 512ul * i::MB; const uint64_t medium_limit = 1ul * i::GB; const uint64_t high_limit = 2ul * i::GB; #else const uint64_t low_limit = 512ul * i::MB; const uint64_t medium_limit = 768ul * i::MB; const uint64_t high_limit = 1ul * i::GB; #endif // The young_space_size should be a power of 2 and old_generation_size should // be a multiple of Page::kPageSize. if (physical_memory <= low_limit) { set_max_young_space_size(2 * lump_of_memory); set_max_old_space_size(128 * lump_of_memory); set_max_executable_size(96 * lump_of_memory); } else if (physical_memory <= medium_limit) { set_max_young_space_size(8 * lump_of_memory); set_max_old_space_size(256 * lump_of_memory); set_max_executable_size(192 * lump_of_memory); } else if (physical_memory <= high_limit) { set_max_young_space_size(16 * lump_of_memory); set_max_old_space_size(512 * lump_of_memory); set_max_executable_size(256 * lump_of_memory); } else { set_max_young_space_size(16 * lump_of_memory); set_max_old_space_size(700 * lump_of_memory); set_max_executable_size(256 * lump_of_memory); } set_max_available_threads(i::Max(i::Min(number_of_processors, 4u), 1u)); } void ResourceConstraints::ConfigureDefaults(uint64_t physical_memory) { ConfigureDefaults(physical_memory, i::CPU::NumberOfProcessorsOnline()); } bool SetResourceConstraints(Isolate* v8_isolate, ResourceConstraints* constraints) { i::Isolate* isolate = reinterpret_cast
(v8_isolate); int young_space_size = constraints->max_young_space_size(); int old_gen_size = constraints->max_old_space_size(); int max_executable_size = constraints->max_executable_size(); if (young_space_size != 0 || old_gen_size != 0 || max_executable_size != 0) { // After initialization it's too late to change Heap constraints. ASSERT(!isolate->IsInitialized()); bool result = isolate->heap()->ConfigureHeap(young_space_size / 2, old_gen_size, max_executable_size); if (!result) return false; } if (constraints->stack_limit() != NULL) { uintptr_t limit = reinterpret_cast
(constraints->stack_limit()); isolate->stack_guard()->SetStackLimit(limit); } isolate->set_max_available_threads(constraints->max_available_threads()); return true; } i::Object** V8::GlobalizeReference(i::Isolate* isolate, i::Object** obj) { LOG_API(isolate, "Persistent::New"); i::Handle
result = isolate->global_handles()->Create(*obj); #ifdef DEBUG (*obj)->Verify(); #endif // DEBUG return result.location(); } i::Object** V8::CopyPersistent(i::Object** obj) { i::Handle
result = i::GlobalHandles::CopyGlobal(obj); #ifdef DEBUG (*obj)->Verify(); #endif // DEBUG return result.location(); } void V8::MakeWeak(i::Object** object, void* parameters, WeakCallback weak_callback, RevivableCallback weak_reference_callback) { i::GlobalHandles::MakeWeak(object, parameters, weak_callback, weak_reference_callback); } void V8::ClearWeak(i::Object** obj) { i::GlobalHandles::ClearWeakness(obj); } void V8::DisposeGlobal(i::Object** obj) { i::GlobalHandles::Destroy(obj); } void V8::Eternalize(Isolate* v8_isolate, Value* value, int* index) { i::Isolate* isolate = reinterpret_cast
(v8_isolate); i::Object* object = *Utils::OpenHandle(value); isolate->eternal_handles()->Create(isolate, object, index); } Local
V8::GetEternal(Isolate* v8_isolate, int index) { i::Isolate* isolate = reinterpret_cast
(v8_isolate); return Utils::ToLocal(isolate->eternal_handles()->Get(index)); } // --- H a n d l e s --- HandleScope::HandleScope(Isolate* isolate) { Initialize(isolate); } void HandleScope::Initialize(Isolate* isolate) { i::Isolate* internal_isolate = reinterpret_cast
(isolate); API_ENTRY_CHECK(internal_isolate, "HandleScope::HandleScope"); v8::ImplementationUtilities::HandleScopeData* current = internal_isolate->handle_scope_data(); isolate_ = internal_isolate; prev_next_ = current->next; prev_limit_ = current->limit; is_closed_ = false; current->level++; } HandleScope::~HandleScope() { if (!is_closed_) { Leave(); } } void HandleScope::Leave() { return i::HandleScope::CloseScope(isolate_, prev_next_, prev_limit_); } int HandleScope::NumberOfHandles() { i::Isolate* isolate = i::Isolate::Current(); if (!EnsureInitializedForIsolate(isolate, "HandleScope::NumberOfHandles")) { return 0; } return i::HandleScope::NumberOfHandles(isolate); } i::Object** HandleScope::CreateHandle(i::Isolate* isolate, i::Object* value) { return i::HandleScope::CreateHandle(isolate, value); } i::Object** HandleScope::CreateHandle(i::HeapObject* heap_object, i::Object* value) { ASSERT(heap_object->IsHeapObject()); return i::HandleScope::CreateHandle(heap_object->GetIsolate(), value); } EscapableHandleScope::EscapableHandleScope(Isolate* v8_isolate) { i::Isolate* isolate = reinterpret_cast
(v8_isolate); escape_slot_ = CreateHandle(isolate, isolate->heap()->the_hole_value()); Initialize(v8_isolate); } i::Object** EscapableHandleScope::Escape(i::Object** escape_value) { ApiCheck(*escape_slot_ == isolate_->heap()->the_hole_value(), "EscapeableHandleScope::Escape", "Escape value set twice"); if (escape_value == NULL) { *escape_slot_ = isolate_->heap()->undefined_value(); return NULL; } *escape_slot_ = *escape_value; return escape_slot_; } void Context::Enter() { i::Handle
env = Utils::OpenHandle(this); i::Isolate* isolate = env->GetIsolate(); ENTER_V8(isolate); isolate->handle_scope_implementer()->EnterContext(env); isolate->handle_scope_implementer()->SaveContext(isolate->context()); isolate->set_context(*env); } void Context::Exit() { // TODO(dcarney): fix this once chrome is fixed. i::Isolate* isolate = i::Isolate::Current(); i::Handle
context = i::Handle
::null(); ENTER_V8(isolate); if (!ApiCheck(isolate->handle_scope_implementer()->LeaveContext(context), "v8::Context::Exit()", "Cannot exit non-entered context")) { return; } // Content of 'last_context' could be NULL. i::Context* last_context = isolate->handle_scope_implementer()->RestoreContext(); isolate->set_context(last_context); } static void* DecodeSmiToAligned(i::Object* value, const char* location) { ApiCheck(value->IsSmi(), location, "Not a Smi"); return reinterpret_cast
(value); } static i::Smi* EncodeAlignedAsSmi(void* value, const char* location) { i::Smi* smi = reinterpret_cast
(value); ApiCheck(smi->IsSmi(), location, "Pointer is not aligned"); return smi; } static i::Handle
EmbedderDataFor(Context* context, int index, bool can_grow, const char* location) { i::Handle
env = Utils::OpenHandle(context); bool ok = ApiCheck(env->IsNativeContext(), location, "Not a native context") && ApiCheck(index >= 0, location, "Negative index"); if (!ok) return i::Handle
(); i::Handle
data(env->embedder_data()); if (index < data->length()) return data; if (!can_grow) { Utils::ReportApiFailure(location, "Index too large"); return i::Handle
(); } int new_size = i::Max(index, data->length() << 1) + 1; data = env->GetIsolate()->factory()->CopySizeFixedArray(data, new_size); env->set_embedder_data(*data); return data; } v8::Local
Context::SlowGetEmbedderData(int index) { const char* location = "v8::Context::GetEmbedderData()"; i::Handle
data = EmbedderDataFor(this, index, false, location); if (data.is_null()) return Local
(); i::Handle
result(data->get(index), data->GetIsolate()); return Utils::ToLocal(result); } void Context::SetEmbedderData(int index, v8::Handle
value) { const char* location = "v8::Context::SetEmbedderData()"; i::Handle
data = EmbedderDataFor(this, index, true, location); if (data.is_null()) return; i::Handle
val = Utils::OpenHandle(*value); data->set(index, *val); ASSERT_EQ(*Utils::OpenHandle(*value), *Utils::OpenHandle(*GetEmbedderData(index))); } void* Context::SlowGetAlignedPointerFromEmbedderData(int index) { const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()"; i::Handle
data = EmbedderDataFor(this, index, false, location); if (data.is_null()) return NULL; return DecodeSmiToAligned(data->get(index), location); } void Context::SetAlignedPointerInEmbedderData(int index, void* value) { const char* location = "v8::Context::SetAlignedPointerInEmbedderData()"; i::Handle
data = EmbedderDataFor(this, index, true, location); data->set(index, EncodeAlignedAsSmi(value, location)); ASSERT_EQ(value, GetAlignedPointerFromEmbedderData(index)); } i::Object** v8::HandleScope::RawClose(i::Object** value) { if (!ApiCheck(!is_closed_, "v8::HandleScope::Close()", "Local scope has already been closed")) { return 0; } LOG_API(isolate_, "CloseHandleScope"); // Read the result before popping the handle block. i::Object* result = NULL; if (value != NULL) { result = *value; } is_closed_ = true; Leave(); if (value == NULL) { return NULL; } // Allocate a new handle on the previous handle block. i::Handle
handle(result, isolate_); return handle.location(); } // --- N e a n d e r --- // A constructor cannot easily return an error value, therefore it is necessary // to check for a dead VM with ON_BAILOUT before constructing any Neander // objects. To remind you about this there is no HandleScope in the // NeanderObject constructor. When you add one to the site calling the // constructor you should check that you ensured the VM was not dead first. NeanderObject::NeanderObject(int size) { i::Isolate* isolate = i::Isolate::Current(); EnsureInitializedForIsolate(isolate, "v8::Nowhere"); ENTER_V8(isolate); value_ = isolate->factory()->NewNeanderObject(); i::Handle
elements = isolate->factory()->NewFixedArray(size); value_->set_elements(*elements); } int NeanderObject::size() { return i::FixedArray::cast(value_->elements())->length(); } NeanderArray::NeanderArray() : obj_(2) { obj_.set(0, i::Smi::FromInt(0)); } int NeanderArray::length() { return i::Smi::cast(obj_.get(0))->value(); } i::Object* NeanderArray::get(int offset) { ASSERT(0 <= offset); ASSERT(offset < length()); return obj_.get(offset + 1); } // This method cannot easily return an error value, therefore it is necessary // to check for a dead VM with ON_BAILOUT before calling it. To remind you // about this there is no HandleScope in this method. When you add one to the // site calling this method you should check that you ensured the VM was not // dead first. void NeanderArray::add(i::Handle
value) { int length = this->length(); int size = obj_.size(); if (length == size - 1) { i::Factory* factory = i::Isolate::Current()->factory(); i::Handle
new_elms = factory->NewFixedArray(2 * size); for (int i = 0; i < length; i++) new_elms->set(i + 1, get(i)); obj_.value()->set_elements(*new_elms); } obj_.set(length + 1, *value); obj_.set(0, i::Smi::FromInt(length + 1)); } void NeanderArray::set(int index, i::Object* value) { if (index < 0 || index >= this->length()) return; obj_.set(index + 1, value); } // --- T e m p l a t e --- static void InitializeTemplate(i::Handle
that, int type) { that->set_tag(i::Smi::FromInt(type)); } static void TemplateSet(i::Isolate* isolate, v8::Template* templ, int length, v8::Handle
* data) { i::Handle
list(Utils::OpenHandle(templ)->property_list(), isolate); if (list->IsUndefined()) { list = NeanderArray().value(); Utils::OpenHandle(templ)->set_property_list(*list); } NeanderArray array(list); array.add(Utils::OpenHandle(*v8::Integer::New(length))); for (int i = 0; i < length; i++) { i::Handle
value = data[i].IsEmpty() ? i::Handle
(isolate->factory()->undefined_value()) : Utils::OpenHandle(*data[i]); array.add(value); } } void Template::Set(v8::Handle
name, v8::Handle
value, v8::PropertyAttribute attribute) { i::Isolate* isolate = i::Isolate::Current(); ENTER_V8(isolate); i::HandleScope scope(isolate); const int kSize = 3; v8::Handle
data[kSize] = { name, value, v8::Integer::New(attribute)}; TemplateSet(isolate, this, kSize, data); } void Template::SetAccessorProperty( v8::Local
name, v8::Local
getter, v8::Local
setter, v8::PropertyAttribute attribute, v8::AccessControl access_control) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); ASSERT(!name.IsEmpty()); ASSERT(!getter.IsEmpty() || !setter.IsEmpty()); i::HandleScope scope(isolate); const int kSize = 5; v8::Handle
data[kSize] = { name, getter, setter, v8::Integer::New(attribute), v8::Integer::New(access_control)}; TemplateSet(isolate, this, kSize, data); } // --- F u n c t i o n T e m p l a t e --- static void InitializeFunctionTemplate( i::Handle
info) { info->set_tag(i::Smi::FromInt(Consts::FUNCTION_TEMPLATE)); info->set_flag(0); } Local
FunctionTemplate::PrototypeTemplate() { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); i::Handle
result(Utils::OpenHandle(this)->prototype_template(), isolate); if (result->IsUndefined()) { result = Utils::OpenHandle(*ObjectTemplate::New()); Utils::OpenHandle(this)->set_prototype_template(*result); } return ToApiHandle
(result); } void FunctionTemplate::Inherit(v8::Handle
value) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); Utils::OpenHandle(this)->set_parent_template(*Utils::OpenHandle(*value)); } static Local
FunctionTemplateNew( i::Isolate* isolate, FunctionCallback callback, v8::Handle
data, v8::Handle
signature, int length, bool do_not_cache) { i::Handle
struct_obj = isolate->factory()->NewStruct(i::FUNCTION_TEMPLATE_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); InitializeFunctionTemplate(obj); obj->set_do_not_cache(do_not_cache); int next_serial_number = 0; if (!do_not_cache) { next_serial_number = isolate->next_serial_number() + 1; isolate->set_next_serial_number(next_serial_number); } obj->set_serial_number(i::Smi::FromInt(next_serial_number)); if (callback != 0) { if (data.IsEmpty()) { data = v8::Undefined(reinterpret_cast
(isolate)); } Utils::ToLocal(obj)->SetCallHandler(callback, data); } obj->set_length(length); obj->set_undetectable(false); obj->set_needs_access_check(false); if (!signature.IsEmpty()) obj->set_signature(*Utils::OpenHandle(*signature)); return Utils::ToLocal(obj); } Local
FunctionTemplate::New( Isolate* isolate, FunctionCallback callback, v8::Handle
data, v8::Handle
signature, int length) { i::Isolate* i_isolate = reinterpret_cast
(isolate); EnsureInitializedForIsolate(i_isolate, "v8::FunctionTemplate::New()"); LOG_API(i_isolate, "FunctionTemplate::New"); ENTER_V8(i_isolate); return FunctionTemplateNew( i_isolate, callback, data, signature, length, false); } Local
FunctionTemplate::New( FunctionCallback callback, v8::Handle
data, v8::Handle
signature, int length) { return New(Isolate::GetCurrent(), callback, data, signature, length); } Local
Signature::New(Isolate* isolate, Handle
receiver, int argc, Handle
argv[]) { i::Isolate* i_isolate = reinterpret_cast
(isolate); EnsureInitializedForIsolate(i_isolate, "v8::Signature::New()"); LOG_API(i_isolate, "Signature::New"); ENTER_V8(i_isolate); i::Handle
struct_obj = i_isolate->factory()->NewStruct(i::SIGNATURE_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); if (!receiver.IsEmpty()) obj->set_receiver(*Utils::OpenHandle(*receiver)); if (argc > 0) { i::Handle
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
Signature::New(Handle
receiver, int argc, Handle
argv[]) { return New(Isolate::GetCurrent(), receiver, argc, argv); } Local
AccessorSignature::New( Isolate* isolate, Handle
receiver) { return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver)); } // While this is just a cast, it's lame not to use an Isolate parameter. Local
AccessorSignature::New( Handle
receiver) { return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver)); } template
static Local
NewDescriptor( Isolate* isolate, const i::DeclaredAccessorDescriptorData& data, Data* previous_descriptor) { i::Isolate* internal_isolate = reinterpret_cast
(isolate); i::Handle
previous = i::Handle
(); if (previous_descriptor != NULL) { previous = Utils::OpenHandle( static_cast
(previous_descriptor)); } i::Handle
descriptor = i::DeclaredAccessorDescriptor::Create(internal_isolate, data, previous); return Utils::Convert
(descriptor); } Local
ObjectOperationDescriptor::NewInternalFieldDereference( Isolate* isolate, int internal_field) { i::DeclaredAccessorDescriptorData data; data.type = i::kDescriptorObjectDereference; data.object_dereference_descriptor.internal_field = internal_field; return NewDescriptor
(isolate, data, NULL); } Local
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
(isolate, data, this); } Local
RawOperationDescriptor::NewHandleDereference( Isolate* isolate) { i::DeclaredAccessorDescriptorData data; data.type = i::kDescriptorReturnObject; return NewDescriptor
(isolate, data, this); } Local
RawOperationDescriptor::NewRawDereference( Isolate* isolate) { i::DeclaredAccessorDescriptorData data; data.type = i::kDescriptorPointerDereference; return NewDescriptor
(isolate, data, this); } Local
RawOperationDescriptor::NewPointerCompare( Isolate* isolate, void* compare_value) { i::DeclaredAccessorDescriptorData data; data.type = i::kDescriptorPointerCompare; data.pointer_compare_descriptor.compare_value = compare_value; return NewDescriptor
(isolate, data, this); } Local
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
(isolate, data, this); } template
static Local
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
(isolate, data, operation); } Local
RawOperationDescriptor::NewBitmaskCompare8( Isolate* isolate, uint8_t bitmask, uint8_t compare_value) { return NewBitmaskCompare(isolate, bitmask, compare_value, this); } Local
RawOperationDescriptor::NewBitmaskCompare16( Isolate* isolate, uint16_t bitmask, uint16_t compare_value) { return NewBitmaskCompare(isolate, bitmask, compare_value, this); } Local
RawOperationDescriptor::NewBitmaskCompare32( Isolate* isolate, uint32_t bitmask, uint32_t compare_value) { return NewBitmaskCompare(isolate, bitmask, compare_value, this); } Local
TypeSwitch::New(Handle
type) { Handle
types[1] = { type }; return TypeSwitch::New(1, types); } Local
TypeSwitch::New(int argc, Handle
types[]) { i::Isolate* isolate = i::Isolate::Current(); EnsureInitializedForIsolate(isolate, "v8::TypeSwitch::New()"); LOG_API(isolate, "TypeSwitch::New"); ENTER_V8(isolate); i::Handle
vector = isolate->factory()->NewFixedArray(argc); for (int i = 0; i < argc; i++) vector->set(i, *Utils::OpenHandle(*types[i])); i::Handle
struct_obj = isolate->factory()->NewStruct(i::TYPE_SWITCH_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); obj->set_types(*vector); return Utils::ToLocal(obj); } int TypeSwitch::match(v8::Handle
value) { i::Isolate* isolate = i::Isolate::Current(); LOG_API(isolate, "TypeSwitch::match"); USE(isolate); i::Handle
obj = Utils::OpenHandle(*value); i::Handle
info = Utils::OpenHandle(this); 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
foreign = FromCData(obj->GetIsolate(), cdata); \ (obj)->setter(*foreign); \ } while (false) void FunctionTemplate::SetCallHandler(FunctionCallback callback, v8::Handle
data) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle
struct_obj = isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); SET_FIELD_WRAPPED(obj, set_callback, callback); if (data.IsEmpty()) { data = v8::Undefined(reinterpret_cast
(isolate)); } obj->set_data(*Utils::OpenHandle(*data)); Utils::OpenHandle(this)->set_call_code(*obj); } static i::Handle
SetAccessorInfoProperties( i::Handle
obj, v8::Handle
name, v8::AccessControl settings, v8::PropertyAttribute attributes, v8::Handle
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); if (settings & PROHIBITS_OVERWRITING) obj->set_prohibits_overwriting(true); obj->set_property_attributes(static_cast
(attributes)); if (!signature.IsEmpty()) { obj->set_expected_receiver_type(*Utils::OpenHandle(*signature)); } return obj; } template
static i::Handle
MakeAccessorInfo( v8::Handle
name, Getter getter, Setter setter, v8::Handle
data, v8::AccessControl settings, v8::PropertyAttribute attributes, v8::Handle
signature) { i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate(); i::Handle
obj = isolate->factory()->NewExecutableAccessorInfo(); SET_FIELD_WRAPPED(obj, set_getter, getter); SET_FIELD_WRAPPED(obj, set_setter, setter); if (data.IsEmpty()) { data = v8::Undefined(reinterpret_cast
(isolate)); } obj->set_data(*Utils::OpenHandle(*data)); return SetAccessorInfoProperties(obj, name, settings, attributes, signature); } static i::Handle
MakeAccessorInfo( v8::Handle
name, v8::Handle
descriptor, void* setter_ignored, void* data_ignored, v8::AccessControl settings, v8::PropertyAttribute attributes, v8::Handle
signature) { i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate(); if (descriptor.IsEmpty()) return i::Handle
(); i::Handle
obj = isolate->factory()->NewDeclaredAccessorInfo(); obj->set_descriptor(*Utils::OpenHandle(*descriptor)); return SetAccessorInfoProperties(obj, name, settings, attributes, signature); } Local
FunctionTemplate::InstanceTemplate() { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); if (EmptyCheck("v8::FunctionTemplate::InstanceTemplate()", this)) return Local
(); ENTER_V8(isolate); i::Handle
handle = Utils::OpenHandle(this); if (handle->instance_template()->IsUndefined()) { Local
templ = ObjectTemplate::New(isolate, ToApiHandle
(handle)); handle->set_instance_template(*Utils::OpenHandle(*templ)); } i::Handle
result( i::ObjectTemplateInfo::cast(handle->instance_template())); return Utils::ToLocal(result); } void FunctionTemplate::SetLength(int length) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); Utils::OpenHandle(this)->set_length(length); } void FunctionTemplate::SetClassName(Handle
name) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); Utils::OpenHandle(this)->set_class_name(*Utils::OpenHandle(*name)); } void FunctionTemplate::SetHiddenPrototype(bool value) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); Utils::OpenHandle(this)->set_hidden_prototype(value); } void FunctionTemplate::ReadOnlyPrototype() { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); Utils::OpenHandle(this)->set_read_only_prototype(true); } void FunctionTemplate::RemovePrototype() { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); Utils::OpenHandle(this)->set_remove_prototype(true); } // --- O b j e c t T e m p l a t e --- Local
ObjectTemplate::New(Isolate* isolate) { return New(reinterpret_cast
(isolate), Local
()); } Local
ObjectTemplate::New() { return New(i::Isolate::Current(), Local
()); } Local
ObjectTemplate::New( i::Isolate* isolate, v8::Handle
constructor) { EnsureInitializedForIsolate(isolate, "v8::ObjectTemplate::New()"); LOG_API(isolate, "ObjectTemplate::New"); ENTER_V8(isolate); i::Handle
struct_obj = isolate->factory()->NewStruct(i::OBJECT_TEMPLATE_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); InitializeTemplate(obj, Consts::OBJECT_TEMPLATE); if (!constructor.IsEmpty()) obj->set_constructor(*Utils::OpenHandle(*constructor)); obj->set_internal_field_count(i::Smi::FromInt(0)); return Utils::ToLocal(obj); } // Ensure that the object template has a constructor. If no // constructor is available we create one. static i::Handle
EnsureConstructor( ObjectTemplate* object_template) { i::Object* obj = Utils::OpenHandle(object_template)->constructor(); if (!obj ->IsUndefined()) { i::FunctionTemplateInfo* info = i::FunctionTemplateInfo::cast(obj); return i::Handle
(info, info->GetIsolate()); } Local
templ = FunctionTemplate::New(); i::Handle
constructor = Utils::OpenHandle(*templ); constructor->set_instance_template(*Utils::OpenHandle(object_template)); Utils::OpenHandle(object_template)->set_constructor(*constructor); return constructor; } static inline void AddPropertyToTemplate( i::Handle
info, i::Handle
obj) { i::Handle
list(info->property_accessors(), info->GetIsolate()); if (list->IsUndefined()) { list = NeanderArray().value(); info->set_property_accessors(*list); } NeanderArray array(list); array.add(obj); } static inline i::Handle
GetTemplateInfo( Template* template_obj) { return Utils::OpenHandle(template_obj); } // TODO(dcarney): remove this with ObjectTemplate::SetAccessor static inline i::Handle
GetTemplateInfo( ObjectTemplate* object_template) { EnsureConstructor(object_template); return Utils::OpenHandle(object_template); } template
static bool TemplateSetAccessor( Template* template_obj, v8::Local
name, Getter getter, Setter setter, Data data, AccessControl settings, PropertyAttribute attribute, v8::Local
signature) { i::Isolate* isolate = Utils::OpenHandle(template_obj)->GetIsolate(); ENTER_V8(isolate); i::HandleScope scope(isolate); i::Handle
obj = MakeAccessorInfo( name, getter, setter, data, settings, attribute, signature); if (obj.is_null()) return false; i::Handle
info = GetTemplateInfo(template_obj); AddPropertyToTemplate(info, obj); return true; } bool Template::SetDeclaredAccessor( Local
name, Local
descriptor, PropertyAttribute attribute, Local
signature, AccessControl settings) { void* null = NULL; return TemplateSetAccessor( this, name, descriptor, null, null, settings, attribute, signature); } void Template::SetNativeDataProperty(v8::Local
name, AccessorGetterCallback getter, AccessorSetterCallback setter, v8::Handle
data, PropertyAttribute attribute, v8::Local
signature, AccessControl settings) { TemplateSetAccessor( this, name, getter, setter, data, settings, attribute, signature); } void ObjectTemplate::SetAccessor(v8::Handle
name, AccessorGetterCallback getter, AccessorSetterCallback setter, v8::Handle
data, AccessControl settings, PropertyAttribute attribute, v8::Handle
signature) { TemplateSetAccessor( this, name, getter, setter, data, settings, attribute, signature); } void ObjectTemplate::SetNamedPropertyHandler( NamedPropertyGetterCallback getter, NamedPropertySetterCallback setter, NamedPropertyQueryCallback query, NamedPropertyDeleterCallback remover, NamedPropertyEnumeratorCallback enumerator, Handle
data) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); i::HandleScope scope(isolate); EnsureConstructor(this); i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast( Utils::OpenHandle(this)->constructor()); i::Handle
cons(constructor); i::Handle
struct_obj = isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); 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); if (data.IsEmpty()) { data = v8::Undefined(reinterpret_cast
(isolate)); } obj->set_data(*Utils::OpenHandle(*data)); cons->set_named_property_handler(*obj); } void ObjectTemplate::MarkAsUndetectable() { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); i::HandleScope scope(isolate); EnsureConstructor(this); i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor()); i::Handle
cons(constructor); cons->set_undetectable(true); } void ObjectTemplate::SetAccessCheckCallbacks( NamedSecurityCallback named_callback, IndexedSecurityCallback indexed_callback, Handle
data, bool turned_on_by_default) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); i::HandleScope scope(isolate); EnsureConstructor(this); i::Handle
struct_info = isolate->factory()->NewStruct(i::ACCESS_CHECK_INFO_TYPE); i::Handle
info = i::Handle
::cast(struct_info); SET_FIELD_WRAPPED(info, set_named_callback, named_callback); SET_FIELD_WRAPPED(info, set_indexed_callback, indexed_callback); if (data.IsEmpty()) { data = v8::Undefined(reinterpret_cast
(isolate)); } info->set_data(*Utils::OpenHandle(*data)); i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(Utils::OpenHandle(this)->constructor()); i::Handle
cons(constructor); cons->set_access_check_info(*info); cons->set_needs_access_check(turned_on_by_default); } void ObjectTemplate::SetIndexedPropertyHandler( IndexedPropertyGetterCallback getter, IndexedPropertySetterCallback setter, IndexedPropertyQueryCallback query, IndexedPropertyDeleterCallback remover, IndexedPropertyEnumeratorCallback enumerator, Handle
data) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); i::HandleScope scope(isolate); EnsureConstructor(this); i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast( Utils::OpenHandle(this)->constructor()); i::Handle
cons(constructor); i::Handle
struct_obj = isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); 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); if (data.IsEmpty()) { data = v8::Undefined(reinterpret_cast
(isolate)); } obj->set_data(*Utils::OpenHandle(*data)); cons->set_indexed_property_handler(*obj); } void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback, Handle
data) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); ENTER_V8(isolate); i::HandleScope scope(isolate); EnsureConstructor(this); i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast( Utils::OpenHandle(this)->constructor()); i::Handle
cons(constructor); i::Handle
struct_obj = isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE); i::Handle
obj = i::Handle
::cast(struct_obj); SET_FIELD_WRAPPED(obj, set_callback, callback); if (data.IsEmpty()) { data = v8::Undefined(reinterpret_cast
(isolate)); } obj->set_data(*Utils::OpenHandle(*data)); cons->set_instance_call_handler(*obj); } int ObjectTemplate::InternalFieldCount() { return i::Smi::cast(Utils::OpenHandle(this)->internal_field_count())->value(); } void ObjectTemplate::SetInternalFieldCount(int value) { i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate(); if (!ApiCheck(i::Smi::IsValid(value), "v8::ObjectTemplate::SetInternalFieldCount()", "Invalid internal field count")) { return; } ENTER_V8(isolate); if (value > 0) { // The internal field count is set by the constructor function's // construct code, so we ensure that there is a constructor // function to do the setting. EnsureConstructor(this); } Utils::OpenHandle(this)->set_internal_field_count(i::Smi::FromInt(value)); } // --- S c r i p t D a t a --- ScriptData* ScriptData::PreCompile(v8::Isolate* isolate, const char* input, int length) { i::Utf8ToUtf16CharacterStream stream( reinterpret_cast
(input), length); return i::PreParserApi::PreParse( reinterpret_cast
(isolate), &stream); } ScriptData* ScriptData::PreCompile(v8::Handle
source) { i::Handle
str = Utils::OpenHandle(*source); i::Isolate* isolate = str->GetIsolate(); if (str->IsExternalTwoByteString()) { i::ExternalTwoByteStringUtf16CharacterStream stream( i::Handle
::cast(str), 0, str->length()); return i::PreParserApi::PreParse(isolate, &stream); } else { i::GenericStringUtf16CharacterStream stream(str, 0, str->length()); return i::PreParserApi::PreParse(isolate, &stream); } } ScriptData* ScriptData::New(const char* data, int length) { // Return an empty ScriptData if the length is obviously invalid. if (length % sizeof(unsigned) != 0) { return new i::ScriptDataImpl(); } // Copy the data to ensure it is properly aligned. int deserialized_data_length = length / sizeof(unsigned); // If aligned, don't create a copy of the data. if (reinterpret_cast
(data) % sizeof(unsigned) == 0) { return new i::ScriptDataImpl(data, length); } // Copy the data to align it. unsigned* deserialized_data = i::NewArray
(deserialized_data_length); i::CopyBytes(reinterpret_cast
(deserialized_data), data, static_cast
(length)); return new i::ScriptDataImpl( i::Vector
(deserialized_data, deserialized_data_length)); } // --- S c r i p t --- Local
登录后可以享受更多权益
您还没有登录,登录后您可以: