// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // Defined when linking against shared lib on Windows. #if defined(USING_V8_SHARED) && !defined(V8_SHARED) #define V8_SHARED #endif #include #include #include #include #ifdef V8_SHARED #include #endif // V8_SHARED #ifndef V8_SHARED #include #endif // !V8_SHARED #ifdef V8_SHARED #include "include/v8-testing.h" #endif // V8_SHARED #if !defined(V8_SHARED) && defined(ENABLE_GDB_JIT_INTERFACE) #include "src/gdb-jit.h" #endif #ifdef ENABLE_VTUNE_JIT_INTERFACE #include "src/third_party/vtune/v8-vtune.h" #endif #include "src/d8.h" #include "include/libplatform/libplatform.h" #ifndef V8_SHARED #include "src/api.h" #include "src/base/cpu.h" #include "src/base/logging.h" #include "src/base/platform/platform.h" #include "src/base/sys-info.h" #include "src/basic-block-profiler.h" #include "src/d8-debug.h" #include "src/debug.h" #include "src/natives.h" #include "src/v8.h" #endif // !V8_SHARED #ifdef V8_USE_EXTERNAL_STARTUP_DATA #include "src/startup-data-util.h" #endif // V8_USE_EXTERNAL_STARTUP_DATA #if !defined(_WIN32) && !defined(_WIN64) #include // NOLINT #else #include // NOLINT #if defined(_MSC_VER) #include // NOLINT #endif // defined(_MSC_VER) #endif // !defined(_WIN32) && !defined(_WIN64) #ifndef DCHECK #define DCHECK(condition) assert(condition) #endif namespace v8 { static Handle Throw(Isolate* isolate, const char* message) { return isolate->ThrowException(String::NewFromUtf8(isolate, message)); } class PerIsolateData { public: explicit PerIsolateData(Isolate* isolate) : isolate_(isolate), realms_(NULL) { HandleScope scope(isolate); isolate->SetData(0, this); } ~PerIsolateData() { isolate_->SetData(0, NULL); // Not really needed, just to be sure... } inline static PerIsolateData* Get(Isolate* isolate) { return reinterpret_cast(isolate->GetData(0)); } class RealmScope { public: explicit RealmScope(PerIsolateData* data); ~RealmScope(); private: PerIsolateData* data_; }; private: friend class Shell; friend class RealmScope; Isolate* isolate_; int realm_count_; int realm_current_; int realm_switch_; Persistent* realms_; Persistent realm_shared_; int RealmIndexOrThrow(const v8::FunctionCallbackInfo& args, int arg_offset); int RealmFind(Handle context); }; LineEditor *LineEditor::current_ = NULL; LineEditor::LineEditor(Type type, const char* name) : type_(type), name_(name) { if (current_ == NULL || current_->type_ < type) current_ = this; } class DumbLineEditor: public LineEditor { public: explicit DumbLineEditor(Isolate* isolate) : LineEditor(LineEditor::DUMB, "dumb"), isolate_(isolate) { } virtual Handle Prompt(const char* prompt); private: Isolate* isolate_; }; Handle DumbLineEditor::Prompt(const char* prompt) { printf("%s", prompt); #if defined(__native_client__) // Native Client libc is used to being embedded in Chrome and // has trouble recognizing when to flush. fflush(stdout); #endif return Shell::ReadFromStdin(isolate_); } #ifndef V8_SHARED CounterMap* Shell::counter_map_; base::OS::MemoryMappedFile* Shell::counters_file_ = NULL; CounterCollection Shell::local_counters_; CounterCollection* Shell::counters_ = &local_counters_; base::Mutex Shell::context_mutex_; const base::TimeTicks Shell::kInitialTicks = base::TimeTicks::HighResolutionNow(); Persistent Shell::utility_context_; #endif // !V8_SHARED Persistent Shell::evaluation_context_; ShellOptions Shell::options; const char* Shell::kPrompt = "d8> "; #ifndef V8_SHARED const int MB = 1024 * 1024; bool CounterMap::Match(void* key1, void* key2) { const char* name1 = reinterpret_cast(key1); const char* name2 = reinterpret_cast(key2); return strcmp(name1, name2) == 0; } #endif // !V8_SHARED // Converts a V8 value to a C string. const char* Shell::ToCString(const v8::String::Utf8Value& value) { return *value ? *value : ""; } ScriptCompiler::CachedData* CompileForCachedData( Local source, Local name, ScriptCompiler::CompileOptions compile_options) { int source_length = source->Length(); uint16_t* source_buffer = new uint16_t[source_length]; source->Write(source_buffer, 0, source_length); int name_length = 0; uint16_t* name_buffer = NULL; if (name->IsString()) { Local name_string = Local::Cast(name); name_length = name_string->Length(); name_buffer = new uint16_t[name_length]; name_string->Write(name_buffer, 0, name_length); } Isolate* temp_isolate = Isolate::New(); ScriptCompiler::CachedData* result = NULL; { Isolate::Scope isolate_scope(temp_isolate); HandleScope handle_scope(temp_isolate); Context::Scope context_scope(Context::New(temp_isolate)); Local source_copy = v8::String::NewFromTwoByte( temp_isolate, source_buffer, v8::String::kNormalString, source_length); Local name_copy; if (name_buffer) { name_copy = v8::String::NewFromTwoByte( temp_isolate, name_buffer, v8::String::kNormalString, name_length); } else { name_copy = v8::Undefined(temp_isolate); } ScriptCompiler::Source script_source(source_copy, ScriptOrigin(name_copy)); ScriptCompiler::CompileUnbound(temp_isolate, &script_source, compile_options); if (script_source.GetCachedData()) { int length = script_source.GetCachedData()->length; uint8_t* cache = new uint8_t[length]; memcpy(cache, script_source.GetCachedData()->data, length); result = new ScriptCompiler::CachedData( cache, length, ScriptCompiler::CachedData::BufferOwned); } } temp_isolate->Dispose(); delete[] source_buffer; delete[] name_buffer; return result; } // Compile a string within the current v8 context. Local