Commit e8bf3142 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Introduces a light version of D8 that links against shared library.

Review URL: http://codereview.chromium.org/7351017

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8657 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d4779286
...@@ -773,6 +773,13 @@ PREPARSER_FLAGS = { ...@@ -773,6 +773,13 @@ PREPARSER_FLAGS = {
D8_FLAGS = { D8_FLAGS = {
'all': {
'library:shared': {
'CPPDEFINES': ['V8_SHARED'],
'LIBS': ['v8'],
'LIBPATH': ['.']
},
},
'gcc': { 'gcc': {
'all': { 'all': {
'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'], 'CCFLAGS': ['$DIALECTFLAGS', '$WARNINGFLAGS'],
...@@ -1370,7 +1377,11 @@ def BuildSpecific(env, mode, env_overrides, tools): ...@@ -1370,7 +1377,11 @@ def BuildSpecific(env, mode, env_overrides, tools):
d8_env = Environment(tools=tools) d8_env = Environment(tools=tools)
d8_env.Replace(**context.flags['d8']) d8_env.Replace(**context.flags['d8'])
context.ApplyEnvOverrides(d8_env) context.ApplyEnvOverrides(d8_env)
if context.options['library'] == 'static':
shell = d8_env.Program('d8' + suffix, object_files + shell_files) shell = d8_env.Program('d8' + suffix, object_files + shell_files)
else:
shell = d8_env.Program('d8' + suffix, shell_files)
d8_env.Depends(shell, library)
context.d8_targets.append(shell) context.d8_targets.append(shell)
for sample in context.samples: for sample in context.samples:
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
'type': 'none', 'type': 'none',
'dependencies': [ 'dependencies': [
'../samples/samples.gyp:*', '../samples/samples.gyp:*',
'../src/d8.gyp:*', '../src/d8.gyp:d8',
], ],
'conditions': [ 'conditions': [
[ 'component!="shared_library"', { [ 'component!="shared_library"', {
......
...@@ -243,7 +243,14 @@ PREPARSER_SOURCES = { ...@@ -243,7 +243,14 @@ PREPARSER_SOURCES = {
} }
D8_FILES = { D8_LIGHT_FILES = {
'all': [
'd8.cc'
]
}
D8_FULL_FILES = {
'all': [ 'all': [
'd8.cc', 'd8-debug.cc' 'd8.cc', 'd8-debug.cc'
], ],
...@@ -323,11 +330,15 @@ def ConfigureObjectFiles(): ...@@ -323,11 +330,15 @@ def ConfigureObjectFiles():
# Build the standard platform-independent source files. # Build the standard platform-independent source files.
source_files = context.GetRelevantSources(SOURCES) source_files = context.GetRelevantSources(SOURCES)
d8_files = context.GetRelevantSources(D8_FILES)
d8_js = env.JS2C('d8-js.cc', 'd8.js', **{'TYPE': 'D8', 'COMPRESSION': 'off'}) d8_js = env.JS2C('d8-js.cc', 'd8.js', **{'TYPE': 'D8', 'COMPRESSION': 'off'})
d8_js_obj = context.ConfigureObject(env, d8_js, CPPPATH=['.']) d8_js_obj = context.ConfigureObject(env, d8_js, CPPPATH=['.'])
d8_objs = [context.ConfigureObject(env, [d8_files]), d8_js_obj] if context.options['library'] == 'shared':
d8_files = context.GetRelevantSources(D8_LIGHT_FILES)
d8_objs = []
else:
d8_files = context.GetRelevantSources(D8_FULL_FILES)
d8_objs = [d8_js_obj]
d8_objs.append(context.ConfigureObject(env, [d8_files]))
# Combine the JavaScript library files into a single C++ file and # Combine the JavaScript library files into a single C++ file and
# compile it. # compile it.
......
...@@ -26,33 +26,49 @@ ...@@ -26,33 +26,49 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef V8_SHARED
#define USING_V8_SHARED
#endif
#ifdef COMPRESS_STARTUP_DATA_BZ2 #ifdef COMPRESS_STARTUP_DATA_BZ2
#include <bzlib.h> #include <bzlib.h>
#endif #endif
#include <errno.h> #include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include "v8.h" #ifdef USING_V8_SHARED
#include <assert.h>
#include "../include/v8-testing.h"
#endif // USING_V8_SHARED
#include "d8.h" #include "d8.h"
#ifndef USING_V8_SHARED
#include "api.h"
#include "checks.h"
#include "d8-debug.h" #include "d8-debug.h"
#include "debug.h" #include "debug.h"
#include "api.h"
#include "natives.h" #include "natives.h"
#include "platform.h" #include "platform.h"
#include "v8.h"
#endif // USING_V8_SHARED
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h> // NOLINT #include <unistd.h> // NOLINT
#endif #endif
namespace v8 { #ifdef USING_V8_SHARED
#define ASSERT(condition) assert(condition)
#endif // USING_V8_SHARED
namespace v8 {
const char* Shell::kHistoryFileName = ".d8_history";
const char* Shell::kPrompt = "d8> ";
#ifndef USING_V8_SHARED
LineEditor *LineEditor::first_ = NULL; LineEditor *LineEditor::first_ = NULL;
const char* Shell::kHistoryFileName = ".d8_history";
LineEditor::LineEditor(Type type, const char* name) LineEditor::LineEditor(Type type, const char* name)
...@@ -98,17 +114,22 @@ CounterMap* Shell::counter_map_; ...@@ -98,17 +114,22 @@ CounterMap* Shell::counter_map_;
i::OS::MemoryMappedFile* Shell::counters_file_ = NULL; i::OS::MemoryMappedFile* Shell::counters_file_ = NULL;
CounterCollection Shell::local_counters_; CounterCollection Shell::local_counters_;
CounterCollection* Shell::counters_ = &local_counters_; CounterCollection* Shell::counters_ = &local_counters_;
i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
Persistent<Context> Shell::utility_context_; Persistent<Context> Shell::utility_context_;
#endif // USING_V8_SHARED
Persistent<Context> Shell::evaluation_context_; Persistent<Context> Shell::evaluation_context_;
i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
ShellOptions Shell::options; ShellOptions Shell::options;
const char* Shell::kPrompt = "d8> ";
#ifndef USING_V8_SHARED
bool CounterMap::Match(void* key1, void* key2) { bool CounterMap::Match(void* key1, void* key2) {
const char* name1 = reinterpret_cast<const char*>(key1); const char* name1 = reinterpret_cast<const char*>(key1);
const char* name2 = reinterpret_cast<const char*>(key2); const char* name2 = reinterpret_cast<const char*>(key2);
return strcmp(name1, name2) == 0; return strcmp(name1, name2) == 0;
} }
#endif // USING_V8_SHARED
// Converts a V8 value to a C string. // Converts a V8 value to a C string.
...@@ -122,17 +143,22 @@ bool Shell::ExecuteString(Handle<String> source, ...@@ -122,17 +143,22 @@ bool Shell::ExecuteString(Handle<String> source,
Handle<Value> name, Handle<Value> name,
bool print_result, bool print_result,
bool report_exceptions) { bool report_exceptions) {
#ifndef USING_V8_SHARED
bool FLAG_debugger = i::FLAG_debugger;
#else
bool FLAG_debugger = false;
#endif // USING_V8_SHARED
HandleScope handle_scope; HandleScope handle_scope;
TryCatch try_catch; TryCatch try_catch;
options.script_executed = true; options.script_executed = true;
if (i::FLAG_debugger) { if (FLAG_debugger) {
// When debugging make exceptions appear to be uncaught. // When debugging make exceptions appear to be uncaught.
try_catch.SetVerbose(true); try_catch.SetVerbose(true);
} }
Handle<Script> script = Script::Compile(source, name); Handle<Script> script = Script::Compile(source, name);
if (script.IsEmpty()) { if (script.IsEmpty()) {
// Print errors that happened during compilation. // Print errors that happened during compilation.
if (report_exceptions && !i::FLAG_debugger) if (report_exceptions && !FLAG_debugger)
ReportException(&try_catch); ReportException(&try_catch);
return false; return false;
} else { } else {
...@@ -140,7 +166,7 @@ bool Shell::ExecuteString(Handle<String> source, ...@@ -140,7 +166,7 @@ bool Shell::ExecuteString(Handle<String> source,
if (result.IsEmpty()) { if (result.IsEmpty()) {
ASSERT(try_catch.HasCaught()); ASSERT(try_catch.HasCaught());
// Print errors that happened during execution. // Print errors that happened during execution.
if (report_exceptions && !i::FLAG_debugger) if (report_exceptions && !FLAG_debugger)
ReportException(&try_catch); ReportException(&try_catch);
return false; return false;
} else { } else {
...@@ -196,15 +222,20 @@ Handle<Value> Shell::Read(const Arguments& args) { ...@@ -196,15 +222,20 @@ Handle<Value> Shell::Read(const Arguments& args) {
Handle<Value> Shell::ReadLine(const Arguments& args) { Handle<Value> Shell::ReadLine(const Arguments& args) {
i::SmartPointer<char> line(i::ReadLine("")); static const int kBufferSize = 256;
if (*line == NULL) { char buffer[kBufferSize];
return Null(); Handle<String> accumulator = String::New("");
} bool linebreak;
size_t len = strlen(*line); int length;
if (len > 0 && line[len - 1] == '\n') { do { // Repeat if the line ends with an escape '\'.
--len; // fgets got an error. Just give up.
} if (fgets(buffer, kBufferSize, stdin) == NULL) return Null();
return String::New(*line, len); length = strlen(buffer);
linebreak = (length > 1 && buffer[length-2] == '\\');
if (linebreak) buffer[length-2] = '\n';
accumulator = String::Concat(accumulator, String::New(buffer, length-1));
} while (linebreak);
return accumulator;
} }
...@@ -236,6 +267,10 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, ...@@ -236,6 +267,10 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
return ThrowException( return ThrowException(
String::New("Array constructor needs one parameter.")); String::New("Array constructor needs one parameter."));
} }
static const int kMaxLength = 0x3fffffff;
#ifndef USING_V8_SHARED
ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
#endif // USING_V8_SHARED
size_t length = 0; size_t length = 0;
if (args[0]->IsUint32()) { if (args[0]->IsUint32()) {
length = args[0]->Uint32Value(); length = args[0]->Uint32Value();
...@@ -244,7 +279,7 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, ...@@ -244,7 +279,7 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
if (raw_length < 0) { if (raw_length < 0) {
return ThrowException(String::New("Array length must not be negative.")); return ThrowException(String::New("Array length must not be negative."));
} }
if (raw_length > i::ExternalArray::kMaxLength) { if (raw_length > kMaxLength) {
return ThrowException( return ThrowException(
String::New("Array length exceeds maximum length.")); String::New("Array length exceeds maximum length."));
} }
...@@ -252,7 +287,7 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, ...@@ -252,7 +287,7 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
} else { } else {
return ThrowException(String::New("Array length must be a number.")); return ThrowException(String::New("Array length must be a number."));
} }
if (length > static_cast<size_t>(i::ExternalArray::kMaxLength)) { if (length > static_cast<size_t>(kMaxLength)) {
return ThrowException(String::New("Array length exceeds maximum length.")); return ThrowException(String::New("Array length exceeds maximum length."));
} }
void* data = calloc(length, element_size); void* data = calloc(length, element_size);
...@@ -332,7 +367,9 @@ Handle<Value> Shell::Yield(const Arguments& args) { ...@@ -332,7 +367,9 @@ Handle<Value> Shell::Yield(const Arguments& args) {
Handle<Value> Shell::Quit(const Arguments& args) { Handle<Value> Shell::Quit(const Arguments& args) {
int exit_code = args[0]->Int32Value(); int exit_code = args[0]->Int32Value();
#ifndef USING_V8_SHARED
OnExit(); OnExit();
#endif // USING_V8_SHARED
exit(exit_code); exit(exit_code);
return Undefined(); return Undefined();
} }
...@@ -381,6 +418,7 @@ void Shell::ReportException(v8::TryCatch* try_catch) { ...@@ -381,6 +418,7 @@ void Shell::ReportException(v8::TryCatch* try_catch) {
} }
#ifndef USING_V8_SHARED
Handle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) { Handle<Array> Shell::GetCompletions(Handle<String> text, Handle<String> full) {
HandleScope handle_scope; HandleScope handle_scope;
Context::Scope context_scope(utility_context_); Context::Scope context_scope(utility_context_);
...@@ -414,9 +452,11 @@ Handle<Value> Shell::DebugCommandToJSONRequest(Handle<String> command) { ...@@ -414,9 +452,11 @@ Handle<Value> Shell::DebugCommandToJSONRequest(Handle<String> command) {
Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv); Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
return val; return val;
} }
#endif #endif // ENABLE_DEBUGGER_SUPPORT
#endif // USING_V8_SHARED
#ifndef USING_V8_SHARED
int32_t* Counter::Bind(const char* name, bool is_histogram) { int32_t* Counter::Bind(const char* name, bool is_histogram) {
int i; int i;
for (i = 0; i < kMaxNameSize - 1 && name[i]; i++) for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
...@@ -448,8 +488,8 @@ Counter* CounterCollection::GetNextCounter() { ...@@ -448,8 +488,8 @@ Counter* CounterCollection::GetNextCounter() {
void Shell::MapCounters(const char* name) { void Shell::MapCounters(const char* name) {
counters_file_ = i::OS::MemoryMappedFile::create(name, counters_file_ = i::OS::MemoryMappedFile::create(
sizeof(CounterCollection), &local_counters_); name, sizeof(CounterCollection), &local_counters_);
void* memory = (counters_file_ == NULL) ? void* memory = (counters_file_ == NULL) ?
NULL : counters_file_->memory(); NULL : counters_file_->memory();
if (memory == NULL) { if (memory == NULL) {
...@@ -514,6 +554,7 @@ void Shell::AddHistogramSample(void* histogram, int sample) { ...@@ -514,6 +554,7 @@ void Shell::AddHistogramSample(void* histogram, int sample) {
counter->AddSample(sample); counter->AddSample(sample);
} }
void Shell::InstallUtilityScript() { void Shell::InstallUtilityScript() {
Locker lock; Locker lock;
HandleScope scope; HandleScope scope;
...@@ -532,7 +573,7 @@ void Shell::InstallUtilityScript() { ...@@ -532,7 +573,7 @@ void Shell::InstallUtilityScript() {
utility_context_->Global()->Set(String::New("$debug"), utility_context_->Global()->Set(String::New("$debug"),
Utils::ToLocal(js_debug)); Utils::ToLocal(js_debug));
debug->debug_context()->set_security_token(HEAP->undefined_value()); debug->debug_context()->set_security_token(HEAP->undefined_value());
#endif #endif // ENABLE_DEBUGGER_SUPPORT
// Run the d8 shell utility script in the utility context // Run the d8 shell utility script in the utility context
int source_index = i::NativesCollection<i::D8>::GetIndex("d8"); int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
...@@ -561,8 +602,9 @@ void Shell::InstallUtilityScript() { ...@@ -561,8 +602,9 @@ void Shell::InstallUtilityScript() {
if (i::FLAG_debugger && !i::FLAG_debugger_agent) { if (i::FLAG_debugger && !i::FLAG_debugger_agent) {
v8::Debug::SetDebugEventListener(HandleDebugEvent); v8::Debug::SetDebugEventListener(HandleDebugEvent);
} }
#endif #endif // ENABLE_DEBUGGER_SUPPORT
} }
#endif // USING_V8_SHARED
#ifdef COMPRESS_STARTUP_DATA_BZ2 #ifdef COMPRESS_STARTUP_DATA_BZ2
...@@ -629,9 +671,11 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() { ...@@ -629,9 +671,11 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
global_template->Set(String::New("lol_is_enabled"), Boolean::New(false)); global_template->Set(String::New("lol_is_enabled"), Boolean::New(false));
#endif #endif
#ifndef USING_V8_SHARED
Handle<ObjectTemplate> os_templ = ObjectTemplate::New(); Handle<ObjectTemplate> os_templ = ObjectTemplate::New();
AddOSMethods(os_templ); AddOSMethods(os_templ);
global_template->Set(String::New("os"), os_templ); global_template->Set(String::New("os"), os_templ);
#endif // USING_V8_SHARED
return global_template; return global_template;
} }
...@@ -647,6 +691,7 @@ void Shell::Initialize() { ...@@ -647,6 +691,7 @@ void Shell::Initialize() {
} }
#endif #endif
#ifndef USING_V8_SHARED
Shell::counter_map_ = new CounterMap(); Shell::counter_map_ = new CounterMap();
// Set up counters // Set up counters
if (i::StrLength(i::FLAG_map_counters) != 0) if (i::StrLength(i::FLAG_map_counters) != 0)
...@@ -656,9 +701,10 @@ void Shell::Initialize() { ...@@ -656,9 +701,10 @@ void Shell::Initialize() {
V8::SetCreateHistogramFunction(CreateHistogram); V8::SetCreateHistogramFunction(CreateHistogram);
V8::SetAddHistogramSampleFunction(AddHistogramSample); V8::SetAddHistogramSampleFunction(AddHistogramSample);
} }
#endif // USING_V8_SHARED
if (options.test_shell) return; if (options.test_shell) return;
#ifndef USING_V8_SHARED
Locker lock; Locker lock;
HandleScope scope; HandleScope scope;
Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
...@@ -669,18 +715,22 @@ void Shell::Initialize() { ...@@ -669,18 +715,22 @@ void Shell::Initialize() {
if (i::FLAG_debugger_agent) { if (i::FLAG_debugger_agent) {
v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true); v8::Debug::EnableAgent("d8 shell", i::FLAG_debugger_port, true);
} }
#endif #endif // ENABLE_DEBUGGER_SUPPORT
#endif // USING_V8_SHARED
} }
Persistent<Context> Shell::CreateEvaluationContext() { Persistent<Context> Shell::CreateEvaluationContext() {
#ifndef USING_V8_SHARED
// This needs to be a critical section since this is not thread-safe // This needs to be a critical section since this is not thread-safe
i::ScopedLock lock(context_mutex_); i::ScopedLock lock(context_mutex_);
#endif // USING_V8_SHARED
// Initialize the global objects // Initialize the global objects
Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); Handle<ObjectTemplate> global_template = CreateGlobalTemplate();
Persistent<Context> context = Context::New(NULL, global_template); Persistent<Context> context = Context::New(NULL, global_template);
Context::Scope scope(context); Context::Scope scope(context);
#ifndef USING_V8_SHARED
i::JSArguments js_args = i::FLAG_js_arguments; i::JSArguments js_args = i::FLAG_js_arguments;
i::Handle<i::FixedArray> arguments_array = i::Handle<i::FixedArray> arguments_array =
FACTORY->NewFixedArray(js_args.argc()); FACTORY->NewFixedArray(js_args.argc());
...@@ -693,10 +743,12 @@ Persistent<Context> Shell::CreateEvaluationContext() { ...@@ -693,10 +743,12 @@ Persistent<Context> Shell::CreateEvaluationContext() {
FACTORY->NewJSArrayWithElements(arguments_array); FACTORY->NewJSArrayWithElements(arguments_array);
context->Global()->Set(String::New("arguments"), context->Global()->Set(String::New("arguments"),
Utils::ToLocal(arguments_jsarray)); Utils::ToLocal(arguments_jsarray));
#endif // USING_V8_SHARED
return context; return context;
} }
#ifndef USING_V8_SHARED
void Shell::OnExit() { void Shell::OnExit() {
if (i::FLAG_dump_counters) { if (i::FLAG_dump_counters) {
printf("+----------------------------------------+-------------+\n"); printf("+----------------------------------------+-------------+\n");
...@@ -716,12 +768,18 @@ void Shell::OnExit() { ...@@ -716,12 +768,18 @@ void Shell::OnExit() {
if (counters_file_ != NULL) if (counters_file_ != NULL)
delete counters_file_; delete counters_file_;
} }
#endif // USING_V8_SHARED
static char* ReadChars(const char* name, int* size_out) { static char* ReadChars(const char* name, int* size_out) {
// Release the V8 lock while reading files. // Release the V8 lock while reading files.
v8::Unlocker unlocker(Isolate::GetCurrent()); v8::Unlocker unlocker(Isolate::GetCurrent());
#ifndef USING_V8_SHARED
FILE* file = i::OS::FOpen(name, "rb"); FILE* file = i::OS::FOpen(name, "rb");
#else
// TODO(yangguo@chromium.org): reading from a directory hangs!
FILE* file = fopen(name, "rb");
#endif // USING_V8_SHARED
if (file == NULL) return NULL; if (file == NULL) return NULL;
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
...@@ -740,6 +798,7 @@ static char* ReadChars(const char* name, int* size_out) { ...@@ -740,6 +798,7 @@ static char* ReadChars(const char* name, int* size_out) {
} }
#ifndef USING_V8_SHARED
static char* ReadToken(char* data, char token) { static char* ReadToken(char* data, char token) {
char* next = i::OS::StrChr(data, token); char* next = i::OS::StrChr(data, token);
if (next != NULL) { if (next != NULL) {
...@@ -759,6 +818,7 @@ static char* ReadLine(char* data) { ...@@ -759,6 +818,7 @@ static char* ReadLine(char* data) {
static char* ReadWord(char* data) { static char* ReadWord(char* data) {
return ReadToken(data, ' '); return ReadToken(data, ' ');
} }
#endif // USING_V8_SHARED
// Reads a file into a v8 string. // Reads a file into a v8 string.
...@@ -773,29 +833,39 @@ Handle<String> Shell::ReadFile(const char* name) { ...@@ -773,29 +833,39 @@ Handle<String> Shell::ReadFile(const char* name) {
void Shell::RunShell() { void Shell::RunShell() {
Locker locker;
Context::Scope context_scope(evaluation_context_);
HandleScope handle_scope;
Handle<String> name = String::New("(d8)");
#ifndef USING_V8_SHARED
LineEditor* editor = LineEditor::Get(); LineEditor* editor = LineEditor::Get();
printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name()); printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name());
if (i::FLAG_debugger) { if (i::FLAG_debugger) {
printf("JavaScript debugger enabled\n"); printf("JavaScript debugger enabled\n");
} }
editor->Open(); editor->Open();
while (true) { while (true) {
Locker locker;
HandleScope handle_scope;
Context::Scope context_scope(evaluation_context_);
i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt); i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt);
if (input.is_empty()) if (input.is_empty()) break;
break;
editor->AddHistory(*input); editor->AddHistory(*input);
Handle<String> name = String::New("(d8)");
ExecuteString(String::New(*input), name, true, true); ExecuteString(String::New(*input), name, true, true);
} }
editor->Close(); editor->Close();
#else
printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion());
static const int kBufferSize = 256;
while (true) {
char buffer[kBufferSize];
printf("%s", Shell::kPrompt);
if (fgets(buffer, kBufferSize, stdin) == NULL) break;
ExecuteString(String::New(buffer), name, true, true);
}
#endif // USING_V8_SHARED
printf("\n"); printf("\n");
} }
#ifndef USING_V8_SHARED
class ShellThread : public i::Thread { class ShellThread : public i::Thread {
public: public:
ShellThread(int no, i::Vector<const char> files) ShellThread(int no, i::Vector<const char> files)
...@@ -848,6 +918,7 @@ void ShellThread::Run() { ...@@ -848,6 +918,7 @@ void ShellThread::Run() {
ptr = next_line; ptr = next_line;
} }
} }
#endif // USING_V8_SHARED
void SourceGroup::ExitShell(int exit_code) { void SourceGroup::ExitShell(int exit_code) {
...@@ -894,7 +965,12 @@ void SourceGroup::Execute() { ...@@ -894,7 +965,12 @@ void SourceGroup::Execute() {
Handle<String> SourceGroup::ReadFile(const char* name) { Handle<String> SourceGroup::ReadFile(const char* name) {
#ifndef USING_V8_SHARED
FILE* file = i::OS::FOpen(name, "rb");
#else
// TODO(yangguo@chromium.org): reading from a directory hangs!
FILE* file = fopen(name, "rb"); FILE* file = fopen(name, "rb");
#endif // USING_V8_SHARED
if (file == NULL) return Handle<String>(); if (file == NULL) return Handle<String>();
fseek(file, 0, SEEK_END); fseek(file, 0, SEEK_END);
...@@ -914,6 +990,7 @@ Handle<String> SourceGroup::ReadFile(const char* name) { ...@@ -914,6 +990,7 @@ Handle<String> SourceGroup::ReadFile(const char* name) {
} }
#ifndef USING_V8_SHARED
i::Thread::Options SourceGroup::GetThreadOptions() { i::Thread::Options SourceGroup::GetThreadOptions() {
i::Thread::Options options; i::Thread::Options options;
options.name = "IsolateThread"; options.name = "IsolateThread";
...@@ -965,6 +1042,7 @@ void SourceGroup::WaitForThread() { ...@@ -965,6 +1042,7 @@ void SourceGroup::WaitForThread() {
done_semaphore_->Wait(); done_semaphore_->Wait();
} }
} }
#endif // USING_V8_SHARED
bool Shell::SetOptions(int argc, char* argv[]) { bool Shell::SetOptions(int argc, char* argv[]) {
...@@ -986,12 +1064,26 @@ bool Shell::SetOptions(int argc, char* argv[]) { ...@@ -986,12 +1064,26 @@ bool Shell::SetOptions(int argc, char* argv[]) {
options.test_shell = true; options.test_shell = true;
argv[i] = NULL; argv[i] = NULL;
} else if (strcmp(argv[i], "--preemption") == 0) { } else if (strcmp(argv[i], "--preemption") == 0) {
#ifdef USING_V8_SHARED
printf("D8 with shared library does not support multi-threading\n");
return false;
#else
options.use_preemption = true; options.use_preemption = true;
argv[i] = NULL; argv[i] = NULL;
#endif // USING_V8_SHARED
} else if (strcmp(argv[i], "--no-preemption") == 0) { } else if (strcmp(argv[i], "--no-preemption") == 0) {
#ifdef USING_V8_SHARED
printf("D8 with shared library does not support multi-threading\n");
return false;
#else
options.use_preemption = false; options.use_preemption = false;
argv[i] = NULL; argv[i] = NULL;
#endif // USING_V8_SHARED
} else if (strcmp(argv[i], "--preemption-interval") == 0) { } else if (strcmp(argv[i], "--preemption-interval") == 0) {
#ifdef USING_V8_SHARED
printf("D8 with shared library does not support multi-threading\n");
return false;
#else
if (++i < argc) { if (++i < argc) {
argv[i-1] = NULL; argv[i-1] = NULL;
char* end = NULL; char* end = NULL;
...@@ -1007,15 +1099,33 @@ bool Shell::SetOptions(int argc, char* argv[]) { ...@@ -1007,15 +1099,33 @@ bool Shell::SetOptions(int argc, char* argv[]) {
printf("Missing value for --preemption-interval\n"); printf("Missing value for --preemption-interval\n");
return false; return false;
} }
#endif // USING_V8_SHARED
} else if (strcmp(argv[i], "-f") == 0) { } else if (strcmp(argv[i], "-f") == 0) {
// Ignore any -f flags for compatibility with other stand-alone // Ignore any -f flags for compatibility with other stand-alone
// JavaScript engines. // JavaScript engines.
continue; continue;
} else if (strcmp(argv[i], "--isolate") == 0) { } else if (strcmp(argv[i], "--isolate") == 0) {
#ifdef USING_V8_SHARED
printf("D8 with shared library does not support multi-threading\n");
return false;
#endif // USING_V8_SHARED
options.num_isolates++; options.num_isolates++;
} }
#ifdef USING_V8_SHARED
else if (strcmp(argv[i], "--dump-counters") == 0) {
printf("D8 with shared library does not include counters\n");
return false;
} else if (strcmp(argv[i], "-p") == 0) {
printf("D8 with shared library does not support multi-threading\n");
return false;
} else if (strcmp(argv[i], "--debugger") == 0) {
printf("Javascript debugger not included\n");
return false;
}
#endif // USING_V8_SHARED
} }
#ifndef USING_V8_SHARED
// Run parallel threads if we are not using --isolate // Run parallel threads if we are not using --isolate
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (argv[i] == NULL) continue; if (argv[i] == NULL) continue;
...@@ -1038,6 +1148,7 @@ bool Shell::SetOptions(int argc, char* argv[]) { ...@@ -1038,6 +1148,7 @@ bool Shell::SetOptions(int argc, char* argv[]) {
options.parallel_files->Add(i::Vector<const char>(files, size)); options.parallel_files->Add(i::Vector<const char>(files, size));
} }
} }
#endif // USING_V8_SHARED
v8::V8::SetFlagsFromCommandLine(&argc, argv, true); v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
...@@ -1062,9 +1173,8 @@ bool Shell::SetOptions(int argc, char* argv[]) { ...@@ -1062,9 +1173,8 @@ bool Shell::SetOptions(int argc, char* argv[]) {
int Shell::RunMain(int argc, char* argv[]) { int Shell::RunMain(int argc, char* argv[]) {
#ifndef USING_V8_SHARED
i::List<i::Thread*> threads(1); i::List<i::Thread*> threads(1);
{
if (options.parallel_files != NULL) if (options.parallel_files != NULL)
for (int i = 0; i < options.parallel_files->length(); i++) { for (int i = 0; i < options.parallel_files->length(); i++) {
i::Vector<const char> files = options.parallel_files->at(i); i::Vector<const char> files = options.parallel_files->at(i);
...@@ -1076,7 +1186,8 @@ int Shell::RunMain(int argc, char* argv[]) { ...@@ -1076,7 +1186,8 @@ int Shell::RunMain(int argc, char* argv[]) {
for (int i = 1; i < options.num_isolates; ++i) { for (int i = 1; i < options.num_isolates; ++i) {
options.isolate_sources[i].StartExecuteInThread(); options.isolate_sources[i].StartExecuteInThread();
} }
#endif // USING_V8_SHARED
{ // NOLINT
Locker lock; Locker lock;
HandleScope scope; HandleScope scope;
Persistent<Context> context = CreateEvaluationContext(); Persistent<Context> context = CreateEvaluationContext();
...@@ -1090,14 +1201,18 @@ int Shell::RunMain(int argc, char* argv[]) { ...@@ -1090,14 +1201,18 @@ int Shell::RunMain(int argc, char* argv[]) {
} else { } else {
context.Dispose(); context.Dispose();
} }
#ifndef USING_V8_SHARED
// Start preemption if threads have been created and preemption is enabled. // Start preemption if threads have been created and preemption is enabled.
if (options.parallel_files != NULL if (options.parallel_files != NULL
&& threads.length() > 0 && threads.length() > 0
&& options.use_preemption) { && options.use_preemption) {
Locker::StartPreemption(options.preemption_interval); Locker::StartPreemption(options.preemption_interval);
} }
#endif // USING_V8_SHARED
} }
#ifndef USING_V8_SHARED
for (int i = 1; i < options.num_isolates; ++i) { for (int i = 1; i < options.num_isolates; ++i) {
options.isolate_sources[i].WaitForThread(); options.isolate_sources[i].WaitForThread();
} }
...@@ -1110,6 +1225,7 @@ int Shell::RunMain(int argc, char* argv[]) { ...@@ -1110,6 +1225,7 @@ int Shell::RunMain(int argc, char* argv[]) {
} }
OnExit(); OnExit();
#endif // USING_V8_SHARED
return 0; return 0;
} }
...@@ -1136,14 +1252,15 @@ int Shell::Main(int argc, char* argv[]) { ...@@ -1136,14 +1252,15 @@ int Shell::Main(int argc, char* argv[]) {
result = RunMain(argc, argv); result = RunMain(argc, argv);
} }
#ifdef ENABLE_DEBUGGER_SUPPORT
#if !defined(USING_V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT)
// Run remote debugger if requested, but never on --test // Run remote debugger if requested, but never on --test
if (i::FLAG_remote_debugger && !options.test_shell) { if (i::FLAG_remote_debugger && !options.test_shell) {
InstallUtilityScript(); InstallUtilityScript();
RunRemoteDebugger(i::FLAG_debugger_port); RunRemoteDebugger(i::FLAG_debugger_port);
return 0; return 0;
} }
#endif #endif // !USING_V8_SHARED && ENABLE_DEBUGGER_SUPPORT
// Run interactive shell if explicitly requested or if no script has been // Run interactive shell if explicitly requested or if no script has been
// executed, but never on --test // executed, but never on --test
...@@ -1151,7 +1268,9 @@ int Shell::Main(int argc, char* argv[]) { ...@@ -1151,7 +1268,9 @@ int Shell::Main(int argc, char* argv[]) {
if (( options.interactive_shell if (( options.interactive_shell
|| !options.script_executed ) || !options.script_executed )
&& !options.test_shell ) { && !options.test_shell ) {
#ifndef USING_V8_SHARED
InstallUtilityScript(); InstallUtilityScript();
#endif // USING_V8_SHARED
RunShell(); RunShell();
} }
......
...@@ -31,7 +31,6 @@ ...@@ -31,7 +31,6 @@
'target_name': 'd8', 'target_name': 'd8',
'type': 'executable', 'type': 'executable',
'dependencies': [ 'dependencies': [
'd8_js2c#host',
'../tools/gyp/v8.gyp:v8', '../tools/gyp/v8.gyp:v8',
], ],
'include_dirs+': [ 'include_dirs+': [
...@@ -42,17 +41,26 @@ ...@@ -42,17 +41,26 @@
], ],
'sources': [ 'sources': [
'd8.cc', 'd8.cc',
'd8-debug.cc',
'<(SHARED_INTERMEDIATE_DIR)/d8-js.cc',
], ],
'conditions': [ 'conditions': [
[ 'OS=="linux" or OS=="mac" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', { [ 'component!="shared_library"', {
'dependencies': [ 'd8_js2c#host', ],
'sources': [ 'd8-debug.cc', '<(SHARED_INTERMEDIATE_DIR)/d8-js.cc', ],
'conditions': [
[ 'console=="readline"', {
'libraries': [ '-lreadline', ],
'sources': [ 'd8-readline.cc' ],
}],
[ '(OS=="linux" or OS=="mac" or OS=="freebsd" \
or OS=="openbsd" or OS=="solaris")', {
'sources': [ 'd8-posix.cc', ] 'sources': [ 'd8-posix.cc', ]
}], }],
[ 'OS=="win"', { [ 'OS=="win"', {
'sources': [ 'd8-windows.cc', ] 'sources': [ 'd8-windows.cc', ]
}], }],
], ],
}],
],
}, },
{ {
'target_name': 'd8_js2c', 'target_name': 'd8_js2c',
......
...@@ -28,16 +28,23 @@ ...@@ -28,16 +28,23 @@
#ifndef V8_D8_H_ #ifndef V8_D8_H_
#define V8_D8_H_ #define V8_D8_H_
#include "allocation.h"
#ifndef USING_V8_SHARED
#include "v8.h" #include "v8.h"
#include "allocation.h"
#include "hashmap.h" #include "hashmap.h"
#else
#include "../include/v8.h"
#endif // USING_V8_SHARED
namespace v8 { namespace v8 {
#ifndef USING_V8_SHARED
namespace i = v8::internal; namespace i = v8::internal;
#endif // USING_V8_SHARED
#ifndef USING_V8_SHARED
// A single counter in a counter collection. // A single counter in a counter collection.
class Counter { class Counter {
public: public:
...@@ -110,14 +117,17 @@ class CounterMap { ...@@ -110,14 +117,17 @@ class CounterMap {
static bool Match(void* key1, void* key2); static bool Match(void* key1, void* key2);
i::HashMap hash_map_; i::HashMap hash_map_;
}; };
#endif // USING_V8_SHARED
class SourceGroup { class SourceGroup {
public: public:
SourceGroup() SourceGroup() :
: next_semaphore_(v8::internal::OS::CreateSemaphore(0)), #ifndef USING_V8_SHARED
next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
done_semaphore_(v8::internal::OS::CreateSemaphore(0)), done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
thread_(NULL), thread_(NULL),
#endif // USING_V8_SHARED
argv_(NULL), argv_(NULL),
begin_offset_(0), begin_offset_(0),
end_offset_(0) { } end_offset_(0) { }
...@@ -131,6 +141,7 @@ class SourceGroup { ...@@ -131,6 +141,7 @@ class SourceGroup {
void Execute(); void Execute();
#ifndef USING_V8_SHARED
void StartExecuteInThread(); void StartExecuteInThread();
void WaitForThread(); void WaitForThread();
...@@ -154,6 +165,7 @@ class SourceGroup { ...@@ -154,6 +165,7 @@ class SourceGroup {
i::Semaphore* next_semaphore_; i::Semaphore* next_semaphore_;
i::Semaphore* done_semaphore_; i::Semaphore* done_semaphore_;
i::Thread* thread_; i::Thread* thread_;
#endif // USING_V8_SHARED
void ExitShell(int exit_code); void ExitShell(int exit_code);
Handle<String> ReadFile(const char* name); Handle<String> ReadFile(const char* name);
...@@ -166,34 +178,41 @@ class SourceGroup { ...@@ -166,34 +178,41 @@ class SourceGroup {
class ShellOptions { class ShellOptions {
public: public:
ShellOptions() ShellOptions() :
: script_executed(false), #ifndef USING_V8_SHARED
use_preemption(true),
preemption_interval(10),
parallel_files(NULL),
#endif // USING_V8_SHARED
script_executed(false),
last_run(true), last_run(true),
stress_opt(false), stress_opt(false),
stress_deopt(false), stress_deopt(false),
interactive_shell(false), interactive_shell(false),
test_shell(false), test_shell(false),
use_preemption(true),
preemption_interval(10),
num_isolates(1), num_isolates(1),
isolate_sources(NULL), isolate_sources(NULL) { }
parallel_files(NULL) { }
#ifndef USING_V8_SHARED
bool use_preemption;
int preemption_interval;
i::List< i::Vector<const char> >* parallel_files;
#endif // USING_V8_SHARED
bool script_executed; bool script_executed;
bool last_run; bool last_run;
bool stress_opt; bool stress_opt;
bool stress_deopt; bool stress_deopt;
bool interactive_shell; bool interactive_shell;
bool test_shell; bool test_shell;
bool use_preemption;
int preemption_interval;
int num_isolates; int num_isolates;
SourceGroup* isolate_sources; SourceGroup* isolate_sources;
i::List< i::Vector<const char> >* parallel_files;
}; };
#ifdef USING_V8_SHARED
class Shell: public i::AllStatic { class Shell {
#else
class Shell : public i::AllStatic {
#endif // USING_V8_SHARED
public: public:
static bool ExecuteString(Handle<String> source, static bool ExecuteString(Handle<String> source,
Handle<Value> name, Handle<Value> name,
...@@ -201,6 +220,14 @@ class Shell: public i::AllStatic { ...@@ -201,6 +220,14 @@ class Shell: public i::AllStatic {
bool report_exceptions); bool report_exceptions);
static const char* ToCString(const v8::String::Utf8Value& value); static const char* ToCString(const v8::String::Utf8Value& value);
static void ReportException(TryCatch* try_catch); static void ReportException(TryCatch* try_catch);
static Handle<String> ReadFile(const char* name);
static Persistent<Context> CreateEvaluationContext();
static int RunMain(int argc, char* argv[]);
static int Main(int argc, char* argv[]);
#ifndef USING_V8_SHARED
static Handle<Array> GetCompletions(Handle<String> text,
Handle<String> full);
static void OnExit(); static void OnExit();
static int* LookupCounter(const char* name); static int* LookupCounter(const char* name);
static void* CreateHistogram(const char* name, static void* CreateHistogram(const char* name,
...@@ -209,18 +236,8 @@ class Shell: public i::AllStatic { ...@@ -209,18 +236,8 @@ class Shell: public i::AllStatic {
size_t buckets); size_t buckets);
static void AddHistogramSample(void* histogram, int sample); static void AddHistogramSample(void* histogram, int sample);
static void MapCounters(const char* name); static void MapCounters(const char* name);
static Handle<String> ReadFile(const char* name); #endif // USING_V8_SHARED
static void Initialize();
static Persistent<Context> CreateEvaluationContext();
static void InstallUtilityScript();
static void RunShell();
static bool SetOptions(int argc, char* argv[]);
static int RunScript(char* filename);
static int RunMain(int argc, char* argv[]);
static int Main(int argc, char* argv[]);
static Handle<ObjectTemplate> CreateGlobalTemplate();
static Handle<Array> GetCompletions(Handle<String> text,
Handle<String> full);
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
static Handle<Object> DebugMessageDetails(Handle<String> message); static Handle<Object> DebugMessageDetails(Handle<String> message);
static Handle<Value> DebugCommandToJSONRequest(Handle<String> command); static Handle<Value> DebugCommandToJSONRequest(Handle<String> command);
...@@ -283,15 +300,16 @@ class Shell: public i::AllStatic { ...@@ -283,15 +300,16 @@ class Shell: public i::AllStatic {
static Handle<Value> RemoveDirectory(const Arguments& args); static Handle<Value> RemoveDirectory(const Arguments& args);
static void AddOSMethods(Handle<ObjectTemplate> os_template); static void AddOSMethods(Handle<ObjectTemplate> os_template);
#ifndef USING_V8_SHARED
static const char* kHistoryFileName; static const char* kHistoryFileName;
#endif // USING_V8_SHARED
static const char* kPrompt; static const char* kPrompt;
static ShellOptions options; static ShellOptions options;
private: private:
static Persistent<Context> utility_context_;
static Persistent<Context> evaluation_context_; static Persistent<Context> evaluation_context_;
#ifndef USING_V8_SHARED
static Persistent<Context> utility_context_;
static CounterMap* counter_map_; static CounterMap* counter_map_;
// We statically allocate a set of local counters to be used if we // We statically allocate a set of local counters to be used if we
// don't want to store the stats in a memory-mapped file // don't want to store the stats in a memory-mapped file
...@@ -299,7 +317,14 @@ class Shell: public i::AllStatic { ...@@ -299,7 +317,14 @@ class Shell: public i::AllStatic {
static CounterCollection* counters_; static CounterCollection* counters_;
static i::OS::MemoryMappedFile* counters_file_; static i::OS::MemoryMappedFile* counters_file_;
static i::Mutex* context_mutex_; static i::Mutex* context_mutex_;
static Counter* GetCounter(const char* name, bool is_histogram); static Counter* GetCounter(const char* name, bool is_histogram);
static void InstallUtilityScript();
#endif // USING_V8_SHARED
static void Initialize();
static void RunShell();
static bool SetOptions(int argc, char* argv[]);
static Handle<ObjectTemplate> CreateGlobalTemplate();
static Handle<Value> CreateExternalArray(const Arguments& args, static Handle<Value> CreateExternalArray(const Arguments& args,
ExternalArrayType type, ExternalArrayType type,
size_t element_size); size_t element_size);
...@@ -307,6 +332,7 @@ class Shell: public i::AllStatic { ...@@ -307,6 +332,7 @@ class Shell: public i::AllStatic {
}; };
#ifndef USING_V8_SHARED
class LineEditor { class LineEditor {
public: public:
enum Type { DUMB = 0, READLINE = 1 }; enum Type { DUMB = 0, READLINE = 1 };
...@@ -326,6 +352,7 @@ class LineEditor { ...@@ -326,6 +352,7 @@ class LineEditor {
LineEditor* next_; LineEditor* next_;
static LineEditor* first_; static LineEditor* first_;
}; };
#endif // USING_V8_SHARED
} // namespace v8 } // namespace v8
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment