Index: src/d8.cc |
diff --git a/src/d8.cc b/src/d8.cc |
index b3b1bb8a170855180c7ba4865c60a1051067ea8e..9fc909ba9fb59173e2a18bade8553abe17dd412f 100644 |
--- a/src/d8.cc |
+++ b/src/d8.cc |
@@ -67,6 +67,62 @@ |
namespace v8 { |
+ |
+static Handle<Value> Throw(const char* message) { |
+ return ThrowException(String::New(message)); |
+} |
+ |
+ |
+// TODO(rossberg): should replace these by proper uses of HasInstance, |
+// once we figure out a good way to make the templates global. |
+const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_"; |
+const char kArrayMarkerPropName[] = "d8::_is_typed_array_"; |
+ |
+ |
+#define FOR_EACH_SYMBOL(V) \ |
+ V(ArrayBuffer, "ArrayBuffer") \ |
+ V(ArrayBufferMarkerPropName, kArrayBufferMarkerPropName) \ |
+ V(ArrayMarkerPropName, kArrayMarkerPropName) \ |
+ V(buffer, "buffer") \ |
+ V(byteLength, "byteLength") \ |
+ V(byteOffset, "byteOffset") \ |
+ V(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT") \ |
+ V(length, "length") |
+ |
+ |
+class Symbols { |
+ public: |
+ explicit Symbols(Isolate* isolate) : isolate_(isolate) { |
+ HandleScope scope; |
+#define INIT_SYMBOL(name, value) \ |
+ name##_ = Persistent<String>::New(String::NewSymbol(value)); |
+ FOR_EACH_SYMBOL(INIT_SYMBOL) |
+#undef INIT_SYMBOL |
+ isolate->SetData(this); |
+ } |
+ |
+ ~Symbols() { |
+#define DISPOSE_SYMBOL(name, value) name##_.Dispose(); |
+ FOR_EACH_SYMBOL(DISPOSE_SYMBOL) |
+#undef DISPOSE_SYMBOL |
+ isolate_->SetData(NULL); // Not really needed, just to be sure... |
+ } |
+ |
+#define DEFINE_SYMBOL_GETTER(name, value) \ |
+ static Persistent<String> name(Isolate* isolate) { \ |
+ return reinterpret_cast<Symbols*>(isolate->GetData())->name##_; \ |
+ } |
+ FOR_EACH_SYMBOL(DEFINE_SYMBOL_GETTER) |
+#undef DEFINE_SYMBOL_GETTER |
+ |
+ private: |
+ Isolate* isolate_; |
+#define DEFINE_MEMBER(name, value) Persistent<String> name##_; |
+ FOR_EACH_SYMBOL(DEFINE_MEMBER) |
+#undef DEFINE_MEMBER |
+}; |
+ |
+ |
LineEditor *LineEditor::first_ = NULL; |
@@ -92,17 +148,17 @@ LineEditor* LineEditor::Get() { |
class DumbLineEditor: public LineEditor { |
public: |
- DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { } |
+ explicit DumbLineEditor(Isolate* isolate) |
+ : LineEditor(LineEditor::DUMB, "dumb"), isolate_(isolate) { } |
virtual Handle<String> Prompt(const char* prompt); |
+ private: |
+ Isolate* isolate_; |
}; |
-static DumbLineEditor dumb_line_editor; |
- |
- |
Handle<String> DumbLineEditor::Prompt(const char* prompt) { |
printf("%s", prompt); |
- return Shell::ReadFromStdin(); |
+ return Shell::ReadFromStdin(isolate_); |
} |
@@ -115,7 +171,6 @@ i::Mutex* Shell::context_mutex_(i::OS::CreateMutex()); |
Persistent<Context> Shell::utility_context_; |
#endif // V8_SHARED |
-LineEditor* Shell::console = NULL; |
Persistent<Context> Shell::evaluation_context_; |
ShellOptions Shell::options; |
const char* Shell::kPrompt = "d8> "; |
@@ -232,17 +287,17 @@ Handle<Value> Shell::DisableProfiler(const Arguments& args) { |
Handle<Value> Shell::Read(const Arguments& args) { |
String::Utf8Value file(args[0]); |
if (*file == NULL) { |
- return ThrowException(String::New("Error loading file")); |
+ return Throw("Error loading file"); |
} |
- Handle<String> source = ReadFile(*file); |
+ Handle<String> source = ReadFile(args.GetIsolate(), *file); |
if (source.IsEmpty()) { |
- return ThrowException(String::New("Error loading file")); |
+ return Throw("Error loading file"); |
} |
return source; |
} |
-Handle<String> Shell::ReadFromStdin() { |
+Handle<String> Shell::ReadFromStdin(Isolate* isolate) { |
static const int kBufferSize = 256; |
char buffer[kBufferSize]; |
Handle<String> accumulator = String::New(""); |
@@ -253,7 +308,7 @@ Handle<String> Shell::ReadFromStdin() { |
// If fgets gets an error, just give up. |
char* input = NULL; |
{ // Release lock for blocking input. |
- Unlocker unlock(Isolate::GetCurrent()); |
+ Unlocker unlock(isolate); |
input = fgets(buffer, kBufferSize, stdin); |
} |
if (input == NULL) return Handle<String>(); |
@@ -277,14 +332,14 @@ Handle<Value> Shell::Load(const Arguments& args) { |
HandleScope handle_scope; |
String::Utf8Value file(args[i]); |
if (*file == NULL) { |
- return ThrowException(String::New("Error loading file")); |
+ return Throw("Error loading file"); |
} |
- Handle<String> source = ReadFile(*file); |
+ Handle<String> source = ReadFile(args.GetIsolate(), *file); |
if (source.IsEmpty()) { |
- return ThrowException(String::New("Error loading file")); |
+ return Throw("Error loading file"); |
} |
if (!ExecuteString(source, String::New(*file), false, true)) { |
- return ThrowException(String::New("Error executing file")); |
+ return Throw("Error executing file"); |
} |
} |
return Undefined(); |
@@ -314,7 +369,7 @@ static int32_t convertToUint(Local<Value> value_in, TryCatch* try_catch) { |
if (try_catch->HasCaught()) return 0; |
if (raw_value < 0) { |
- ThrowException(String::New("Array length must not be negative.")); |
+ Throw("Array length must not be negative."); |
return 0; |
} |
@@ -323,33 +378,27 @@ static int32_t convertToUint(Local<Value> value_in, TryCatch* try_catch) { |
ASSERT(kMaxLength == i::ExternalArray::kMaxLength); |
#endif // V8_SHARED |
if (raw_value > static_cast<int32_t>(kMaxLength)) { |
- ThrowException( |
- String::New("Array length exceeds maximum length.")); |
+ Throw("Array length exceeds maximum length."); |
} |
return raw_value; |
} |
-// TODO(rossberg): should replace these by proper uses of HasInstance, |
-// once we figure out a good way to make the templates global. |
-const char kArrayBufferMarkerPropName[] = "d8::_is_array_buffer_"; |
-const char kArrayMarkerPropName[] = "d8::_is_typed_array_"; |
- |
- |
-Handle<Value> Shell::CreateExternalArrayBuffer(Handle<Object> buffer, |
+Handle<Value> Shell::CreateExternalArrayBuffer(Isolate* isolate, |
+ Handle<Object> buffer, |
int32_t length) { |
static const int32_t kMaxSize = 0x7fffffff; |
// Make sure the total size fits into a (signed) int. |
if (length < 0 || length > kMaxSize) { |
- return ThrowException(String::New("ArrayBuffer exceeds maximum size (2G)")); |
+ return Throw("ArrayBuffer exceeds maximum size (2G)"); |
} |
uint8_t* data = new uint8_t[length]; |
if (data == NULL) { |
- return ThrowException(String::New("Memory allocation failed")); |
+ return Throw("Memory allocation failed"); |
} |
memset(data, 0, length); |
- buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True()); |
+ buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True()); |
Persistent<Object> persistent_array = Persistent<Object>::New(buffer); |
persistent_array.MakeWeak(data, ExternalArrayWeakCallback); |
persistent_array.MarkIndependent(); |
@@ -357,7 +406,7 @@ Handle<Value> Shell::CreateExternalArrayBuffer(Handle<Object> buffer, |
buffer->SetIndexedPropertiesToExternalArrayData( |
data, v8::kExternalByteArray, length); |
- buffer->Set(String::New("byteLength"), Int32::New(length), ReadOnly); |
+ buffer->Set(Symbols::byteLength(isolate), Int32::New(length), ReadOnly); |
return buffer; |
} |
@@ -373,18 +422,18 @@ Handle<Value> Shell::ArrayBuffer(const Arguments& args) { |
} |
if (args.Length() == 0) { |
- return ThrowException( |
- String::New("ArrayBuffer constructor must have one argument")); |
+ return Throw("ArrayBuffer constructor must have one argument"); |
} |
TryCatch try_catch; |
int32_t length = convertToUint(args[0], &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
- return CreateExternalArrayBuffer(args.This(), length); |
+ return CreateExternalArrayBuffer(args.GetIsolate(), args.This(), length); |
} |
-Handle<Object> Shell::CreateExternalArray(Handle<Object> array, |
+Handle<Object> Shell::CreateExternalArray(Isolate* isolate, |
+ Handle<Object> array, |
Handle<Object> buffer, |
ExternalArrayType type, |
int32_t length, |
@@ -400,12 +449,13 @@ Handle<Object> Shell::CreateExternalArray(Handle<Object> array, |
array->SetIndexedPropertiesToExternalArrayData( |
static_cast<uint8_t*>(data) + byteOffset, type, length); |
- array->SetHiddenValue(String::New(kArrayMarkerPropName), Int32::New(type)); |
- array->Set(String::New("byteLength"), Int32::New(byteLength), ReadOnly); |
- array->Set(String::New("byteOffset"), Int32::New(byteOffset), ReadOnly); |
- array->Set(String::New("length"), Int32::New(length), ReadOnly); |
- array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size)); |
- array->Set(String::New("buffer"), buffer, ReadOnly); |
+ array->SetHiddenValue(Symbols::ArrayMarkerPropName(isolate), |
+ Int32::New(type)); |
+ array->Set(Symbols::byteLength(isolate), Int32::New(byteLength), ReadOnly); |
+ array->Set(Symbols::byteOffset(isolate), Int32::New(byteOffset), ReadOnly); |
+ array->Set(Symbols::length(isolate), Int32::New(length), ReadOnly); |
+ array->Set(Symbols::BYTES_PER_ELEMENT(isolate), Int32::New(element_size)); |
+ array->Set(Symbols::buffer(isolate), buffer, ReadOnly); |
return array; |
} |
@@ -414,6 +464,7 @@ Handle<Object> Shell::CreateExternalArray(Handle<Object> array, |
Handle<Value> Shell::CreateExternalArray(const Arguments& args, |
ExternalArrayType type, |
int32_t element_size) { |
+ Isolate* isolate = args.GetIsolate(); |
if (!args.IsConstructCall()) { |
Handle<Value>* rec_args = new Handle<Value>[args.Length()]; |
for (int i = 0; i < args.Length(); ++i) rec_args[i] = args[i]; |
@@ -439,16 +490,15 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, |
int32_t byteOffset; |
bool init_from_array = false; |
if (args.Length() == 0) { |
- return ThrowException( |
- String::New("Array constructor must have at least one argument")); |
+ return Throw("Array constructor must have at least one argument"); |
} |
if (args[0]->IsObject() && |
!args[0]->ToObject()->GetHiddenValue( |
- String::New(kArrayBufferMarkerPropName)).IsEmpty()) { |
+ Symbols::ArrayBufferMarkerPropName(isolate)).IsEmpty()) { |
// Construct from ArrayBuffer. |
buffer = args[0]->ToObject(); |
int32_t bufferLength = |
- convertToUint(buffer->Get(String::New("byteLength")), &try_catch); |
+ convertToUint(buffer->Get(Symbols::byteLength(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
if (args.Length() < 2 || args[1]->IsUndefined()) { |
@@ -457,11 +507,10 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, |
byteOffset = convertToUint(args[1], &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
if (byteOffset > bufferLength) { |
- return ThrowException(String::New("byteOffset out of bounds")); |
+ return Throw("byteOffset out of bounds"); |
} |
if (byteOffset % element_size != 0) { |
- return ThrowException( |
- String::New("byteOffset must be multiple of element size")); |
+ return Throw("byteOffset must be multiple of element size"); |
} |
} |
@@ -469,23 +518,22 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, |
byteLength = bufferLength - byteOffset; |
length = byteLength / element_size; |
if (byteLength % element_size != 0) { |
- return ThrowException( |
- String::New("buffer size must be multiple of element size")); |
+ return Throw("buffer size must be multiple of element size"); |
} |
} else { |
length = convertToUint(args[2], &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
byteLength = length * element_size; |
if (byteOffset + byteLength > bufferLength) { |
- return ThrowException(String::New("length out of bounds")); |
+ return Throw("length out of bounds"); |
} |
} |
} else { |
if (args[0]->IsObject() && |
- args[0]->ToObject()->Has(String::New("length"))) { |
+ args[0]->ToObject()->Has(Symbols::length(isolate))) { |
// Construct from array. |
length = convertToUint( |
- args[0]->ToObject()->Get(String::New("length")), &try_catch); |
+ args[0]->ToObject()->Get(Symbols::length(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
init_from_array = true; |
} else { |
@@ -497,7 +545,7 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, |
byteOffset = 0; |
Handle<Object> global = Context::GetCurrent()->Global(); |
- Handle<Value> array_buffer = global->Get(String::New("ArrayBuffer")); |
+ Handle<Value> array_buffer = global->Get(Symbols::ArrayBuffer(isolate)); |
ASSERT(!try_catch.HasCaught() && array_buffer->IsFunction()); |
Handle<Value> buffer_args[] = { Uint32::New(byteLength) }; |
Handle<Value> result = Handle<Function>::Cast(array_buffer)->NewInstance( |
@@ -506,8 +554,9 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args, |
buffer = result->ToObject(); |
} |
- Handle<Object> array = CreateExternalArray( |
- args.This(), buffer, type, length, byteLength, byteOffset, element_size); |
+ Handle<Object> array = |
+ CreateExternalArray(isolate, args.This(), buffer, type, length, |
+ byteLength, byteOffset, element_size); |
if (init_from_array) { |
Handle<Object> init = args[0]->ToObject(); |
@@ -522,25 +571,23 @@ Handle<Value> Shell::ArrayBufferSlice(const Arguments& args) { |
TryCatch try_catch; |
if (!args.This()->IsObject()) { |
- return ThrowException( |
- String::New("'slice' invoked on non-object receiver")); |
+ return Throw("'slice' invoked on non-object receiver"); |
} |
+ Isolate* isolate = args.GetIsolate(); |
Local<Object> self = args.This(); |
Local<Value> marker = |
- self->GetHiddenValue(String::New(kArrayBufferMarkerPropName)); |
+ self->GetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate)); |
if (marker.IsEmpty()) { |
- return ThrowException( |
- String::New("'slice' invoked on wrong receiver type")); |
+ return Throw("'slice' invoked on wrong receiver type"); |
} |
int32_t length = |
- convertToUint(self->Get(String::New("byteLength")), &try_catch); |
+ convertToUint(self->Get(Symbols::byteLength(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
if (args.Length() == 0) { |
- return ThrowException( |
- String::New("'slice' must have at least one argument")); |
+ return Throw("'slice' must have at least one argument"); |
} |
int32_t begin = convertToInt(args[0], &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
@@ -579,32 +626,31 @@ Handle<Value> Shell::ArraySubArray(const Arguments& args) { |
TryCatch try_catch; |
if (!args.This()->IsObject()) { |
- return ThrowException( |
- String::New("'subarray' invoked on non-object receiver")); |
+ return Throw("'subarray' invoked on non-object receiver"); |
} |
+ Isolate* isolate = args.GetIsolate(); |
Local<Object> self = args.This(); |
- Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName)); |
+ Local<Value> marker = |
+ self->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate)); |
if (marker.IsEmpty()) { |
- return ThrowException( |
- String::New("'subarray' invoked on wrong receiver type")); |
+ return Throw("'subarray' invoked on wrong receiver type"); |
} |
- Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject(); |
+ Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject(); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t length = |
- convertToUint(self->Get(String::New("length")), &try_catch); |
+ convertToUint(self->Get(Symbols::length(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t byteOffset = |
- convertToUint(self->Get(String::New("byteOffset")), &try_catch); |
+ convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t element_size = |
- convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch); |
+ convertToUint(self->Get(Symbols::BYTES_PER_ELEMENT(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
if (args.Length() == 0) { |
- return ThrowException( |
- String::New("'subarray' must have at least one argument")); |
+ return Throw("'subarray' must have at least one argument"); |
} |
int32_t begin = convertToInt(args[0], &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
@@ -639,35 +685,33 @@ Handle<Value> Shell::ArraySet(const Arguments& args) { |
TryCatch try_catch; |
if (!args.This()->IsObject()) { |
- return ThrowException( |
- String::New("'set' invoked on non-object receiver")); |
+ return Throw("'set' invoked on non-object receiver"); |
} |
+ Isolate* isolate = args.GetIsolate(); |
Local<Object> self = args.This(); |
- Local<Value> marker = self->GetHiddenValue(String::New(kArrayMarkerPropName)); |
+ Local<Value> marker = |
+ self->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate)); |
if (marker.IsEmpty()) { |
- return ThrowException( |
- String::New("'set' invoked on wrong receiver type")); |
+ return Throw("'set' invoked on wrong receiver type"); |
} |
int32_t length = |
- convertToUint(self->Get(String::New("length")), &try_catch); |
+ convertToUint(self->Get(Symbols::length(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t element_size = |
- convertToUint(self->Get(String::New("BYTES_PER_ELEMENT")), &try_catch); |
+ convertToUint(self->Get(Symbols::BYTES_PER_ELEMENT(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
if (args.Length() == 0) { |
- return ThrowException( |
- String::New("'set' must have at least one argument")); |
+ return Throw("'set' must have at least one argument"); |
} |
if (!args[0]->IsObject() || |
- !args[0]->ToObject()->Has(String::New("length"))) { |
- return ThrowException( |
- String::New("'set' invoked with non-array argument")); |
+ !args[0]->ToObject()->Has(Symbols::length(isolate))) { |
+ return Throw("'set' invoked with non-array argument"); |
} |
Handle<Object> source = args[0]->ToObject(); |
int32_t source_length = |
- convertToUint(source->Get(String::New("length")), &try_catch); |
+ convertToUint(source->Get(Symbols::length(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t offset; |
@@ -678,31 +722,32 @@ Handle<Value> Shell::ArraySet(const Arguments& args) { |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
} |
if (offset + source_length > length) { |
- return ThrowException(String::New("offset or source length out of bounds")); |
+ return Throw("offset or source length out of bounds"); |
} |
int32_t source_element_size; |
- if (source->GetHiddenValue(String::New(kArrayMarkerPropName)).IsEmpty()) { |
+ if (source->GetHiddenValue(Symbols::ArrayMarkerPropName(isolate)).IsEmpty()) { |
source_element_size = 0; |
} else { |
source_element_size = |
- convertToUint(source->Get(String::New("BYTES_PER_ELEMENT")), &try_catch); |
+ convertToUint(source->Get(Symbols::BYTES_PER_ELEMENT(isolate)), |
+ &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
} |
if (element_size == source_element_size && |
self->GetConstructor()->StrictEquals(source->GetConstructor())) { |
// Use memmove on the array buffers. |
- Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject(); |
+ Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject(); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
Handle<Object> source_buffer = |
- source->Get(String::New("buffer"))->ToObject(); |
+ source->Get(Symbols::buffer(isolate))->ToObject(); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t byteOffset = |
- convertToUint(self->Get(String::New("byteOffset")), &try_catch); |
+ convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t source_byteOffset = |
- convertToUint(source->Get(String::New("byteOffset")), &try_catch); |
+ convertToUint(source->Get(Symbols::byteOffset(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
uint8_t* dest = byteOffset + offset * element_size + static_cast<uint8_t*>( |
@@ -718,10 +763,10 @@ Handle<Value> Shell::ArraySet(const Arguments& args) { |
} |
} else { |
// Need to copy element-wise to make the right conversions. |
- Handle<Object> buffer = self->Get(String::New("buffer"))->ToObject(); |
+ Handle<Object> buffer = self->Get(Symbols::buffer(isolate))->ToObject(); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
Handle<Object> source_buffer = |
- source->Get(String::New("buffer"))->ToObject(); |
+ source->Get(Symbols::buffer(isolate))->ToObject(); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
if (buffer->StrictEquals(source_buffer)) { |
@@ -729,10 +774,10 @@ Handle<Value> Shell::ArraySet(const Arguments& args) { |
// This gets a bit tricky in the case of different element sizes |
// (which, of course, is extremely unlikely to ever occur in practice). |
int32_t byteOffset = |
- convertToUint(self->Get(String::New("byteOffset")), &try_catch); |
+ convertToUint(self->Get(Symbols::byteOffset(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
int32_t source_byteOffset = |
- convertToUint(source->Get(String::New("byteOffset")), &try_catch); |
+ convertToUint(source->Get(Symbols::byteOffset(isolate)), &try_catch); |
if (try_catch.HasCaught()) return try_catch.ReThrow(); |
// Copy as much as we can from left to right. |
@@ -778,8 +823,9 @@ Handle<Value> Shell::ArraySet(const Arguments& args) { |
void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) { |
HandleScope scope; |
+ Isolate* isolate = Isolate::GetCurrent(); |
int32_t length = |
- object->ToObject()->Get(String::New("byteLength"))->Uint32Value(); |
+ object->ToObject()->Get(Symbols::byteLength(isolate))->Uint32Value(); |
V8::AdjustAmountOfExternalAllocatedMemory(-length); |
delete[] static_cast<uint8_t*>(data); |
object.Dispose(); |
@@ -1145,7 +1191,7 @@ Handle<FunctionTemplate> Shell::CreateArrayTemplate(InvocationCallback fun) { |
} |
-Handle<ObjectTemplate> Shell::CreateGlobalTemplate() { |
+Handle<ObjectTemplate> Shell::CreateGlobalTemplate(Isolate* isolate) { |
Handle<ObjectTemplate> global_template = ObjectTemplate::New(); |
global_template->Set(String::New("print"), FunctionTemplate::New(Print)); |
global_template->Set(String::New("write"), FunctionTemplate::New(Write)); |
@@ -1165,7 +1211,7 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() { |
// Bind the handlers for external arrays. |
PropertyAttribute attr = |
static_cast<PropertyAttribute>(ReadOnly | DontDelete); |
- global_template->Set(String::New("ArrayBuffer"), |
+ global_template->Set(Symbols::ArrayBuffer(isolate), |
CreateArrayBufferTemplate(ArrayBuffer), attr); |
global_template->Set(String::New("Int8Array"), |
CreateArrayTemplate(Int8Array), attr); |
@@ -1202,7 +1248,7 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() { |
} |
-void Shell::Initialize() { |
+void Shell::Initialize(Isolate* isolate) { |
#ifdef COMPRESS_STARTUP_DATA_BZ2 |
BZip2Decompressor startup_data_decompressor; |
int bz2_result = startup_data_decompressor.Decompress(); |
@@ -1228,7 +1274,7 @@ void Shell::Initialize() { |
#ifndef V8_SHARED |
Locker lock; |
HandleScope scope; |
- Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); |
+ Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); |
utility_context_ = Context::New(NULL, global_template); |
#ifdef ENABLE_DEBUGGER_SUPPORT |
@@ -1242,13 +1288,13 @@ void Shell::Initialize() { |
} |
-Persistent<Context> Shell::CreateEvaluationContext() { |
+Persistent<Context> Shell::CreateEvaluationContext(Isolate* isolate) { |
#ifndef V8_SHARED |
// This needs to be a critical section since this is not thread-safe |
i::ScopedLock lock(context_mutex_); |
#endif // V8_SHARED |
// Initialize the global objects |
- Handle<ObjectTemplate> global_template = CreateGlobalTemplate(); |
+ Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate); |
Persistent<Context> context = Context::New(NULL, global_template); |
ASSERT(!context.IsEmpty()); |
Context::Scope scope(context); |
@@ -1294,7 +1340,6 @@ int CompareKeys(const void* a, const void* b) { |
void Shell::OnExit() { |
- if (console != NULL) console->Close(); |
if (i::FLAG_dump_counters) { |
int number_of_counters = 0; |
for (CounterMap::Iterator i(counter_map_); i.More(); i.Next()) { |
@@ -1354,9 +1399,9 @@ static FILE* FOpen(const char* path, const char* mode) { |
} |
-static char* ReadChars(const char* name, int* size_out) { |
+static char* ReadChars(Isolate* isolate, const char* name, int* size_out) { |
// Release the V8 lock while reading files. |
- v8::Unlocker unlocker(Isolate::GetCurrent()); |
+ v8::Unlocker unlocker(isolate); |
FILE* file = FOpen(name, "rb"); |
if (file == NULL) return NULL; |
@@ -1381,15 +1426,17 @@ Handle<Value> Shell::ReadBuffer(const Arguments& args) { |
String::Utf8Value filename(args[0]); |
int length; |
if (*filename == NULL) { |
- return ThrowException(String::New("Error loading file")); |
+ return Throw("Error loading file"); |
} |
- uint8_t* data = reinterpret_cast<uint8_t*>(ReadChars(*filename, &length)); |
+ uint8_t* data = reinterpret_cast<uint8_t*>( |
+ ReadChars(args.GetIsolate(), *filename, &length)); |
if (data == NULL) { |
- return ThrowException(String::New("Error reading file")); |
+ return Throw("Error reading file"); |
} |
+ Isolate* isolate = args.GetIsolate(); |
Handle<Object> buffer = Object::New(); |
- buffer->SetHiddenValue(String::New(kArrayBufferMarkerPropName), True()); |
+ buffer->SetHiddenValue(Symbols::ArrayBufferMarkerPropName(isolate), True()); |
Persistent<Object> persistent_buffer = Persistent<Object>::New(buffer); |
persistent_buffer.MakeWeak(data, ExternalArrayWeakCallback); |
persistent_buffer.MarkIndependent(); |
@@ -1397,7 +1444,7 @@ Handle<Value> Shell::ReadBuffer(const Arguments& args) { |
buffer->SetIndexedPropertiesToExternalArrayData( |
data, kExternalUnsignedByteArray, length); |
- buffer->Set(String::New("byteLength"), |
+ buffer->Set(Symbols::byteLength(isolate), |
Int32::New(static_cast<int32_t>(length)), ReadOnly); |
return buffer; |
} |
@@ -1427,9 +1474,9 @@ static char* ReadWord(char* data) { |
// Reads a file into a v8 string. |
-Handle<String> Shell::ReadFile(const char* name) { |
+Handle<String> Shell::ReadFile(Isolate* isolate, const char* name) { |
int size = 0; |
- char* chars = ReadChars(name, &size); |
+ char* chars = ReadChars(isolate, name, &size); |
if (chars == NULL) return Handle<String>(); |
Handle<String> result = String::New(chars); |
delete[] chars; |
@@ -1437,12 +1484,13 @@ Handle<String> Shell::ReadFile(const char* name) { |
} |
-void Shell::RunShell() { |
+void Shell::RunShell(Isolate* isolate) { |
Locker locker; |
Context::Scope context_scope(evaluation_context_); |
HandleScope outer_scope; |
Handle<String> name = String::New("(d8)"); |
- console = LineEditor::Get(); |
+ DumbLineEditor dumb_line_editor(isolate); |
+ LineEditor* console = LineEditor::Get(); |
printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name()); |
console->Open(); |
while (true) { |
@@ -1452,6 +1500,7 @@ void Shell::RunShell() { |
ExecuteString(input, name, true, true); |
} |
printf("\n"); |
+ console->Close(); |
} |
@@ -1459,9 +1508,9 @@ void Shell::RunShell() { |
class ShellThread : public i::Thread { |
public: |
// Takes ownership of the underlying char array of |files|. |
- ShellThread(int no, char* files) |
+ ShellThread(Isolate* isolate, int no, char* files) |
: Thread("d8:ShellThread"), |
- no_(no), files_(files) { } |
+ isolate_(isolate), no_(no), files_(files) { } |
~ShellThread() { |
delete[] files_; |
@@ -1469,6 +1518,7 @@ class ShellThread : public i::Thread { |
virtual void Run(); |
private: |
+ Isolate* isolate_; |
int no_; |
char* files_; |
}; |
@@ -1489,7 +1539,8 @@ void ShellThread::Run() { |
// Prepare the context for this thread. |
Locker locker; |
HandleScope outer_scope; |
- Persistent<Context> thread_context = Shell::CreateEvaluationContext(); |
+ Persistent<Context> thread_context = |
+ Shell::CreateEvaluationContext(isolate_); |
Context::Scope context_scope(thread_context); |
while ((ptr != NULL) && (*ptr != '\0')) { |
@@ -1502,7 +1553,7 @@ void ShellThread::Run() { |
continue; |
} |
- Handle<String> str = Shell::ReadFile(filename); |
+ Handle<String> str = Shell::ReadFile(isolate_, filename); |
if (str.IsEmpty()) { |
printf("File '%s' not found\n", filename); |
Shell::Exit(1); |
@@ -1530,7 +1581,7 @@ SourceGroup::~SourceGroup() { |
} |
-void SourceGroup::Execute() { |
+void SourceGroup::Execute(Isolate* isolate) { |
for (int i = begin_offset_; i < end_offset_; ++i) { |
const char* arg = argv_[i]; |
if (strcmp(arg, "-e") == 0 && i + 1 < end_offset_) { |
@@ -1548,7 +1599,7 @@ void SourceGroup::Execute() { |
// Use all other arguments as names of files to load and run. |
HandleScope handle_scope; |
Handle<String> file_name = String::New(arg); |
- Handle<String> source = ReadFile(arg); |
+ Handle<String> source = ReadFile(isolate, arg); |
if (source.IsEmpty()) { |
printf("Error reading '%s'\n", arg); |
Shell::Exit(1); |
@@ -1561,9 +1612,9 @@ void SourceGroup::Execute() { |
} |
-Handle<String> SourceGroup::ReadFile(const char* name) { |
+Handle<String> SourceGroup::ReadFile(Isolate* isolate, const char* name) { |
int size; |
- char* chars = ReadChars(name, &size); |
+ char* chars = ReadChars(isolate, name, &size); |
if (chars == NULL) return Handle<String>(); |
Handle<String> result = String::New(chars, size); |
delete[] chars; |
@@ -1589,10 +1640,11 @@ void SourceGroup::ExecuteInThread() { |
Isolate::Scope iscope(isolate); |
Locker lock(isolate); |
HandleScope scope; |
- Persistent<Context> context = Shell::CreateEvaluationContext(); |
+ Symbols symbols(isolate); |
+ Persistent<Context> context = Shell::CreateEvaluationContext(isolate); |
{ |
Context::Scope cscope(context); |
- Execute(); |
+ Execute(isolate); |
} |
context.Dispose(); |
if (Shell::options.send_idle_notification) { |
@@ -1760,21 +1812,21 @@ bool Shell::SetOptions(int argc, char* argv[]) { |
} |
-int Shell::RunMain(int argc, char* argv[]) { |
+int Shell::RunMain(Isolate* isolate, int argc, char* argv[]) { |
#ifndef V8_SHARED |
i::List<i::Thread*> threads(1); |
if (options.parallel_files != NULL) { |
for (int i = 0; i < options.num_parallel_files; i++) { |
char* files = NULL; |
- { Locker lock(Isolate::GetCurrent()); |
+ { Locker lock(isolate); |
int size = 0; |
- files = ReadChars(options.parallel_files[i], &size); |
+ files = ReadChars(isolate, options.parallel_files[i], &size); |
} |
if (files == NULL) { |
printf("File list '%s' not found\n", options.parallel_files[i]); |
Exit(1); |
} |
- ShellThread* thread = new ShellThread(threads.length(), files); |
+ ShellThread* thread = new ShellThread(isolate, threads.length(), files); |
thread->Start(); |
threads.Add(thread); |
} |
@@ -1786,7 +1838,7 @@ int Shell::RunMain(int argc, char* argv[]) { |
{ // NOLINT |
Locker lock; |
HandleScope scope; |
- Persistent<Context> context = CreateEvaluationContext(); |
+ Persistent<Context> context = CreateEvaluationContext(isolate); |
if (options.last_run) { |
// Keep using the same context in the interactive shell. |
evaluation_context_ = context; |
@@ -1800,7 +1852,7 @@ int Shell::RunMain(int argc, char* argv[]) { |
} |
{ |
Context::Scope cscope(context); |
- options.isolate_sources[0].Execute(); |
+ options.isolate_sources[0].Execute(isolate); |
} |
if (!options.last_run) { |
context.Dispose(); |
@@ -1842,59 +1894,61 @@ int Shell::RunMain(int argc, char* argv[]) { |
int Shell::Main(int argc, char* argv[]) { |
if (!SetOptions(argc, argv)) return 1; |
- Initialize(); |
- |
int result = 0; |
- if (options.stress_opt || options.stress_deopt) { |
- 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); |
- Testing::PrepareStressRun(i); |
- options.last_run = (i == stress_runs - 1); |
- result = RunMain(argc, argv); |
- } |
- printf("======== Full Deoptimization =======\n"); |
- Testing::DeoptimizeAll(); |
+ Isolate* isolate = Isolate::GetCurrent(); |
+ { |
+ Symbols symbols(isolate); |
+ Initialize(isolate); |
+ |
+ if (options.stress_opt || options.stress_deopt) { |
+ 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); |
+ Testing::PrepareStressRun(i); |
+ options.last_run = (i == stress_runs - 1); |
+ result = RunMain(isolate, argc, argv); |
+ } |
+ 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(argc, argv); |
- } |
+ } 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); |
+ } |
#endif |
- } else { |
- result = RunMain(argc, argv); |
- } |
+ } else { |
+ result = RunMain(isolate, argc, argv); |
+ } |
#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT) |
- // Run remote debugger if requested, but never on --test |
- if (i::FLAG_remote_debugger && !options.test_shell) { |
- InstallUtilityScript(); |
- RunRemoteDebugger(i::FLAG_debugger_port); |
- return 0; |
- } |
+ // Run remote debugger if requested, but never on --test |
+ if (i::FLAG_remote_debugger && !options.test_shell) { |
+ InstallUtilityScript(); |
+ RunRemoteDebugger(i::FLAG_debugger_port); |
+ return 0; |
+ } |
#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT |
- // Run interactive shell if explicitly requested or if no script has been |
- // executed, but never on --test |
+ // Run interactive shell if explicitly requested or if no script has been |
+ // executed, but never on --test |
- if (( options.interactive_shell |
- || !options.script_executed ) |
- && !options.test_shell ) { |
+ if (( options.interactive_shell || !options.script_executed ) |
+ && !options.test_shell ) { |
#if !defined(V8_SHARED) && defined(ENABLE_DEBUGGER_SUPPORT) |
- if (!i::FLAG_debugger) { |
- InstallUtilityScript(); |
- } |
+ if (!i::FLAG_debugger) { |
+ InstallUtilityScript(); |
+ } |
#endif // !V8_SHARED && ENABLE_DEBUGGER_SUPPORT |
- RunShell(); |
+ RunShell(isolate); |
+ } |
} |
- |
V8::Dispose(); |
#ifndef V8_SHARED |