aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/src/d8.cc
diff options
context:
space:
mode:
authorMichaƫl Zasso <mic.besace@gmail.com>2015-10-06 08:42:38 +0200
committerAli Ijaz Sheikh <ofrobots@google.com>2015-10-14 11:20:34 -0700
commitd8011d1683fe0d977de2bea1147f5213d4490c5a (patch)
tree54967df8dc1732e59eef39e5c5b39fe99ad88977 /deps/v8/src/d8.cc
parentd1a2e5357ef0357cec9b516fa9ac78cc38a984aa (diff)
downloadandroid-node-v8-d8011d1683fe0d977de2bea1147f5213d4490c5a.tar.gz
android-node-v8-d8011d1683fe0d977de2bea1147f5213d4490c5a.tar.bz2
android-node-v8-d8011d1683fe0d977de2bea1147f5213d4490c5a.zip
deps: upgrade V8 to 4.6.85.23
PR-URL: https://github.com/nodejs/node/pull/3351 Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com> Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/d8.cc')
-rw-r--r--deps/v8/src/d8.cc985
1 files changed, 521 insertions, 464 deletions
diff --git a/deps/v8/src/d8.cc b/deps/v8/src/d8.cc
index 45bf33167f..58b59c890f 100644
--- a/deps/v8/src/d8.cc
+++ b/deps/v8/src/d8.cc
@@ -19,6 +19,7 @@
#ifndef V8_SHARED
#include <algorithm>
+#include <vector>
#endif // !V8_SHARED
#ifdef V8_SHARED
@@ -43,13 +44,15 @@
#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/snapshot/natives.h"
#include "src/utils.h"
#include "src/v8.h"
#endif // !V8_SHARED
+#if defined(V8_WASM)
+#include "src/wasm/wasm-js.h"
+#endif
+
#if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h> // NOLINT
#else
@@ -72,6 +75,9 @@ namespace v8 {
namespace {
const int MB = 1024 * 1024;
+#ifndef V8_SHARED
+const int kMaxWorkers = 50;
+#endif
class ShellArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
@@ -102,8 +108,15 @@ class MockArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
v8::Platform* g_platform = NULL;
+static Local<Value> Throw(Isolate* isolate, const char* message) {
+ return isolate->ThrowException(
+ String::NewFromUtf8(isolate, message, NewStringType::kNormal)
+ .ToLocalChecked());
+}
+
+
#ifndef V8_SHARED
-bool FindInObjectList(Handle<Object> object, const Shell::ObjectList& list) {
+bool FindInObjectList(Local<Object> object, const Shell::ObjectList& list) {
for (int i = 0; i < list.length(); ++i) {
if (list[i]->StrictEquals(object)) {
return true;
@@ -111,16 +124,27 @@ bool FindInObjectList(Handle<Object> object, const Shell::ObjectList& list) {
}
return false;
}
-#endif // !V8_SHARED
-} // namespace
+Worker* GetWorkerFromInternalField(Isolate* isolate, Local<Object> object) {
+ if (object->InternalFieldCount() != 1) {
+ Throw(isolate, "this is not a Worker");
+ return NULL;
+ }
+ Worker* worker =
+ static_cast<Worker*>(object->GetAlignedPointerFromInternalField(0));
+ if (worker == NULL) {
+ Throw(isolate, "Worker is defunct because main thread is terminating");
+ return NULL;
+ }
-static Handle<Value> Throw(Isolate* isolate, const char* message) {
- return isolate->ThrowException(String::NewFromUtf8(isolate, message));
+ return worker;
}
+#endif // !V8_SHARED
+
+} // namespace
class PerIsolateData {
@@ -153,64 +177,34 @@ class PerIsolateData {
int realm_count_;
int realm_current_;
int realm_switch_;
- Persistent<Context>* realms_;
- Persistent<Value> realm_shared_;
+ Global<Context>* realms_;
+ Global<Value> realm_shared_;
int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args,
int arg_offset);
- int RealmFind(Handle<Context> 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<String> Prompt(const char* prompt);
- private:
- Isolate* isolate_;
+ int RealmFind(Local<Context> context);
};
-Handle<String> 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_;
+base::LazyMutex Shell::context_mutex_;
const base::TimeTicks Shell::kInitialTicks =
base::TimeTicks::HighResolutionNow();
-Persistent<Context> Shell::utility_context_;
-base::Mutex Shell::workers_mutex_;
+Global<Context> Shell::utility_context_;
+base::LazyMutex Shell::workers_mutex_;
bool Shell::allow_new_workers_ = true;
i::List<Worker*> Shell::workers_;
i::List<SharedArrayBuffer::Contents> Shell::externalized_shared_contents_;
#endif // !V8_SHARED
-Persistent<Context> Shell::evaluation_context_;
+Global<Context> Shell::evaluation_context_;
ArrayBuffer::Allocator* Shell::array_buffer_allocator;
ShellOptions Shell::options;
-const char* Shell::kPrompt = "d8> ";
+base::OnceType Shell::quit_once_ = V8_ONCE_INIT;
#ifndef V8_SHARED
bool CounterMap::Match(void* key1, void* key2) {
@@ -249,19 +243,22 @@ ScriptCompiler::CachedData* CompileForCachedData(
Isolate::Scope isolate_scope(temp_isolate);
HandleScope handle_scope(temp_isolate);
Context::Scope context_scope(Context::New(temp_isolate));
- Local<String> source_copy = v8::String::NewFromTwoByte(
- temp_isolate, source_buffer, v8::String::kNormalString, source_length);
+ Local<String> source_copy =
+ v8::String::NewFromTwoByte(temp_isolate, source_buffer,
+ v8::NewStringType::kNormal,
+ source_length).ToLocalChecked();
Local<Value> name_copy;
if (name_buffer) {
- name_copy = v8::String::NewFromTwoByte(
- temp_isolate, name_buffer, v8::String::kNormalString, name_length);
+ name_copy = v8::String::NewFromTwoByte(temp_isolate, name_buffer,
+ v8::NewStringType::kNormal,
+ name_length).ToLocalChecked();
} 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()) {
+ if (!ScriptCompiler::CompileUnboundScript(temp_isolate, &script_source,
+ compile_options).IsEmpty() &&
+ script_source.GetCachedData()) {
int length = script_source.GetCachedData()->length;
uint8_t* cache = new uint8_t[length];
memcpy(cache, script_source.GetCachedData()->data, length);
@@ -277,16 +274,17 @@ ScriptCompiler::CachedData* CompileForCachedData(
// Compile a string within the current v8 context.
-Local<Script> Shell::CompileString(
+MaybeLocal<Script> Shell::CompileString(
Isolate* isolate, Local<String> source, Local<Value> name,
ScriptCompiler::CompileOptions compile_options, SourceType source_type) {
+ Local<Context> context(isolate->GetCurrentContext());
ScriptOrigin origin(name);
if (compile_options == ScriptCompiler::kNoCompileOptions) {
ScriptCompiler::Source script_source(source, origin);
return source_type == SCRIPT
- ? ScriptCompiler::Compile(isolate, &script_source,
+ ? ScriptCompiler::Compile(context, &script_source,
compile_options)
- : ScriptCompiler::CompileModule(isolate, &script_source,
+ : ScriptCompiler::CompileModule(context, &script_source,
compile_options);
}
@@ -301,10 +299,10 @@ Local<Script> Shell::CompileString(
DCHECK(false); // A new compile option?
}
if (data == NULL) compile_options = ScriptCompiler::kNoCompileOptions;
- Local<Script> result =
+ MaybeLocal<Script> result =
source_type == SCRIPT
- ? ScriptCompiler::Compile(isolate, &cached_source, compile_options)
- : ScriptCompiler::CompileModule(isolate, &cached_source,
+ ? ScriptCompiler::Compile(context, &cached_source, compile_options)
+ : ScriptCompiler::CompileModule(context, &cached_source,
compile_options);
CHECK(data == NULL || !data->rejected);
return result;
@@ -312,44 +310,34 @@ Local<Script> Shell::CompileString(
// Executes a string within the current v8 context.
-bool Shell::ExecuteString(Isolate* isolate, Handle<String> source,
- Handle<Value> name, bool print_result,
+bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
+ Local<Value> name, bool print_result,
bool report_exceptions, SourceType source_type) {
-#ifndef V8_SHARED
- bool FLAG_debugger = i::FLAG_debugger;
-#else
- bool FLAG_debugger = false;
-#endif // !V8_SHARED
HandleScope handle_scope(isolate);
TryCatch try_catch(isolate);
- options.script_executed = true;
- if (FLAG_debugger) {
- // When debugging make exceptions appear to be uncaught.
- try_catch.SetVerbose(true);
- }
- Handle<Value> result;
+ MaybeLocal<Value> maybe_result;
{
PerIsolateData* data = PerIsolateData::Get(isolate);
Local<Context> realm =
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
Context::Scope context_scope(realm);
- Handle<Script> script = Shell::CompileString(
- isolate, source, name, options.compile_options, source_type);
- if (script.IsEmpty()) {
+ Local<Script> script;
+ if (!Shell::CompileString(isolate, source, name, options.compile_options,
+ source_type).ToLocal(&script)) {
// Print errors that happened during compilation.
- if (report_exceptions && !FLAG_debugger)
- ReportException(isolate, &try_catch);
+ if (report_exceptions) ReportException(isolate, &try_catch);
return false;
}
- result = script->Run();
+ maybe_result = script->Run(realm);
+ EmptyMessageQueues(isolate);
data->realm_current_ = data->realm_switch_;
}
- if (result.IsEmpty()) {
+ Local<Value> result;
+ if (!maybe_result.ToLocal(&result)) {
DCHECK(try_catch.HasCaught());
// Print errors that happened during execution.
- if (report_exceptions && !FLAG_debugger)
- ReportException(isolate, &try_catch);
+ if (report_exceptions) ReportException(isolate, &try_catch);
return false;
}
DCHECK(!try_catch.HasCaught());
@@ -370,12 +358,19 @@ bool Shell::ExecuteString(Isolate* isolate, Handle<String> source,
v8::Local<v8::Context> context =
v8::Local<v8::Context>::New(isolate, utility_context_);
v8::Context::Scope context_scope(context);
- Handle<Object> global = context->Global();
- Handle<Value> fun =
- global->Get(String::NewFromUtf8(isolate, "Stringify"));
- Handle<Value> argv[1] = {result};
- Handle<Value> s = Handle<Function>::Cast(fun)->Call(global, 1, argv);
- if (try_catch.HasCaught()) return true;
+ Local<Object> global = context->Global();
+ Local<Value> fun =
+ global->Get(context, String::NewFromUtf8(isolate, "Stringify",
+ v8::NewStringType::kNormal)
+ .ToLocalChecked()).ToLocalChecked();
+ Local<Value> argv[1] = {result};
+ Local<Value> s;
+ if (!Local<Function>::Cast(fun)
+ ->Call(context, global, 1, argv)
+ .ToLocal(&s)) {
+ return true;
+ }
+ DCHECK(!try_catch.HasCaught());
v8::String::Utf8Value str(s);
fwrite(*str, sizeof(**str), str.length(), stdout);
printf("\n");
@@ -390,7 +385,7 @@ PerIsolateData::RealmScope::RealmScope(PerIsolateData* data) : data_(data) {
data_->realm_count_ = 1;
data_->realm_current_ = 0;
data_->realm_switch_ = 0;
- data_->realms_ = new Persistent<Context>[1];
+ data_->realms_ = new Global<Context>[1];
data_->realms_[0].Reset(data_->isolate_,
data_->isolate_->GetEnteredContext());
}
@@ -406,7 +401,7 @@ PerIsolateData::RealmScope::~RealmScope() {
}
-int PerIsolateData::RealmFind(Handle<Context> context) {
+int PerIsolateData::RealmFind(Local<Context> context) {
for (int i = 0; i < realm_count_; ++i) {
if (realms_[i] == context) return i;
}
@@ -421,10 +416,10 @@ int PerIsolateData::RealmIndexOrThrow(
Throw(args.GetIsolate(), "Invalid argument");
return -1;
}
- int index = args[arg_offset]->Int32Value();
- if (index < 0 ||
- index >= realm_count_ ||
- realms_[index].IsEmpty()) {
+ int index = args[arg_offset]
+ ->Int32Value(args.GetIsolate()->GetCurrentContext())
+ .FromMaybe(-1);
+ if (index < 0 || index >= realm_count_ || realms_[index].IsEmpty()) {
Throw(args.GetIsolate(), "Invalid realm index");
return -1;
}
@@ -468,7 +463,10 @@ void Shell::RealmOwner(const v8::FunctionCallbackInfo<v8::Value>& args) {
Throw(args.GetIsolate(), "Invalid argument");
return;
}
- int index = data->RealmFind(args[0]->ToObject(isolate)->CreationContext());
+ int index = data->RealmFind(args[0]
+ ->ToObject(isolate->GetCurrentContext())
+ .ToLocalChecked()
+ ->CreationContext());
if (index == -1) return;
args.GetReturnValue().Set(index);
}
@@ -490,15 +488,15 @@ void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
TryCatch try_catch(isolate);
PerIsolateData* data = PerIsolateData::Get(isolate);
- Persistent<Context>* old_realms = data->realms_;
+ Global<Context>* old_realms = data->realms_;
int index = data->realm_count_;
- data->realms_ = new Persistent<Context>[++data->realm_count_];
+ data->realms_ = new Global<Context>[++data->realm_count_];
for (int i = 0; i < index; ++i) {
data->realms_[i].Reset(isolate, old_realms[i]);
old_realms[i].Reset();
}
delete[] old_realms;
- Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
+ Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
Local<Context> context = Context::New(isolate, NULL, global_template);
if (context.IsEmpty()) {
DCHECK(try_catch.HasCaught());
@@ -547,13 +545,20 @@ void Shell::RealmEval(const v8::FunctionCallbackInfo<v8::Value>& args) {
Throw(args.GetIsolate(), "Invalid argument");
return;
}
- ScriptCompiler::Source script_source(args[1]->ToString(isolate));
- Handle<UnboundScript> script = ScriptCompiler::CompileUnbound(
- isolate, &script_source);
- if (script.IsEmpty()) return;
+ ScriptCompiler::Source script_source(
+ args[1]->ToString(isolate->GetCurrentContext()).ToLocalChecked());
+ Local<UnboundScript> script;
+ if (!ScriptCompiler::CompileUnboundScript(isolate, &script_source)
+ .ToLocal(&script)) {
+ return;
+ }
Local<Context> realm = Local<Context>::New(isolate, data->realms_[index]);
realm->Enter();
- Handle<Value> result = script->BindToCurrentContext()->Run();
+ Local<Value> result;
+ if (!script->BindToCurrentContext()->Run(realm).ToLocal(&result)) {
+ realm->Exit();
+ return;
+ }
realm->Exit();
args.GetReturnValue().Set(result);
}
@@ -593,8 +598,10 @@ void Shell::Write(const v8::FunctionCallbackInfo<v8::Value>& args) {
// Explicitly catch potential exceptions in toString().
v8::TryCatch try_catch(args.GetIsolate());
- Handle<String> str_obj = args[i]->ToString(args.GetIsolate());
- if (try_catch.HasCaught()) {
+ Local<String> str_obj;
+ if (!args[i]
+ ->ToString(args.GetIsolate()->GetCurrentContext())
+ .ToLocal(&str_obj)) {
try_catch.ReThrow();
return;
}
@@ -615,7 +622,7 @@ void Shell::Read(const v8::FunctionCallbackInfo<v8::Value>& args) {
Throw(args.GetIsolate(), "Error loading file");
return;
}
- Handle<String> source = ReadFile(args.GetIsolate(), *file);
+ Local<String> source = ReadFile(args.GetIsolate(), *file);
if (source.IsEmpty()) {
Throw(args.GetIsolate(), "Error loading file");
return;
@@ -624,10 +631,11 @@ void Shell::Read(const v8::FunctionCallbackInfo<v8::Value>& args) {
}
-Handle<String> Shell::ReadFromStdin(Isolate* isolate) {
+Local<String> Shell::ReadFromStdin(Isolate* isolate) {
static const int kBufferSize = 256;
char buffer[kBufferSize];
- Handle<String> accumulator = String::NewFromUtf8(isolate, "");
+ Local<String> accumulator =
+ String::NewFromUtf8(isolate, "", NewStringType::kNormal).ToLocalChecked();
int length;
while (true) {
// Continue reading if the line ends with an escape '\\' or the line has
@@ -635,23 +643,26 @@ Handle<String> Shell::ReadFromStdin(Isolate* isolate) {
// If fgets gets an error, just give up.
char* input = NULL;
input = fgets(buffer, kBufferSize, stdin);
- if (input == NULL) return Handle<String>();
+ if (input == NULL) return Local<String>();
length = static_cast<int>(strlen(buffer));
if (length == 0) {
return accumulator;
} else if (buffer[length-1] != '\n') {
accumulator = String::Concat(
accumulator,
- String::NewFromUtf8(isolate, buffer, String::kNormalString, length));
+ String::NewFromUtf8(isolate, buffer, NewStringType::kNormal, length)
+ .ToLocalChecked());
} else if (length > 1 && buffer[length-2] == '\\') {
buffer[length-2] = '\n';
accumulator = String::Concat(
- accumulator, String::NewFromUtf8(isolate, buffer,
- String::kNormalString, length - 1));
+ accumulator,
+ String::NewFromUtf8(isolate, buffer, NewStringType::kNormal,
+ length - 1).ToLocalChecked());
} else {
return String::Concat(
- accumulator, String::NewFromUtf8(isolate, buffer,
- String::kNormalString, length - 1));
+ accumulator,
+ String::NewFromUtf8(isolate, buffer, NewStringType::kNormal,
+ length - 1).ToLocalChecked());
}
}
}
@@ -665,16 +676,16 @@ void Shell::Load(const v8::FunctionCallbackInfo<v8::Value>& args) {
Throw(args.GetIsolate(), "Error loading file");
return;
}
- Handle<String> source = ReadFile(args.GetIsolate(), *file);
+ Local<String> source = ReadFile(args.GetIsolate(), *file);
if (source.IsEmpty()) {
Throw(args.GetIsolate(), "Error loading file");
return;
}
- if (!ExecuteString(args.GetIsolate(),
- source,
- String::NewFromUtf8(args.GetIsolate(), *file),
- false,
- true)) {
+ if (!ExecuteString(
+ args.GetIsolate(), source,
+ String::NewFromUtf8(args.GetIsolate(), *file,
+ NewStringType::kNormal).ToLocalChecked(),
+ false, true)) {
Throw(args.GetIsolate(), "Error executing file");
return;
}
@@ -691,12 +702,27 @@ void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
+ if (!args.IsConstructCall()) {
+ Throw(args.GetIsolate(), "Worker must be constructed with new");
+ return;
+ }
+
{
- base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
+ base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
+ if (workers_.length() >= kMaxWorkers) {
+ Throw(args.GetIsolate(), "Too many workers, I won't let you create more");
+ return;
+ }
+
+ // Initialize the internal field to NULL; if we return early without
+ // creating a new Worker (because the main thread is terminating) we can
+ // early-out from the instance calls.
+ args.Holder()->SetAlignedPointerInInternalField(0, NULL);
+
if (!allow_new_workers_) return;
Worker* worker = new Worker;
- args.This()->SetInternalField(0, External::New(isolate, worker));
+ args.Holder()->SetAlignedPointerInInternalField(0, worker);
workers_.Add(worker);
String::Utf8Value script(args[0]);
@@ -704,7 +730,7 @@ void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args) {
Throw(args.GetIsolate(), "Can't get worker script");
return;
}
- worker->StartExecuteInThread(isolate, *script);
+ worker->StartExecuteInThread(*script);
}
}
@@ -719,16 +745,12 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
- Local<Value> this_value = args.This()->GetInternalField(0);
- if (!this_value->IsExternal()) {
- Throw(isolate, "this is not a Worker");
+ Worker* worker = GetWorkerFromInternalField(isolate, args.Holder());
+ if (!worker) {
return;
}
- Worker* worker =
- static_cast<Worker*>(Local<External>::Cast(this_value)->Value());
-
- Handle<Value> message = args[0];
+ Local<Value> message = args[0];
ObjectList to_transfer;
if (args.Length() >= 2) {
if (!args[1]->IsArray()) {
@@ -736,10 +758,10 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
- Handle<Array> transfer = Handle<Array>::Cast(args[1]);
+ Local<Array> transfer = Local<Array>::Cast(args[1]);
uint32_t length = transfer->Length();
for (uint32_t i = 0; i < length; ++i) {
- Handle<Value> element;
+ Local<Value> element;
if (transfer->Get(context, i).ToLocal(&element)) {
if (!element->IsArrayBuffer() && !element->IsSharedArrayBuffer()) {
Throw(isolate,
@@ -748,7 +770,7 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
break;
}
- to_transfer.Add(Handle<Object>::Cast(element));
+ to_transfer.Add(Local<Object>::Cast(element));
}
}
}
@@ -766,16 +788,11 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope handle_scope(isolate);
-
- Local<Value> this_value = args.This()->GetInternalField(0);
- if (!this_value->IsExternal()) {
- Throw(isolate, "this is not a Worker");
+ Worker* worker = GetWorkerFromInternalField(isolate, args.Holder());
+ if (!worker) {
return;
}
- Worker* worker =
- static_cast<Worker*>(Local<External>::Cast(this_value)->Value());
-
SerializationData* data = worker->GetMessage();
if (data) {
int offset = 0;
@@ -791,36 +808,45 @@ void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo<v8::Value>& args) {
void Shell::WorkerTerminate(const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope handle_scope(isolate);
- Local<Value> this_value = args.This()->GetInternalField(0);
- if (!this_value->IsExternal()) {
- Throw(isolate, "this is not a Worker");
+ Worker* worker = GetWorkerFromInternalField(isolate, args.Holder());
+ if (!worker) {
return;
}
- Worker* worker =
- static_cast<Worker*>(Local<External>::Cast(this_value)->Value());
worker->Terminate();
}
#endif // !V8_SHARED
+void Shell::QuitOnce(v8::FunctionCallbackInfo<v8::Value>* args) {
+ int exit_code = (*args)[0]
+ ->Int32Value(args->GetIsolate()->GetCurrentContext())
+ .FromMaybe(0);
+#ifndef V8_SHARED
+ CleanupWorkers();
+#endif // !V8_SHARED
+ OnExit(args->GetIsolate());
+ Exit(exit_code);
+}
+
+
void Shell::Quit(const v8::FunctionCallbackInfo<v8::Value>& args) {
- int exit_code = args[0]->Int32Value();
- OnExit(args.GetIsolate());
- exit(exit_code);
+ base::CallOnce(&quit_once_, &QuitOnce,
+ const_cast<v8::FunctionCallbackInfo<v8::Value>*>(&args));
}
void Shell::Version(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(
- String::NewFromUtf8(args.GetIsolate(), V8::GetVersion()));
+ String::NewFromUtf8(args.GetIsolate(), V8::GetVersion(),
+ NewStringType::kNormal).ToLocalChecked());
}
void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
HandleScope handle_scope(isolate);
#ifndef V8_SHARED
- Handle<Context> utility_context;
+ Local<Context> utility_context;
bool enter_context = !isolate->InContext();
if (enter_context) {
utility_context = Local<Context>::New(isolate, utility_context_);
@@ -829,7 +855,7 @@ void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
#endif // !V8_SHARED
v8::String::Utf8Value exception(try_catch->Exception());
const char* exception_string = ToCString(exception);
- Handle<Message> message = try_catch->Message();
+ Local<Message> message = try_catch->Message();
if (message.IsEmpty()) {
// V8 didn't provide any extra information about this error; just
// print the exception.
@@ -838,26 +864,32 @@ void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
// Print (filename):(line number): (message).
v8::String::Utf8Value filename(message->GetScriptOrigin().ResourceName());
const char* filename_string = ToCString(filename);
- int linenum = message->GetLineNumber();
+ int linenum =
+ message->GetLineNumber(isolate->GetCurrentContext()).FromJust();
printf("%s:%i: %s\n", filename_string, linenum, exception_string);
// Print line of source code.
- v8::String::Utf8Value sourceline(message->GetSourceLine());
+ v8::String::Utf8Value sourceline(
+ message->GetSourceLine(isolate->GetCurrentContext()).ToLocalChecked());
const char* sourceline_string = ToCString(sourceline);
printf("%s\n", sourceline_string);
// Print wavy underline (GetUnderline is deprecated).
- int start = message->GetStartColumn();
+ int start =
+ message->GetStartColumn(isolate->GetCurrentContext()).FromJust();
for (int i = 0; i < start; i++) {
printf(" ");
}
- int end = message->GetEndColumn();
+ int end = message->GetEndColumn(isolate->GetCurrentContext()).FromJust();
for (int i = start; i < end; i++) {
printf("^");
}
printf("\n");
- v8::String::Utf8Value stack_trace(try_catch->StackTrace());
- if (stack_trace.length() > 0) {
- const char* stack_trace_string = ToCString(stack_trace);
- printf("%s\n", stack_trace_string);
+ Local<Value> stack_trace_string;
+ if (try_catch->StackTrace(isolate->GetCurrentContext())
+ .ToLocal(&stack_trace_string) &&
+ stack_trace_string->IsString()) {
+ v8::String::Utf8Value stack_trace(
+ Local<String>::Cast(stack_trace_string));
+ printf("%s\n", ToCString(stack_trace));
}
}
printf("\n");
@@ -868,57 +900,6 @@ void Shell::ReportException(Isolate* isolate, v8::TryCatch* try_catch) {
#ifndef V8_SHARED
-Handle<Array> Shell::GetCompletions(Isolate* isolate,
- Handle<String> text,
- Handle<String> full) {
- EscapableHandleScope handle_scope(isolate);
- v8::Local<v8::Context> utility_context =
- v8::Local<v8::Context>::New(isolate, utility_context_);
- v8::Context::Scope context_scope(utility_context);
- Handle<Object> global = utility_context->Global();
- Local<Value> fun =
- global->Get(String::NewFromUtf8(isolate, "GetCompletions"));
- static const int kArgc = 3;
- v8::Local<v8::Context> evaluation_context =
- v8::Local<v8::Context>::New(isolate, evaluation_context_);
- Handle<Value> argv[kArgc] = { evaluation_context->Global(), text, full };
- Local<Value> val = Local<Function>::Cast(fun)->Call(global, kArgc, argv);
- return handle_scope.Escape(Local<Array>::Cast(val));
-}
-
-
-Local<Object> Shell::DebugMessageDetails(Isolate* isolate,
- Handle<String> message) {
- EscapableHandleScope handle_scope(isolate);
- v8::Local<v8::Context> context =
- v8::Local<v8::Context>::New(isolate, utility_context_);
- v8::Context::Scope context_scope(context);
- Handle<Object> global = context->Global();
- Handle<Value> fun =
- global->Get(String::NewFromUtf8(isolate, "DebugMessageDetails"));
- static const int kArgc = 1;
- Handle<Value> argv[kArgc] = { message };
- Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
- return handle_scope.Escape(Local<Object>(Handle<Object>::Cast(val)));
-}
-
-
-Local<Value> Shell::DebugCommandToJSONRequest(Isolate* isolate,
- Handle<String> command) {
- EscapableHandleScope handle_scope(isolate);
- v8::Local<v8::Context> context =
- v8::Local<v8::Context>::New(isolate, utility_context_);
- v8::Context::Scope context_scope(context);
- Handle<Object> global = context->Global();
- Handle<Value> fun =
- global->Get(String::NewFromUtf8(isolate, "DebugCommandToJSONRequest"));
- static const int kArgc = 1;
- Handle<Value> argv[kArgc] = { command };
- Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
- return handle_scope.Escape(Local<Value>(val));
-}
-
-
int32_t* Counter::Bind(const char* name, bool is_histogram) {
int i;
for (i = 0; i < kMaxNameSize - 1 && name[i]; i++)
@@ -1034,6 +1015,8 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
HandleScope scope(isolate);
// If we use the utility context, we have to set the security tokens so that
// utility, evaluation and debug context can all access each other.
+ Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
+ utility_context_.Reset(isolate, Context::New(isolate, NULL, global_template));
v8::Local<v8::Context> utility_context =
v8::Local<v8::Context>::New(isolate, utility_context_);
v8::Local<v8::Context> evaluation_context =
@@ -1042,33 +1025,23 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
evaluation_context->SetSecurityToken(Undefined(isolate));
v8::Context::Scope context_scope(utility_context);
- if (i::FLAG_debugger) printf("JavaScript debugger enabled\n");
- // Install the debugger object in the utility scope
- i::Debug* debug = reinterpret_cast<i::Isolate*>(isolate)->debug();
- debug->Load();
- i::Handle<i::Context> debug_context = debug->debug_context();
- i::Handle<i::JSObject> js_debug
- = i::Handle<i::JSObject>(debug_context->global_object());
- utility_context->Global()->Set(String::NewFromUtf8(isolate, "$debug"),
- Utils::ToLocal(js_debug));
- debug_context->set_security_token(
- reinterpret_cast<i::Isolate*>(isolate)->heap()->undefined_value());
-
// Run the d8 shell utility script in the utility context
int source_index = i::NativesCollection<i::D8>::GetIndex("d8");
i::Vector<const char> shell_source =
i::NativesCollection<i::D8>::GetScriptSource(source_index);
i::Vector<const char> shell_source_name =
i::NativesCollection<i::D8>::GetScriptName(source_index);
- Handle<String> source =
- String::NewFromUtf8(isolate, shell_source.start(), String::kNormalString,
- shell_source.length());
- Handle<String> name =
+ Local<String> source =
+ String::NewFromUtf8(isolate, shell_source.start(), NewStringType::kNormal,
+ shell_source.length()).ToLocalChecked();
+ Local<String> name =
String::NewFromUtf8(isolate, shell_source_name.start(),
- String::kNormalString, shell_source_name.length());
+ NewStringType::kNormal,
+ shell_source_name.length()).ToLocalChecked();
ScriptOrigin origin(name);
- Handle<Script> script = Script::Compile(source, &origin);
- script->Run();
+ Local<Script> script =
+ Script::Compile(utility_context, source, &origin).ToLocalChecked();
+ script->Run(utility_context).ToLocalChecked();
// Mark the d8 shell script as native to avoid it showing up as normal source
// in the debugger.
i::Handle<i::Object> compiled_script = Utils::OpenHandle(*script);
@@ -1078,83 +1051,141 @@ void Shell::InstallUtilityScript(Isolate* isolate) {
: i::Handle<i::Script>(i::Script::cast(
i::SharedFunctionInfo::cast(*compiled_script)->script()));
script_object->set_type(i::Smi::FromInt(i::Script::TYPE_NATIVE));
-
- // Start the in-process debugger if requested.
- if (i::FLAG_debugger) v8::Debug::SetDebugEventListener(HandleDebugEvent);
}
#endif // !V8_SHARED
-Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
- Handle<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
- global_template->Set(String::NewFromUtf8(isolate, "print"),
- FunctionTemplate::New(isolate, Print));
- global_template->Set(String::NewFromUtf8(isolate, "write"),
- FunctionTemplate::New(isolate, Write));
- global_template->Set(String::NewFromUtf8(isolate, "read"),
- FunctionTemplate::New(isolate, Read));
- global_template->Set(String::NewFromUtf8(isolate, "readbuffer"),
- FunctionTemplate::New(isolate, ReadBuffer));
- global_template->Set(String::NewFromUtf8(isolate, "readline"),
- FunctionTemplate::New(isolate, ReadLine));
- global_template->Set(String::NewFromUtf8(isolate, "load"),
- FunctionTemplate::New(isolate, Load));
+Local<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) {
+ Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
+ global_template->Set(
+ String::NewFromUtf8(isolate, "print", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, Print));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "write", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, Write));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "read", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, Read));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "readbuffer", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, ReadBuffer));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "readline", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, ReadLine));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "load", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, Load));
// Some Emscripten-generated code tries to call 'quit', which in turn would
// call C's exit(). This would lead to memory leaks, because there is no way
// we can terminate cleanly then, so we need a way to hide 'quit'.
if (!options.omit_quit) {
- global_template->Set(String::NewFromUtf8(isolate, "quit"),
- FunctionTemplate::New(isolate, Quit));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "quit", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, Quit));
}
- global_template->Set(String::NewFromUtf8(isolate, "version"),
- FunctionTemplate::New(isolate, Version));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "version", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, Version));
// Bind the Realm object.
- Handle<ObjectTemplate> realm_template = ObjectTemplate::New(isolate);
- realm_template->Set(String::NewFromUtf8(isolate, "current"),
- FunctionTemplate::New(isolate, RealmCurrent));
- realm_template->Set(String::NewFromUtf8(isolate, "owner"),
- FunctionTemplate::New(isolate, RealmOwner));
- realm_template->Set(String::NewFromUtf8(isolate, "global"),
- FunctionTemplate::New(isolate, RealmGlobal));
- realm_template->Set(String::NewFromUtf8(isolate, "create"),
- FunctionTemplate::New(isolate, RealmCreate));
- realm_template->Set(String::NewFromUtf8(isolate, "dispose"),
- FunctionTemplate::New(isolate, RealmDispose));
- realm_template->Set(String::NewFromUtf8(isolate, "switch"),
- FunctionTemplate::New(isolate, RealmSwitch));
- realm_template->Set(String::NewFromUtf8(isolate, "eval"),
- FunctionTemplate::New(isolate, RealmEval));
- realm_template->SetAccessor(String::NewFromUtf8(isolate, "shared"),
- RealmSharedGet, RealmSharedSet);
- global_template->Set(String::NewFromUtf8(isolate, "Realm"), realm_template);
+ Local<ObjectTemplate> realm_template = ObjectTemplate::New(isolate);
+ realm_template->Set(
+ String::NewFromUtf8(isolate, "current", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, RealmCurrent));
+ realm_template->Set(
+ String::NewFromUtf8(isolate, "owner", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, RealmOwner));
+ realm_template->Set(
+ String::NewFromUtf8(isolate, "global", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, RealmGlobal));
+ realm_template->Set(
+ String::NewFromUtf8(isolate, "create", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, RealmCreate));
+ realm_template->Set(
+ String::NewFromUtf8(isolate, "dispose", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, RealmDispose));
+ realm_template->Set(
+ String::NewFromUtf8(isolate, "switch", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, RealmSwitch));
+ realm_template->Set(
+ String::NewFromUtf8(isolate, "eval", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, RealmEval));
+ realm_template->SetAccessor(
+ String::NewFromUtf8(isolate, "shared", NewStringType::kNormal)
+ .ToLocalChecked(),
+ RealmSharedGet, RealmSharedSet);
+ global_template->Set(
+ String::NewFromUtf8(isolate, "Realm", NewStringType::kNormal)
+ .ToLocalChecked(),
+ realm_template);
#ifndef V8_SHARED
- Handle<ObjectTemplate> performance_template = ObjectTemplate::New(isolate);
- performance_template->Set(String::NewFromUtf8(isolate, "now"),
- FunctionTemplate::New(isolate, PerformanceNow));
- global_template->Set(String::NewFromUtf8(isolate, "performance"),
- performance_template);
-
- Handle<FunctionTemplate> worker_fun_template =
+ Local<ObjectTemplate> performance_template = ObjectTemplate::New(isolate);
+ performance_template->Set(
+ String::NewFromUtf8(isolate, "now", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, PerformanceNow));
+ global_template->Set(
+ String::NewFromUtf8(isolate, "performance", NewStringType::kNormal)
+ .ToLocalChecked(),
+ performance_template);
+
+ Local<FunctionTemplate> worker_fun_template =
FunctionTemplate::New(isolate, WorkerNew);
+ Local<Signature> worker_signature =
+ Signature::New(isolate, worker_fun_template);
+ worker_fun_template->SetClassName(
+ String::NewFromUtf8(isolate, "Worker", NewStringType::kNormal)
+ .ToLocalChecked());
+ worker_fun_template->ReadOnlyPrototype();
worker_fun_template->PrototypeTemplate()->Set(
- String::NewFromUtf8(isolate, "terminate"),
- FunctionTemplate::New(isolate, WorkerTerminate));
+ String::NewFromUtf8(isolate, "terminate", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, WorkerTerminate, Local<Value>(),
+ worker_signature));
worker_fun_template->PrototypeTemplate()->Set(
- String::NewFromUtf8(isolate, "postMessage"),
- FunctionTemplate::New(isolate, WorkerPostMessage));
+ String::NewFromUtf8(isolate, "postMessage", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, WorkerPostMessage, Local<Value>(),
+ worker_signature));
worker_fun_template->PrototypeTemplate()->Set(
- String::NewFromUtf8(isolate, "getMessage"),
- FunctionTemplate::New(isolate, WorkerGetMessage));
+ String::NewFromUtf8(isolate, "getMessage", NewStringType::kNormal)
+ .ToLocalChecked(),
+ FunctionTemplate::New(isolate, WorkerGetMessage, Local<Value>(),
+ worker_signature));
worker_fun_template->InstanceTemplate()->SetInternalFieldCount(1);
- global_template->Set(String::NewFromUtf8(isolate, "Worker"),
- worker_fun_template);
+ global_template->Set(
+ String::NewFromUtf8(isolate, "Worker", NewStringType::kNormal)
+ .ToLocalChecked(),
+ worker_fun_template);
#endif // !V8_SHARED
- Handle<ObjectTemplate> os_templ = ObjectTemplate::New(isolate);
+ Local<ObjectTemplate> os_templ = ObjectTemplate::New(isolate);
AddOSMethods(isolate, os_templ);
- global_template->Set(String::NewFromUtf8(isolate, "os"), os_templ);
+ global_template->Set(
+ String::NewFromUtf8(isolate, "os", NewStringType::kNormal)
+ .ToLocalChecked(),
+ os_templ);
+
+#if defined(V8_WASM)
+ // Install WASM API.
+ WasmJs::Install(isolate, global_template);
+#endif
return global_template;
}
@@ -1169,28 +1200,13 @@ void Shell::Initialize(Isolate* isolate) {
}
-void Shell::InitializeDebugger(Isolate* isolate) {
- if (options.test_shell) return;
-#ifndef V8_SHARED
- HandleScope scope(isolate);
- Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
- utility_context_.Reset(isolate,
- Context::New(isolate, NULL, global_template));
- if (utility_context_.IsEmpty()) {
- printf("Failed to initialize debugger\n");
- Shell::Exit(1);
- }
-#endif // !V8_SHARED
-}
-
-
Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
#ifndef V8_SHARED
// This needs to be a critical section since this is not thread-safe
- base::LockGuard<base::Mutex> lock_guard(&context_mutex_);
+ base::LockGuard<base::Mutex> lock_guard(context_mutex_.Pointer());
#endif // !V8_SHARED
// Initialize the global objects
- Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
+ Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
EscapableHandleScope handle_scope(isolate);
Local<Context> context = Context::New(isolate, NULL, global_template);
DCHECK(!context.IsEmpty());
@@ -1208,8 +1224,12 @@ Local<Context> Shell::CreateEvaluationContext(Isolate* isolate) {
}
i::Handle<i::JSArray> arguments_jsarray =
factory->NewJSArrayWithElements(arguments_array);
- context->Global()->Set(String::NewFromUtf8(isolate, "arguments"),
- Utils::ToLocal(arguments_jsarray));
+ context->Global()
+ ->Set(context,
+ String::NewFromUtf8(isolate, "arguments", NewStringType::kNormal)
+ .ToLocalChecked(),
+ Utils::ToLocal(arguments_jsarray))
+ .FromJust();
#endif // !V8_SHARED
return handle_scope.Escape(context);
}
@@ -1238,8 +1258,6 @@ inline bool operator<(const CounterAndKey& lhs, const CounterAndKey& rhs) {
void Shell::OnExit(v8::Isolate* isolate) {
- LineEditor* line_editor = LineEditor::Get();
- if (line_editor) line_editor->Close();
#ifndef V8_SHARED
reinterpret_cast<i::Isolate*>(isolate)->DumpAndResetCompilationStats();
if (i::FLAG_dump_counters) {
@@ -1364,8 +1382,7 @@ void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
data->byte_length = length;
- Handle<v8::ArrayBuffer> buffer =
- ArrayBuffer::New(isolate, data->data, length);
+ Local<v8::ArrayBuffer> buffer = ArrayBuffer::New(isolate, data->data, length);
data->handle.Reset(isolate, buffer);
data->handle.SetWeak(data, ReadBufferWeakCallback,
v8::WeakCallbackType::kParameter);
@@ -1377,12 +1394,13 @@ void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
// Reads a file into a v8 string.
-Handle<String> Shell::ReadFile(Isolate* isolate, const char* name) {
+Local<String> Shell::ReadFile(Isolate* isolate, const char* name) {
int size = 0;
char* chars = ReadChars(isolate, name, &size);
- if (chars == NULL) return Handle<String>();
- Handle<String> result =
- String::NewFromUtf8(isolate, chars, String::kNormalString, size);
+ if (chars == NULL) return Local<String>();
+ Local<String> result =
+ String::NewFromUtf8(isolate, chars, NewStringType::kNormal, size)
+ .ToLocalChecked();
delete[] chars;
return result;
}
@@ -1394,13 +1412,19 @@ void Shell::RunShell(Isolate* isolate) {
v8::Local<v8::Context>::New(isolate, evaluation_context_);
v8::Context::Scope context_scope(context);
PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
- Handle<String> name = String::NewFromUtf8(isolate, "(d8)");
- LineEditor* console = LineEditor::Get();
- printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
- console->Open(isolate);
+ Local<String> name =
+ String::NewFromUtf8(isolate, "(d8)", NewStringType::kNormal)
+ .ToLocalChecked();
+ printf("V8 version %s\n", V8::GetVersion());
while (true) {
HandleScope inner_scope(isolate);
- Handle<String> input = console->Prompt(Shell::kPrompt);
+ printf("d8> ");
+#if defined(__native_client__)
+ // Native Client libc is used to being embedded in Chrome and
+ // has trouble recognizing when to flush.
+ fflush(stdout);
+#endif
+ Local<String> input = Shell::ReadFromStdin(isolate);
if (input.IsEmpty()) break;
ExecuteString(isolate, input, name, true, true);
}
@@ -1424,8 +1448,13 @@ void SourceGroup::Execute(Isolate* isolate) {
if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) {
// Execute argument given to -e option directly.
HandleScope handle_scope(isolate);
- Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed");
- Handle<String> source = String::NewFromUtf8(isolate, argv_[i + 1]);
+ Local<String> file_name =
+ String::NewFromUtf8(isolate, "unnamed", NewStringType::kNormal)
+ .ToLocalChecked();
+ Local<String> source =
+ String::NewFromUtf8(isolate, argv_[i + 1], NewStringType::kNormal)
+ .ToLocalChecked();
+ Shell::options.script_executed = true;
if (!Shell::ExecuteString(isolate, source, file_name, false, true)) {
exception_was_thrown = true;
break;
@@ -1443,12 +1472,15 @@ void SourceGroup::Execute(Isolate* isolate) {
// Use all other arguments as names of files to load and run.
HandleScope handle_scope(isolate);
- Handle<String> file_name = String::NewFromUtf8(isolate, arg);
- Handle<String> source = ReadFile(isolate, arg);
+ Local<String> file_name =
+ String::NewFromUtf8(isolate, arg, NewStringType::kNormal)
+ .ToLocalChecked();
+ Local<String> source = ReadFile(isolate, arg);
if (source.IsEmpty()) {
printf("Error reading '%s'\n", arg);
Shell::Exit(1);
}
+ Shell::options.script_executed = true;
if (!Shell::ExecuteString(isolate, source, file_name, false, true,
source_type)) {
exception_was_thrown = true;
@@ -1461,12 +1493,13 @@ void SourceGroup::Execute(Isolate* isolate) {
}
-Handle<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) {
+Local<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) {
int size;
char* chars = ReadChars(isolate, name, &size);
- if (chars == NULL) return Handle<String>();
- Handle<String> result =
- String::NewFromUtf8(isolate, chars, String::kNormalString, size);
+ if (chars == NULL) return Local<String>();
+ Local<String> result =
+ String::NewFromUtf8(isolate, chars, NewStringType::kNormal, size)
+ .ToLocalChecked();
delete[] chars;
return result;
}
@@ -1486,7 +1519,7 @@ void SourceGroup::ExecuteInThread() {
Isolate::CreateParams create_params;
create_params.array_buffer_allocator = Shell::array_buffer_allocator;
Isolate* isolate = Isolate::New(create_params);
- do {
+ for (int i = 0; i < Shell::options.stress_runs; ++i) {
next_semaphore_.Wait();
{
Isolate::Scope iscope(isolate);
@@ -1503,7 +1536,7 @@ void SourceGroup::ExecuteInThread() {
Shell::CollectGarbage(isolate);
}
done_semaphore_.Signal();
- } while (!Shell::options.last_run);
+ }
isolate->Dispose();
}
@@ -1520,31 +1553,37 @@ void SourceGroup::StartExecuteInThread() {
void SourceGroup::WaitForThread() {
if (thread_ == NULL) return;
- if (Shell::options.last_run) {
- thread_->Join();
- } else {
- done_semaphore_.Wait();
- }
+ done_semaphore_.Wait();
+}
+
+
+void SourceGroup::JoinThread() {
+ if (thread_ == NULL) return;
+ thread_->Join();
}
SerializationData::~SerializationData() {
- // Any ArrayBuffer::Contents are owned by this SerializationData object.
- // SharedArrayBuffer::Contents may be used by other threads, so must be
+ // Any ArrayBuffer::Contents are owned by this SerializationData object if
+ // ownership hasn't been transferred out via ReadArrayBufferContents.
+ // SharedArrayBuffer::Contents may be used by multiple threads, so must be
// cleaned up by the main thread in Shell::CleanupWorkers().
- for (int i = 0; i < array_buffer_contents.length(); ++i) {
- ArrayBuffer::Contents& contents = array_buffer_contents[i];
- Shell::array_buffer_allocator->Free(contents.Data(), contents.ByteLength());
+ for (int i = 0; i < array_buffer_contents_.length(); ++i) {
+ ArrayBuffer::Contents& contents = array_buffer_contents_[i];
+ if (contents.Data()) {
+ Shell::array_buffer_allocator->Free(contents.Data(),
+ contents.ByteLength());
+ }
}
}
-void SerializationData::WriteTag(SerializationTag tag) { data.Add(tag); }
+void SerializationData::WriteTag(SerializationTag tag) { data_.Add(tag); }
void SerializationData::WriteMemory(const void* p, int length) {
if (length > 0) {
- i::Vector<uint8_t> block = data.AddBlock(0, length);
+ i::Vector<uint8_t> block = data_.AddBlock(0, length);
memcpy(&block[0], p, length);
}
}
@@ -1552,18 +1591,18 @@ void SerializationData::WriteMemory(const void* p, int length) {
void SerializationData::WriteArrayBufferContents(
const ArrayBuffer::Contents& contents) {
- array_buffer_contents.Add(contents);
+ array_buffer_contents_.Add(contents);
WriteTag(kSerializationTagTransferredArrayBuffer);
- int index = array_buffer_contents.length() - 1;
+ int index = array_buffer_contents_.length() - 1;
Write(index);
}
void SerializationData::WriteSharedArrayBufferContents(
const SharedArrayBuffer::Contents& contents) {
- shared_array_buffer_contents.Add(contents);
+ shared_array_buffer_contents_.Add(contents);
WriteTag(kSerializationTagTransferredSharedArrayBuffer);
- int index = shared_array_buffer_contents.length() - 1;
+ int index = shared_array_buffer_contents_.length() - 1;
Write(index);
}
@@ -1575,7 +1614,7 @@ SerializationTag SerializationData::ReadTag(int* offset) const {
void SerializationData::ReadMemory(void* p, int length, int* offset) const {
if (length > 0) {
- memcpy(p, &data[*offset], length);
+ memcpy(p, &data_[*offset], length);
(*offset) += length;
}
}
@@ -1584,16 +1623,20 @@ void SerializationData::ReadMemory(void* p, int length, int* offset) const {
void SerializationData::ReadArrayBufferContents(ArrayBuffer::Contents* contents,
int* offset) const {
int index = Read<int>(offset);
- DCHECK(index < array_buffer_contents.length());
- *contents = array_buffer_contents[index];
+ DCHECK(index < array_buffer_contents_.length());
+ *contents = array_buffer_contents_[index];
+ // Ownership of this ArrayBuffer::Contents is passed to the caller. Neuter
+ // our copy so it won't be double-free'd when this SerializationData is
+ // destroyed.
+ array_buffer_contents_[index] = ArrayBuffer::Contents();
}
void SerializationData::ReadSharedArrayBufferContents(
SharedArrayBuffer::Contents* contents, int* offset) const {
int index = Read<int>(offset);
- DCHECK(index < shared_array_buffer_contents.length());
- *contents = shared_array_buffer_contents[index];
+ DCHECK(index < shared_array_buffer_contents_.length());
+ *contents = shared_array_buffer_contents_[index];
}
@@ -1605,6 +1648,7 @@ void SerializationDataQueue::Enqueue(SerializationData* data) {
bool SerializationDataQueue::Dequeue(SerializationData** data) {
base::LockGuard<base::Mutex> lock_guard(&mutex_);
+ *data = NULL;
if (data_.is_empty()) return false;
*data = data_.Remove(0);
return true;
@@ -1631,21 +1675,24 @@ Worker::Worker()
out_semaphore_(0),
thread_(NULL),
script_(NULL),
- state_(IDLE) {}
+ running_(false) {}
-Worker::~Worker() { Cleanup(); }
+Worker::~Worker() {
+ delete thread_;
+ thread_ = NULL;
+ delete[] script_;
+ script_ = NULL;
+ in_queue_.Clear();
+ out_queue_.Clear();
+}
-void Worker::StartExecuteInThread(Isolate* isolate, const char* script) {
- if (base::NoBarrier_CompareAndSwap(&state_, IDLE, RUNNING) == IDLE) {
- script_ = i::StrDup(script);
- thread_ = new WorkerThread(this);
- thread_->Start();
- } else {
- // Somehow the Worker was started twice.
- UNREACHABLE();
- }
+void Worker::StartExecuteInThread(const char* script) {
+ running_ = true;
+ script_ = i::StrDup(script);
+ thread_ = new WorkerThread(this);
+ thread_->Start();
}
@@ -1658,20 +1705,26 @@ void Worker::PostMessage(SerializationData* data) {
SerializationData* Worker::GetMessage() {
SerializationData* data = NULL;
while (!out_queue_.Dequeue(&data)) {
- if (base::NoBarrier_Load(&state_) != RUNNING) break;
+ // If the worker is no longer running, and there are no messages in the
+ // queue, don't expect any more messages from it.
+ if (!base::NoBarrier_Load(&running_)) break;
out_semaphore_.Wait();
}
-
return data;
}
void Worker::Terminate() {
- if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) {
- // Post NULL to wake the Worker thread message loop.
- PostMessage(NULL);
- thread_->Join();
- }
+ base::NoBarrier_Store(&running_, false);
+ // Post NULL to wake the Worker thread message loop, and tell it to stop
+ // running.
+ PostMessage(NULL);
+}
+
+
+void Worker::WaitForThread() {
+ Terminate();
+ thread_->Join();
}
@@ -1689,42 +1742,48 @@ void Worker::ExecuteInThread() {
Context::Scope cscope(context);
PerIsolateData::RealmScope realm_scope(PerIsolateData::Get(isolate));
- Handle<Object> global = context->Global();
- Handle<Value> this_value = External::New(isolate, this);
- Handle<FunctionTemplate> postmessage_fun_template =
+ Local<Object> global = context->Global();
+ Local<Value> this_value = External::New(isolate, this);
+ Local<FunctionTemplate> postmessage_fun_template =
FunctionTemplate::New(isolate, PostMessageOut, this_value);
- Handle<Function> postmessage_fun;
+ Local<Function> postmessage_fun;
if (postmessage_fun_template->GetFunction(context)
.ToLocal(&postmessage_fun)) {
- global->Set(String::NewFromUtf8(isolate, "postMessage"),
- postmessage_fun);
+ global->Set(context, String::NewFromUtf8(isolate, "postMessage",
+ NewStringType::kNormal)
+ .ToLocalChecked(),
+ postmessage_fun).FromJust();
}
// First run the script
- Handle<String> file_name = String::NewFromUtf8(isolate, "unnamed");
- Handle<String> source = String::NewFromUtf8(isolate, script_);
+ Local<String> file_name =
+ String::NewFromUtf8(isolate, "unnamed", NewStringType::kNormal)
+ .ToLocalChecked();
+ Local<String> source =
+ String::NewFromUtf8(isolate, script_, NewStringType::kNormal)
+ .ToLocalChecked();
if (Shell::ExecuteString(isolate, source, file_name, false, true)) {
// Get the message handler
- Handle<Value> onmessage =
- global->Get(String::NewFromUtf8(isolate, "onmessage"));
+ Local<Value> onmessage =
+ global->Get(context, String::NewFromUtf8(isolate, "onmessage",
+ NewStringType::kNormal)
+ .ToLocalChecked()).ToLocalChecked();
if (onmessage->IsFunction()) {
- Handle<Function> onmessage_fun = Handle<Function>::Cast(onmessage);
+ Local<Function> onmessage_fun = Local<Function>::Cast(onmessage);
// Now wait for messages
- bool done = false;
- while (!done) {
+ while (true) {
in_semaphore_.Wait();
SerializationData* data;
if (!in_queue_.Dequeue(&data)) continue;
if (data == NULL) {
- done = true;
break;
}
int offset = 0;
Local<Value> data_value;
if (Shell::DeserializeValue(isolate, *data, &offset)
.ToLocal(&data_value)) {
- Handle<Value> argv[] = {data_value};
+ Local<Value> argv[] = {data_value};
(void)onmessage_fun->Call(context, global, 1, argv);
}
delete data;
@@ -1737,21 +1796,9 @@ void Worker::ExecuteInThread() {
}
isolate->Dispose();
- if (base::NoBarrier_CompareAndSwap(&state_, RUNNING, TERMINATED) == RUNNING) {
- // Post NULL to wake the thread waiting on GetMessage() if there is one.
- out_queue_.Enqueue(NULL);
- out_semaphore_.Signal();
- }
-}
-
-
-void Worker::Cleanup() {
- delete thread_;
- thread_ = NULL;
- delete[] script_;
- script_ = NULL;
- in_queue_.Clear();
- out_queue_.Clear();
+ // Post NULL to wake the thread waiting on GetMessage() if there is one.
+ out_queue_.Enqueue(NULL);
+ out_semaphore_.Signal();
}
@@ -1764,7 +1811,7 @@ void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& args) {
return;
}
- Handle<Value> message = args[0];
+ Local<Value> message = args[0];
// TODO(binji): Allow transferring from worker to main thread?
Shell::ObjectList to_transfer;
@@ -1774,7 +1821,7 @@ void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& args) {
if (Shell::SerializeValue(isolate, message, to_transfer, &seen_objects,
data)) {
DCHECK(args.Data()->IsExternal());
- Handle<External> this_value = Handle<External>::Cast(args.Data());
+ Local<External> this_value = Local<External>::Cast(args.Data());
Worker* worker = static_cast<Worker*>(this_value->Value());
worker->out_queue_.Enqueue(data);
worker->out_semaphore_.Signal();
@@ -1861,9 +1908,6 @@ bool Shell::SetOptions(int argc, char* argv[]) {
} 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], "--debugger") == 0) {
- printf("Javascript debugger not included\n");
- return false;
#endif // V8_SHARED
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
} else if (strncmp(argv[i], "--natives_blob=", 15) == 0) {
@@ -1909,6 +1953,11 @@ bool Shell::SetOptions(int argc, char* argv[]) {
enable_harmony_modules = true;
} else if (strncmp(argv[i], "--", 2) == 0) {
printf("Warning: unknown flag %s.\nTry --help for options\n", argv[i]);
+ } else if (strcmp(str, "-e") == 0 && i + 1 < argc) {
+ options.script_executed = true;
+ } else if (strncmp(str, "-", 1) != 0) {
+ // Not a flag, so it must be a script to execute.
+ options.script_executed = true;
}
}
current->End(argc);
@@ -1925,7 +1974,7 @@ bool Shell::SetOptions(int argc, char* argv[]) {
}
-int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
+int Shell::RunMain(Isolate* isolate, int argc, char* argv[], bool last_run) {
#ifndef V8_SHARED
for (int i = 1; i < options.num_isolates; ++i) {
options.isolate_sources[i].StartExecuteInThread();
@@ -1934,16 +1983,9 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
{
HandleScope scope(isolate);
Local<Context> context = CreateEvaluationContext(isolate);
- if (options.last_run && options.use_interactive_shell()) {
+ if (last_run && options.use_interactive_shell()) {
// Keep using the same context in the interactive shell.
evaluation_context_.Reset(isolate, context);
-#ifndef V8_SHARED
- // If the interactive debugger is enabled make sure to activate
- // it before running the files passed on the command line.
- if (i::FLAG_debugger) {
- InstallUtilityScript(isolate);
- }
-#endif // !V8_SHARED
}
{
Context::Scope cscope(context);
@@ -1954,7 +1996,11 @@ int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) {
CollectGarbage(isolate);
#ifndef V8_SHARED
for (int i = 1; i < options.num_isolates; ++i) {
- options.isolate_sources[i].WaitForThread();
+ if (last_run) {
+ options.isolate_sources[i].JoinThread();
+ } else {
+ options.isolate_sources[i].WaitForThread();
+ }
}
CleanupWorkers();
#endif // !V8_SHARED
@@ -1978,8 +2024,13 @@ void Shell::CollectGarbage(Isolate* isolate) {
}
+void Shell::EmptyMessageQueues(Isolate* isolate) {
+ while (v8::platform::PumpMessageLoop(g_platform, isolate)) continue;
+}
+
+
#ifndef V8_SHARED
-bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
+bool Shell::SerializeValue(Isolate* isolate, Local<Value> value,
const ObjectList& to_transfer,
ObjectList* seen_objects,
SerializationData* out_data) {
@@ -1995,7 +2046,7 @@ bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
} else if (value->IsFalse()) {
out_data->WriteTag(kSerializationTagFalse);
} else if (value->IsNumber()) {
- Handle<Number> num = Handle<Number>::Cast(value);
+ Local<Number> num = Local<Number>::Cast(value);
double value = num->Value();
out_data->WriteTag(kSerializationTagNumber);
out_data->Write(value);
@@ -2005,7 +2056,7 @@ bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
out_data->Write(str.length());
out_data->WriteMemory(*str, str.length());
} else if (value->IsArray()) {
- Handle<Array> array = Handle<Array>::Cast(value);
+ Local<Array> array = Local<Array>::Cast(value);
if (FindInObjectList(array, *seen_objects)) {
Throw(isolate, "Duplicated arrays not supported");
return false;
@@ -2020,10 +2071,13 @@ bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
if (!SerializeValue(isolate, element_value, to_transfer, seen_objects,
out_data))
return false;
+ } else {
+ Throw(isolate, "Failed to serialize array element.");
+ return false;
}
}
} else if (value->IsArrayBuffer()) {
- Handle<ArrayBuffer> array_buffer = Handle<ArrayBuffer>::Cast(value);
+ Local<ArrayBuffer> array_buffer = Local<ArrayBuffer>::Cast(value);
if (FindInObjectList(array_buffer, *seen_objects)) {
Throw(isolate, "Duplicated array buffers not supported");
return false;
@@ -2036,25 +2090,26 @@ bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
return false;
}
- ArrayBuffer::Contents contents = array_buffer->Externalize();
+ ArrayBuffer::Contents contents = array_buffer->IsExternal()
+ ? array_buffer->GetContents()
+ : array_buffer->Externalize();
array_buffer->Neuter();
out_data->WriteArrayBufferContents(contents);
} else {
ArrayBuffer::Contents contents = array_buffer->GetContents();
// Clone ArrayBuffer
- if (contents.ByteLength() > i::kMaxUInt32) {
+ if (contents.ByteLength() > i::kMaxInt) {
Throw(isolate, "ArrayBuffer is too big to clone");
return false;
}
- int byte_length = static_cast<int>(contents.ByteLength());
+ int32_t byte_length = static_cast<int32_t>(contents.ByteLength());
out_data->WriteTag(kSerializationTagArrayBuffer);
out_data->Write(byte_length);
- out_data->WriteMemory(contents.Data(),
- static_cast<int>(contents.ByteLength()));
+ out_data->WriteMemory(contents.Data(), byte_length);
}
} else if (value->IsSharedArrayBuffer()) {
- Handle<SharedArrayBuffer> sab = Handle<SharedArrayBuffer>::Cast(value);
+ Local<SharedArrayBuffer> sab = Local<SharedArrayBuffer>::Cast(value);
if (FindInObjectList(sab, *seen_objects)) {
Throw(isolate, "Duplicated shared array buffers not supported");
return false;
@@ -2065,11 +2120,17 @@ bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
return false;
}
- SharedArrayBuffer::Contents contents = sab->Externalize();
+ SharedArrayBuffer::Contents contents;
+ if (sab->IsExternal()) {
+ contents = sab->GetContents();
+ } else {
+ contents = sab->Externalize();
+ base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
+ externalized_shared_contents_.Add(contents);
+ }
out_data->WriteSharedArrayBufferContents(contents);
- externalized_shared_contents_.Add(contents);
} else if (value->IsObject()) {
- Handle<Object> object = Handle<Object>::Cast(value);
+ Local<Object> object = Local<Object>::Cast(value);
if (FindInObjectList(object, *seen_objects)) {
Throw(isolate, "Duplicated objects not supported");
return false;
@@ -2085,8 +2146,8 @@ bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
out_data->WriteTag(kSerializationTagObject);
out_data->Write(length);
for (uint32_t i = 0; i < length; ++i) {
- Handle<Value> name;
- Handle<Value> property_value;
+ Local<Value> name;
+ Local<Value> property_value;
if (property_names->Get(context, i).ToLocal(&name) &&
object->Get(context, name).ToLocal(&property_value)) {
if (!SerializeValue(isolate, name, to_transfer, seen_objects, out_data))
@@ -2094,6 +2155,9 @@ bool Shell::SerializeValue(Isolate* isolate, Handle<Value> value,
if (!SerializeValue(isolate, property_value, to_transfer, seen_objects,
out_data))
return false;
+ } else {
+ Throw(isolate, "Failed to serialize property.");
+ return false;
}
}
} else {
@@ -2133,47 +2197,43 @@ MaybeLocal<Value> Shell::DeserializeValue(Isolate* isolate,
break;
case kSerializationTagString: {
int length = data.Read<int>(offset);
- static char s_buffer[128];
- char* p = s_buffer;
- bool allocated = false;
- if (length > static_cast<int>(sizeof(s_buffer))) {
- p = new char[length];
- allocated = true;
- }
- data.ReadMemory(p, length, offset);
+ CHECK(length >= 0);
+ std::vector<char> buffer(length + 1); // + 1 so it is never empty.
+ data.ReadMemory(&buffer[0], length, offset);
MaybeLocal<String> str =
- String::NewFromUtf8(isolate, p, String::kNormalString, length);
+ String::NewFromUtf8(isolate, &buffer[0], NewStringType::kNormal,
+ length).ToLocalChecked();
if (!str.IsEmpty()) result = str.ToLocalChecked();
- if (allocated) delete[] p;
break;
}
case kSerializationTagArray: {
uint32_t length = data.Read<uint32_t>(offset);
- Handle<Array> array = Array::New(isolate, length);
+ Local<Array> array = Array::New(isolate, length);
for (uint32_t i = 0; i < length; ++i) {
Local<Value> element_value;
CHECK(DeserializeValue(isolate, data, offset).ToLocal(&element_value));
- array->Set(i, element_value);
+ array->Set(isolate->GetCurrentContext(), i, element_value).FromJust();
}
result = array;
break;
}
case kSerializationTagObject: {
int length = data.Read<int>(offset);
- Handle<Object> object = Object::New(isolate);
+ Local<Object> object = Object::New(isolate);
for (int i = 0; i < length; ++i) {
Local<Value> property_name;
CHECK(DeserializeValue(isolate, data, offset).ToLocal(&property_name));
Local<Value> property_value;
CHECK(DeserializeValue(isolate, data, offset).ToLocal(&property_value));
- object->Set(property_name, property_value);
+ object->Set(isolate->GetCurrentContext(), property_name, property_value)
+ .FromJust();
}
result = object;
break;
}
case kSerializationTagArrayBuffer: {
- int byte_length = data.Read<int>(offset);
- Handle<ArrayBuffer> array_buffer = ArrayBuffer::New(isolate, byte_length);
+ int32_t byte_length = data.Read<int32_t>(offset);
+ Local<ArrayBuffer> array_buffer = ArrayBuffer::New(isolate, byte_length);
ArrayBuffer::Contents contents = array_buffer->GetContents();
DCHECK(static_cast<size_t>(byte_length) == contents.ByteLength());
data.ReadMemory(contents.Data(), byte_length, offset);
@@ -2183,8 +2243,8 @@ MaybeLocal<Value> Shell::DeserializeValue(Isolate* isolate,
case kSerializationTagTransferredArrayBuffer: {
ArrayBuffer::Contents contents;
data.ReadArrayBufferContents(&contents, offset);
- result =
- ArrayBuffer::New(isolate, contents.Data(), contents.ByteLength());
+ result = ArrayBuffer::New(isolate, contents.Data(), contents.ByteLength(),
+ ArrayBufferCreationMode::kInternalized);
break;
}
case kSerializationTagTransferredSharedArrayBuffer: {
@@ -2208,7 +2268,7 @@ void Shell::CleanupWorkers() {
// create a new Worker, it would deadlock.
i::List<Worker*> workers_copy;
{
- base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
+ base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
allow_new_workers_ = false;
workers_copy.AddAll(workers_);
workers_.Clear();
@@ -2216,15 +2276,13 @@ void Shell::CleanupWorkers() {
for (int i = 0; i < workers_copy.length(); ++i) {
Worker* worker = workers_copy[i];
- worker->Terminate();
+ worker->WaitForThread();
delete worker;
}
// Now that all workers are terminated, we can re-enable Worker creation.
- {
- base::LockGuard<base::Mutex> lock_guard(&workers_mutex_);
- allow_new_workers_ = true;
- }
+ base::LockGuard<base::Mutex> lock_guard(workers_mutex_.Pointer());
+ allow_new_workers_ = true;
for (int i = 0; i < externalized_shared_contents_.length(); ++i) {
const SharedArrayBuffer::Contents& contents =
@@ -2352,12 +2410,10 @@ int Shell::Main(int argc, char* argv[]) {
}
#endif
Isolate* isolate = Isolate::New(create_params);
- DumbLineEditor dumb_line_editor(isolate);
{
Isolate::Scope scope(isolate);
Initialize(isolate);
PerIsolateData data(isolate);
- InitializeDebugger(isolate);
#ifndef V8_SHARED
if (options.dump_heap_constants) {
@@ -2370,35 +2426,36 @@ int Shell::Main(int argc, char* argv[]) {
Testing::SetStressRunType(options.stress_opt
? Testing::kStressTypeOpt
: Testing::kStressTypeDeopt);
- int stress_runs = Testing::GetStressRuns();
- for (int i = 0; i < stress_runs && result == 0; i++) {
- printf("============ Stress %d/%d ============\n", i + 1, stress_runs);
+ options.stress_runs = Testing::GetStressRuns();
+ for (int i = 0; i < options.stress_runs && result == 0; i++) {
+ printf("============ Stress %d/%d ============\n", i + 1,
+ options.stress_runs);
Testing::PrepareStressRun(i);
- options.last_run = (i == stress_runs - 1);
- result = RunMain(isolate, argc, argv);
+ bool last_run = i == options.stress_runs - 1;
+ result = RunMain(isolate, argc, argv, last_run);
}
printf("======== Full Deoptimization =======\n");
Testing::DeoptimizeAll();
#if !defined(V8_SHARED)
} else if (i::FLAG_stress_runs > 0) {
- int stress_runs = i::FLAG_stress_runs;
- for (int i = 0; i < stress_runs && result == 0; i++) {
- printf("============ Run %d/%d ============\n", i + 1, stress_runs);
- options.last_run = (i == stress_runs - 1);
- result = RunMain(isolate, argc, argv);
+ options.stress_runs = i::FLAG_stress_runs;
+ for (int i = 0; i < options.stress_runs && result == 0; i++) {
+ printf("============ Run %d/%d ============\n", i + 1,
+ options.stress_runs);
+ bool last_run = i == options.stress_runs - 1;
+ result = RunMain(isolate, argc, argv, last_run);
}
#endif
} else {
- result = RunMain(isolate, argc, argv);
+ bool last_run = true;
+ result = RunMain(isolate, argc, argv, last_run);
}
// Run interactive shell if explicitly requested or if no script has been
// executed, but never on --test
if (options.use_interactive_shell()) {
#ifndef V8_SHARED
- if (!i::FLAG_debugger) {
- InstallUtilityScript(isolate);
- }
+ InstallUtilityScript(isolate);
#endif // !V8_SHARED
RunShell(isolate);
}