diff options
author | Ben Murdoch <benm@google.com> | 2011-11-30 16:03:39 +0000 |
---|---|---|
committer | Ben Murdoch <benm@google.com> | 2011-12-02 17:28:02 +0000 |
commit | 69a99ed0b2b2ef69d393c371b03db3a98aaf880e (patch) | |
tree | 6438154d0f3ab526b9206f8860fa4db5cf073c11 /samples | |
parent | 3fb3ca8c7ca439d408449a395897395c0faae8d1 (diff) | |
download | android_external_v8-69a99ed0b2b2ef69d393c371b03db3a98aaf880e.tar.gz android_external_v8-69a99ed0b2b2ef69d393c371b03db3a98aaf880e.tar.bz2 android_external_v8-69a99ed0b2b2ef69d393c371b03db3a98aaf880e.zip |
Upgrade to V8 3.5
Merge V8 3.5.10.24
Simple merge required updates to makefiles only.
Bug: 5688872
Change-Id: I0acdb9a1a53919d84e9a7525308e8371739d2f06
Diffstat (limited to 'samples')
-rw-r--r-- | samples/samples.gyp | 20 | ||||
-rw-r--r-- | samples/shell.cc | 485 |
2 files changed, 63 insertions, 442 deletions
diff --git a/samples/samples.gyp b/samples/samples.gyp index f383ee20..55b2a98a 100644 --- a/samples/samples.gyp +++ b/samples/samples.gyp @@ -1,4 +1,4 @@ -# Copyright 2010 the V8 project authors. All rights reserved. +# Copyright 2011 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: @@ -26,23 +26,25 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { + 'includes': ['../build/common.gypi'], + 'target_defaults': { + 'type': 'executable', + 'dependencies': [ + '../tools/gyp/v8.gyp:v8', + ], + 'include_dirs': [ + '../include', + ], + }, 'targets': [ { 'target_name': 'shell', - 'type': 'executable', - 'dependencies': [ - '../tools/gyp/v8.gyp:v8', - ], 'sources': [ 'shell.cc', ], }, { 'target_name': 'process', - 'type': 'executable', - 'dependencies': [ - '../tools/gyp/v8.gyp:v8', - ], 'sources': [ 'process.cc', ], diff --git a/samples/shell.cc b/samples/shell.cc index f37e731f..8ed9d032 100644 --- a/samples/shell.cc +++ b/samples/shell.cc @@ -26,39 +26,28 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include <v8.h> -#include <v8-testing.h> #include <assert.h> -#ifdef COMPRESS_STARTUP_DATA_BZ2 -#include <bzlib.h> -#endif #include <fcntl.h> #include <string.h> #include <stdio.h> #include <stdlib.h> -// When building with V8 in a shared library we cannot use functions which -// is not explicitly a part of the public V8 API. This extensive use of -// #ifndef USING_V8_SHARED/#endif is a hack until we can resolve whether to -// still use the shell sample for testing or change to use the developer -// shell d8 TODO(1272). -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) -#include "../src/v8.h" -#endif // USING_V8_SHARED - -#if !defined(_WIN32) && !defined(_WIN64) -#include <unistd.h> // NOLINT +#ifdef COMPRESS_STARTUP_DATA_BZ2 +#error Using compressed startup data is not supported for this sample #endif -static void ExitShell(int exit_code) { - // Use _exit instead of exit to avoid races between isolate - // threads and static destructors. - fflush(stdout); - fflush(stderr); - _exit(exit_code); -} +/** + * This sample program shows how to implement a simple javascript shell + * based on V8. This includes initializing V8 with command line options, + * creating global functions, compiling and executing strings. + * + * For a more sophisticated shell, consider using the debug shell D8. + */ + v8::Persistent<v8::Context> CreateShellContext(); void RunShell(v8::Handle<v8::Context> context); +int RunMain(int argc, char* argv[]); bool ExecuteString(v8::Handle<v8::String> source, v8::Handle<v8::Value> name, bool print_result, @@ -68,305 +57,28 @@ v8::Handle<v8::Value> Read(const v8::Arguments& args); v8::Handle<v8::Value> Load(const v8::Arguments& args); v8::Handle<v8::Value> Quit(const v8::Arguments& args); v8::Handle<v8::Value> Version(const v8::Arguments& args); -v8::Handle<v8::Value> Int8Array(const v8::Arguments& args); -v8::Handle<v8::Value> Uint8Array(const v8::Arguments& args); -v8::Handle<v8::Value> Int16Array(const v8::Arguments& args); -v8::Handle<v8::Value> Uint16Array(const v8::Arguments& args); -v8::Handle<v8::Value> Int32Array(const v8::Arguments& args); -v8::Handle<v8::Value> Uint32Array(const v8::Arguments& args); -v8::Handle<v8::Value> Float32Array(const v8::Arguments& args); -v8::Handle<v8::Value> Float64Array(const v8::Arguments& args); -v8::Handle<v8::Value> PixelArray(const v8::Arguments& args); v8::Handle<v8::String> ReadFile(const char* name); void ReportException(v8::TryCatch* handler); -static bool last_run = true; - -class SourceGroup { - public: - SourceGroup() : -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - next_semaphore_(v8::internal::OS::CreateSemaphore(0)), - done_semaphore_(v8::internal::OS::CreateSemaphore(0)), - thread_(NULL), -#endif // USING_V8_SHARED - argv_(NULL), - begin_offset_(0), - end_offset_(0) { } - -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - ~SourceGroup() { - delete next_semaphore_; - delete done_semaphore_; - } -#endif // USING_V8_SHARED - - void Begin(char** argv, int offset) { - argv_ = const_cast<const char**>(argv); - begin_offset_ = offset; - } - - void End(int offset) { end_offset_ = offset; } - - void Execute() { - for (int i = begin_offset_; i < end_offset_; ++i) { - const char* arg = argv_[i]; - if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) { - // Execute argument given to -e option directly. - v8::HandleScope handle_scope; - v8::Handle<v8::String> file_name = v8::String::New("unnamed"); - v8::Handle<v8::String> source = v8::String::New(argv_[i + 1]); - if (!ExecuteString(source, file_name, false, true)) { - ExitShell(1); - return; - } - ++i; - } else if (arg[0] == '-') { - // Ignore other options. They have been parsed already. - } else { - // Use all other arguments as names of files to load and run. - v8::HandleScope handle_scope; - v8::Handle<v8::String> file_name = v8::String::New(arg); - v8::Handle<v8::String> source = ReadFile(arg); - if (source.IsEmpty()) { - printf("Error reading '%s'\n", arg); - continue; - } - if (!ExecuteString(source, file_name, false, true)) { - ExitShell(1); - return; - } - } - } - } - -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - void StartExecuteInThread() { - if (thread_ == NULL) { - thread_ = new IsolateThread(this); - thread_->Start(); - } - next_semaphore_->Signal(); - } - - void WaitForThread() { - if (thread_ == NULL) return; - if (last_run) { - thread_->Join(); - thread_ = NULL; - } else { - done_semaphore_->Wait(); - } - } -#endif // USING_V8_SHARED - - private: -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - static v8::internal::Thread::Options GetThreadOptions() { - v8::internal::Thread::Options options; - options.name = "IsolateThread"; - // On some systems (OSX 10.6) the stack size default is 0.5Mb or less - // which is not enough to parse the big literal expressions used in tests. - // The stack size should be at least StackGuard::kLimitSize + some - // OS-specific padding for thread startup code. - options.stack_size = 2 << 20; // 2 Mb seems to be enough - return options; - } - - class IsolateThread : public v8::internal::Thread { - public: - explicit IsolateThread(SourceGroup* group) - : v8::internal::Thread(GetThreadOptions()), group_(group) {} - - virtual void Run() { - group_->ExecuteInThread(); - } - - private: - SourceGroup* group_; - }; - - void ExecuteInThread() { - v8::Isolate* isolate = v8::Isolate::New(); - do { - if (next_semaphore_ != NULL) next_semaphore_->Wait(); - { - v8::Isolate::Scope iscope(isolate); - v8::HandleScope scope; - v8::Persistent<v8::Context> context = CreateShellContext(); - { - v8::Context::Scope cscope(context); - Execute(); - } - context.Dispose(); - } - if (done_semaphore_ != NULL) done_semaphore_->Signal(); - } while (!last_run); - isolate->Dispose(); - } - - v8::internal::Semaphore* next_semaphore_; - v8::internal::Semaphore* done_semaphore_; - v8::internal::Thread* thread_; -#endif // USING_V8_SHARED - - const char** argv_; - int begin_offset_; - int end_offset_; -}; - +static bool run_shell; -static SourceGroup* isolate_sources = NULL; - -#ifdef COMPRESS_STARTUP_DATA_BZ2 -class BZip2Decompressor : public v8::StartupDataDecompressor { - public: - virtual ~BZip2Decompressor() { } - - protected: - virtual int DecompressData(char* raw_data, - int* raw_data_size, - const char* compressed_data, - int compressed_data_size) { - ASSERT_EQ(v8::StartupData::kBZip2, - v8::V8::GetCompressedStartupDataAlgorithm()); - unsigned int decompressed_size = *raw_data_size; - int result = - BZ2_bzBuffToBuffDecompress(raw_data, - &decompressed_size, - const_cast<char*>(compressed_data), - compressed_data_size, - 0, 1); - if (result == BZ_OK) { - *raw_data_size = decompressed_size; - } - return result; - } -}; -#endif - - -int RunMain(int argc, char* argv[]) { +int main(int argc, char* argv[]) { v8::V8::SetFlagsFromCommandLine(&argc, argv, true); + run_shell = (argc == 1); v8::HandleScope handle_scope; v8::Persistent<v8::Context> context = CreateShellContext(); - // Enter the newly created execution environment. - context->Enter(); if (context.IsEmpty()) { printf("Error creating context\n"); return 1; } - - bool run_shell = (argc == 1); - int num_isolates = 1; - for (int i = 1; i < argc; i++) { - if (strcmp(argv[i], "--isolate") == 0) { -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - ++num_isolates; -#else // USING_V8_SHARED - printf("Error: --isolate not supported when linked with shared " - "library\n"); - ExitShell(1); -#endif // USING_V8_SHARED - } - } - if (isolate_sources == NULL) { - isolate_sources = new SourceGroup[num_isolates]; - SourceGroup* current = isolate_sources; - current->Begin(argv, 1); - for (int i = 1; i < argc; i++) { - const char* str = argv[i]; - if (strcmp(str, "--isolate") == 0) { - current->End(i); - current++; - current->Begin(argv, i + 1); - } else if (strcmp(str, "--shell") == 0) { - run_shell = true; - } else if (strcmp(str, "-f") == 0) { - // Ignore any -f flags for compatibility with the other stand- - // alone JavaScript engines. - continue; - } else if (strncmp(str, "--", 2) == 0) { - printf("Warning: unknown flag %s.\nTry --help for options\n", str); - } - } - current->End(argc); - } -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - for (int i = 1; i < num_isolates; ++i) { - isolate_sources[i].StartExecuteInThread(); - } -#endif // USING_V8_SHARED - isolate_sources[0].Execute(); + context->Enter(); + int result = RunMain(argc, argv); if (run_shell) RunShell(context); -#if !(defined(USING_V8_SHARED) || defined(V8_SHARED)) - for (int i = 1; i < num_isolates; ++i) { - isolate_sources[i].WaitForThread(); - } -#endif // USING_V8_SHARED - if (last_run) { - delete[] isolate_sources; - isolate_sources = NULL; - } context->Exit(); context.Dispose(); - return 0; -} - - -int main(int argc, char* argv[]) { - // Figure out if we're requested to stress the optimization - // infrastructure by running tests multiple times and forcing - // optimization in the last run. - bool FLAG_stress_opt = false; - bool FLAG_stress_deopt = false; - for (int i = 0; i < argc; i++) { - if (strcmp(argv[i], "--stress-opt") == 0) { - FLAG_stress_opt = true; - argv[i] = NULL; - } else if (strcmp(argv[i], "--stress-deopt") == 0) { - FLAG_stress_deopt = true; - argv[i] = NULL; - } else if (strcmp(argv[i], "--noalways-opt") == 0) { - // No support for stressing if we can't use --always-opt. - FLAG_stress_opt = false; - FLAG_stress_deopt = false; - break; - } - } - -#ifdef COMPRESS_STARTUP_DATA_BZ2 - BZip2Decompressor startup_data_decompressor; - int bz2_result = startup_data_decompressor.Decompress(); - if (bz2_result != BZ_OK) { - fprintf(stderr, "bzip error code: %d\n", bz2_result); - exit(1); - } -#endif - - v8::V8::SetFlagsFromCommandLine(&argc, argv, true); - int result = 0; - if (FLAG_stress_opt || FLAG_stress_deopt) { - v8::Testing::SetStressRunType(FLAG_stress_opt - ? v8::Testing::kStressTypeOpt - : v8::Testing::kStressTypeDeopt); - int stress_runs = v8::Testing::GetStressRuns(); - for (int i = 0; i < stress_runs && result == 0; i++) { - printf("============ Stress %d/%d ============\n", - i + 1, stress_runs); - v8::Testing::PrepareStressRun(i); - last_run = (i == stress_runs - 1); - result = RunMain(argc, argv); - } - printf("======== Full Deoptimization =======\n"); - v8::Testing::DeoptimizeAll(); - } else { - result = RunMain(argc, argv); - } v8::V8::Dispose(); - return result; } @@ -393,26 +105,6 @@ v8::Persistent<v8::Context> CreateShellContext() { // Bind the 'version' function global->Set(v8::String::New("version"), v8::FunctionTemplate::New(Version)); - // Bind the handlers for external arrays. - global->Set(v8::String::New("Int8Array"), - v8::FunctionTemplate::New(Int8Array)); - global->Set(v8::String::New("Uint8Array"), - v8::FunctionTemplate::New(Uint8Array)); - global->Set(v8::String::New("Int16Array"), - v8::FunctionTemplate::New(Int16Array)); - global->Set(v8::String::New("Uint16Array"), - v8::FunctionTemplate::New(Uint16Array)); - global->Set(v8::String::New("Int32Array"), - v8::FunctionTemplate::New(Int32Array)); - global->Set(v8::String::New("Uint32Array"), - v8::FunctionTemplate::New(Uint32Array)); - global->Set(v8::String::New("Float32Array"), - v8::FunctionTemplate::New(Float32Array)); - global->Set(v8::String::New("Float64Array"), - v8::FunctionTemplate::New(Float64Array)); - global->Set(v8::String::New("PixelArray"), - v8::FunctionTemplate::New(PixelArray)); - return v8::Context::New(NULL, global); } @@ -486,7 +178,9 @@ v8::Handle<v8::Value> Quit(const v8::Arguments& args) { // If not arguments are given args[0] will yield undefined which // converts to the integer value 0. int exit_code = args[0]->Int32Value(); - ExitShell(exit_code); + fflush(stdout); + fflush(stderr); + exit(exit_code); return v8::Undefined(); } @@ -496,113 +190,6 @@ v8::Handle<v8::Value> Version(const v8::Arguments& args) { } -void ExternalArrayWeakCallback(v8::Persistent<v8::Value> object, void* data) { - free(data); - object.Dispose(); -} - - -v8::Handle<v8::Value> CreateExternalArray(const v8::Arguments& args, - v8::ExternalArrayType type, - size_t element_size) { - assert(element_size == 1 || - element_size == 2 || - element_size == 4 || - element_size == 8); - if (args.Length() != 1) { - return v8::ThrowException( - v8::String::New("Array constructor needs one parameter.")); - } - static const int kMaxLength = 0x3fffffff; - size_t length = 0; - if (args[0]->IsUint32()) { - length = args[0]->Uint32Value(); - } else if (args[0]->IsNumber()) { - double raw_length = args[0]->NumberValue(); - if (raw_length < 0) { - return v8::ThrowException( - v8::String::New("Array length must not be negative.")); - } - if (raw_length > kMaxLength) { - return v8::ThrowException( - v8::String::New("Array length exceeds maximum length.")); - } - length = static_cast<size_t>(raw_length); - } else { - return v8::ThrowException( - v8::String::New("Array length must be a number.")); - } - if (length > static_cast<size_t>(kMaxLength)) { - return v8::ThrowException( - v8::String::New("Array length exceeds maximum length.")); - } - void* data = calloc(length, element_size); - if (data == NULL) { - return v8::ThrowException(v8::String::New("Memory allocation failed.")); - } - v8::Handle<v8::Object> array = v8::Object::New(); - v8::Persistent<v8::Object> persistent_array = - v8::Persistent<v8::Object>::New(array); - persistent_array.MakeWeak(data, ExternalArrayWeakCallback); - persistent_array.MarkIndependent(); - array->SetIndexedPropertiesToExternalArrayData(data, type, length); - array->Set(v8::String::New("length"), v8::Int32::New(length), - v8::ReadOnly); - array->Set(v8::String::New("BYTES_PER_ELEMENT"), - v8::Int32::New(element_size)); - return array; -} - - -v8::Handle<v8::Value> Int8Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t)); -} - - -v8::Handle<v8::Value> Uint8Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalUnsignedByteArray, - sizeof(uint8_t)); -} - - -v8::Handle<v8::Value> Int16Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalShortArray, sizeof(int16_t)); -} - - -v8::Handle<v8::Value> Uint16Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalUnsignedShortArray, - sizeof(uint16_t)); -} - -v8::Handle<v8::Value> Int32Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalIntArray, sizeof(int32_t)); -} - - -v8::Handle<v8::Value> Uint32Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalUnsignedIntArray, - sizeof(uint32_t)); -} - - -v8::Handle<v8::Value> Float32Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalFloatArray, - sizeof(float)); // NOLINT -} - - -v8::Handle<v8::Value> Float64Array(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalDoubleArray, - sizeof(double)); // NOLINT -} - - -v8::Handle<v8::Value> PixelArray(const v8::Arguments& args) { - return CreateExternalArray(args, v8::kExternalPixelArray, sizeof(uint8_t)); -} - - // Reads a file into a v8 string. v8::Handle<v8::String> ReadFile(const char* name) { FILE* file = fopen(name, "rb"); @@ -625,9 +212,41 @@ v8::Handle<v8::String> ReadFile(const char* name) { } +// Process remaining command line arguments and execute files +int RunMain(int argc, char* argv[]) { + for (int i = 1; i < argc; i++) { + const char* str = argv[i]; + if (strcmp(str, "--shell") == 0) { + run_shell = true; + } else if (strcmp(str, "-f") == 0) { + // Ignore any -f flags for compatibility with the other stand- + // alone JavaScript engines. + continue; + } else if (strncmp(str, "--", 2) == 0) { + printf("Warning: unknown flag %s.\nTry --help for options\n", str); + } else if (strcmp(str, "-e") == 0 && i + 1 < argc) { + // Execute argument given to -e option directly. + v8::Handle<v8::String> file_name = v8::String::New("unnamed"); + v8::Handle<v8::String> source = v8::String::New(argv[++i]); + if (!ExecuteString(source, file_name, false, true)) return 1; + } else { + // Use all other arguments as names of files to load and run. + v8::Handle<v8::String> file_name = v8::String::New(str); + v8::Handle<v8::String> source = ReadFile(str); + if (source.IsEmpty()) { + printf("Error reading '%s'\n", str); + continue; + } + if (!ExecuteString(source, file_name, false, true)) return 1; + } + } + return 0; +} + + // The read-eval-execute loop of the shell. void RunShell(v8::Handle<v8::Context> context) { - printf("V8 version %s\n", v8::V8::GetVersion()); + printf("V8 version %s [sample shell]\n", v8::V8::GetVersion()); static const int kBufferSize = 256; // Enter the execution environment before evaluating any code. v8::Context::Scope context_scope(context); |