Fixed bug #57. Introduced String::Utf8Value and replaced a bunch of

uses of String::AsciiValue with String::Utf8Value.  Fixed shell sample
'load' so it doesn't print error messages.



git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@254 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 255b63ef
...@@ -879,6 +879,21 @@ class EXPORT String : public Primitive { ...@@ -879,6 +879,21 @@ class EXPORT String : public Primitive {
/** Creates an undetectable string from the supplied utf-16 data.*/ /** Creates an undetectable string from the supplied utf-16 data.*/
static Local<String> NewUndetectable(const uint16_t* data, int length = -1); static Local<String> NewUndetectable(const uint16_t* data, int length = -1);
/**
* Converts an object to a utf8-encoded character array. Useful if
* you want to print the object.
*/
class EXPORT Utf8Value {
public:
explicit Utf8Value(Handle<v8::Value> obj);
~Utf8Value();
char* operator*() { return str_; }
int length() { return length_; }
private:
char* str_;
int length_;
};
/** /**
* Converts an object to an ascii string. * Converts an object to an ascii string.
* Useful if you want to print the object. * Useful if you want to print the object.
...@@ -888,8 +903,10 @@ class EXPORT String : public Primitive { ...@@ -888,8 +903,10 @@ class EXPORT String : public Primitive {
explicit AsciiValue(Handle<v8::Value> obj); explicit AsciiValue(Handle<v8::Value> obj);
~AsciiValue(); ~AsciiValue();
char* operator*() { return str_; } char* operator*() { return str_; }
int length() { return length_; }
private: private:
char* str_; char* str_;
int length_;
}; };
/** /**
...@@ -900,8 +917,10 @@ class EXPORT String : public Primitive { ...@@ -900,8 +917,10 @@ class EXPORT String : public Primitive {
explicit Value(Handle<v8::Value> obj); explicit Value(Handle<v8::Value> obj);
~Value(); ~Value();
uint16_t* operator*() { return str_; } uint16_t* operator*() { return str_; }
int length() { return length_; }
private: private:
uint16_t* str_; uint16_t* str_;
int length_;
}; };
}; };
......
...@@ -137,7 +137,7 @@ static Handle<Value> LogCallback(const Arguments& args) { ...@@ -137,7 +137,7 @@ static Handle<Value> LogCallback(const Arguments& args) {
if (args.Length() < 1) return v8::Undefined(); if (args.Length() < 1) return v8::Undefined();
HandleScope scope; HandleScope scope;
Handle<Value> arg = args[0]; Handle<Value> arg = args[0];
String::AsciiValue value(arg); String::Utf8Value value(arg);
HttpRequestProcessor::Log(*value); HttpRequestProcessor::Log(*value);
return v8::Undefined(); return v8::Undefined();
} }
...@@ -206,7 +206,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) { ...@@ -206,7 +206,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
// Compile the script and check for errors. // Compile the script and check for errors.
Handle<Script> compiled_script = Script::Compile(script); Handle<Script> compiled_script = Script::Compile(script);
if (compiled_script.IsEmpty()) { if (compiled_script.IsEmpty()) {
String::AsciiValue error(try_catch.Exception()); String::Utf8Value error(try_catch.Exception());
Log(*error); Log(*error);
// The script failed to compile; bail out. // The script failed to compile; bail out.
return false; return false;
...@@ -216,7 +216,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) { ...@@ -216,7 +216,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
Handle<Value> result = compiled_script->Run(); Handle<Value> result = compiled_script->Run();
if (result.IsEmpty()) { if (result.IsEmpty()) {
// The TryCatch above is still in effect and will have caught the error. // The TryCatch above is still in effect and will have caught the error.
String::AsciiValue error(try_catch.Exception()); String::Utf8Value error(try_catch.Exception());
Log(*error); Log(*error);
// Running the script failed; bail out. // Running the script failed; bail out.
return false; return false;
...@@ -262,7 +262,7 @@ bool JsHttpRequestProcessor::Process(HttpRequest* request) { ...@@ -262,7 +262,7 @@ bool JsHttpRequestProcessor::Process(HttpRequest* request) {
Handle<Value> argv[argc] = { request_obj }; Handle<Value> argv[argc] = { request_obj };
Handle<Value> result = process_->Call(context_->Global(), argc, argv); Handle<Value> result = process_->Call(context_->Global(), argc, argv);
if (result.IsEmpty()) { if (result.IsEmpty()) {
String::AsciiValue error(try_catch.Exception()); String::Utf8Value error(try_catch.Exception());
Log(*error); Log(*error);
return false; return false;
} else { } else {
...@@ -332,8 +332,8 @@ map<string, string>* JsHttpRequestProcessor::UnwrapMap(Handle<Object> obj) { ...@@ -332,8 +332,8 @@ map<string, string>* JsHttpRequestProcessor::UnwrapMap(Handle<Object> obj) {
// Convert a JavaScript string to a std::string. To not bother too // Convert a JavaScript string to a std::string. To not bother too
// much with string encodings we just use ascii. // much with string encodings we just use ascii.
string ObjectToString(Local<Value> value) { string ObjectToString(Local<Value> value) {
String::AsciiValue ascii_value(value); String::Utf8Value utf8_value(value);
return string(*ascii_value); return string(*utf8_value);
} }
......
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
void RunShell(v8::Handle<v8::Context> context); void RunShell(v8::Handle<v8::Context> context);
bool ExecuteString(v8::Handle<v8::String> source, bool ExecuteString(v8::Handle<v8::String> source,
v8::Handle<v8::Value> name, v8::Handle<v8::Value> name,
bool print_result); bool print_result,
bool report_exceptions);
v8::Handle<v8::Value> Print(const v8::Arguments& args); v8::Handle<v8::Value> Print(const v8::Arguments& args);
v8::Handle<v8::Value> Load(const v8::Arguments& args); v8::Handle<v8::Value> Load(const v8::Arguments& args);
v8::Handle<v8::Value> Quit(const v8::Arguments& args); v8::Handle<v8::Value> Quit(const v8::Arguments& args);
...@@ -81,7 +82,7 @@ int main(int argc, char* argv[]) { ...@@ -81,7 +82,7 @@ int main(int argc, char* argv[]) {
printf("Error reading '%s'\n", str); printf("Error reading '%s'\n", str);
return 1; return 1;
} }
if (!ExecuteString(source, file_name, false)) if (!ExecuteString(source, file_name, false, true))
return 1; return 1;
} }
} }
...@@ -102,7 +103,7 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) { ...@@ -102,7 +103,7 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) {
} else { } else {
printf(" "); printf(" ");
} }
v8::String::AsciiValue str(args[i]); v8::String::Utf8Value str(args[i]);
printf("%s", *str); printf("%s", *str);
} }
printf("\n"); printf("\n");
...@@ -116,12 +117,14 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) { ...@@ -116,12 +117,14 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) {
v8::Handle<v8::Value> Load(const v8::Arguments& args) { v8::Handle<v8::Value> Load(const v8::Arguments& args) {
for (int i = 0; i < args.Length(); i++) { for (int i = 0; i < args.Length(); i++) {
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::String::AsciiValue file(args[i]); v8::String::Utf8Value file(args[i]);
v8::Handle<v8::String> source = ReadFile(*file); v8::Handle<v8::String> source = ReadFile(*file);
if (source.IsEmpty()) { if (source.IsEmpty()) {
return v8::ThrowException(v8::String::New("Error loading file")); return v8::ThrowException(v8::String::New("Error loading file"));
} }
ExecuteString(source, v8::String::New(*file), false); if (!ExecuteString(source, v8::String::New(*file), false, false)) {
return v8::ThrowException(v8::String::New("Error executing file"));
}
} }
return v8::Undefined(); return v8::Undefined();
} }
...@@ -175,7 +178,10 @@ void RunShell(v8::Handle<v8::Context> context) { ...@@ -175,7 +178,10 @@ void RunShell(v8::Handle<v8::Context> context) {
char* str = fgets(buffer, kBufferSize, stdin); char* str = fgets(buffer, kBufferSize, stdin);
if (str == NULL) break; if (str == NULL) break;
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
ExecuteString(v8::String::New(str), v8::String::New("(shell)"), true); ExecuteString(v8::String::New(str),
v8::String::New("(shell)"),
true,
true);
} }
printf("\n"); printf("\n");
} }
...@@ -184,25 +190,28 @@ void RunShell(v8::Handle<v8::Context> context) { ...@@ -184,25 +190,28 @@ void RunShell(v8::Handle<v8::Context> context) {
// Executes a string within the current v8 context. // Executes a string within the current v8 context.
bool ExecuteString(v8::Handle<v8::String> source, bool ExecuteString(v8::Handle<v8::String> source,
v8::Handle<v8::Value> name, v8::Handle<v8::Value> name,
bool print_result) { bool print_result,
bool report_exceptions) {
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::TryCatch try_catch; v8::TryCatch try_catch;
v8::Handle<v8::Script> script = v8::Script::Compile(source, name); v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
if (script.IsEmpty()) { if (script.IsEmpty()) {
// Print errors that happened during compilation. // Print errors that happened during compilation.
ReportException(&try_catch); if (report_exceptions)
ReportException(&try_catch);
return false; return false;
} else { } else {
v8::Handle<v8::Value> result = script->Run(); v8::Handle<v8::Value> result = script->Run();
if (result.IsEmpty()) { if (result.IsEmpty()) {
// Print errors that happened during execution. // Print errors that happened during execution.
ReportException(&try_catch); if (report_exceptions)
ReportException(&try_catch);
return false; return false;
} else { } else {
if (print_result && !result->IsUndefined()) { if (print_result && !result->IsUndefined()) {
// If all went well and the result wasn't undefined then print // If all went well and the result wasn't undefined then print
// the returned value. // the returned value.
v8::String::AsciiValue str(result); v8::String::Utf8Value str(result);
printf("%s\n", *str); printf("%s\n", *str);
} }
return true; return true;
...@@ -213,7 +222,7 @@ bool ExecuteString(v8::Handle<v8::String> source, ...@@ -213,7 +222,7 @@ bool ExecuteString(v8::Handle<v8::String> source,
void ReportException(v8::TryCatch* try_catch) { void ReportException(v8::TryCatch* try_catch) {
v8::HandleScope handle_scope; v8::HandleScope handle_scope;
v8::String::AsciiValue exception(try_catch->Exception()); v8::String::Utf8Value exception(try_catch->Exception());
v8::Handle<v8::Message> message = try_catch->Message(); v8::Handle<v8::Message> message = try_catch->Message();
if (message.IsEmpty()) { if (message.IsEmpty()) {
// V8 didn't provide any extra information about this error; just // V8 didn't provide any extra information about this error; just
...@@ -221,11 +230,11 @@ void ReportException(v8::TryCatch* try_catch) { ...@@ -221,11 +230,11 @@ void ReportException(v8::TryCatch* try_catch) {
printf("%s\n", *exception); printf("%s\n", *exception);
} else { } else {
// Print (filename):(line number): (message). // Print (filename):(line number): (message).
v8::String::AsciiValue filename(message->GetScriptResourceName()); v8::String::Utf8Value filename(message->GetScriptResourceName());
int linenum = message->GetLineNumber(); int linenum = message->GetLineNumber();
printf("%s:%i: %s\n", *filename, linenum, *exception); printf("%s:%i: %s\n", *filename, linenum, *exception);
// Print line of source code. // Print line of source code.
v8::String::AsciiValue sourceline(message->GetSourceLine()); v8::String::Utf8Value sourceline(message->GetSourceLine());
printf("%s\n", *sourceline); printf("%s\n", *sourceline);
// Print wavy underline (GetUnderline is deprecated). // Print wavy underline (GetUnderline is deprecated).
int start = message->GetStartColumn(); int start = message->GetStartColumn();
...@@ -237,5 +246,10 @@ void ReportException(v8::TryCatch* try_catch) { ...@@ -237,5 +246,10 @@ void ReportException(v8::TryCatch* try_catch) {
printf("^"); printf("^");
} }
printf("\n"); printf("\n");
v8::Handle<v8::String> stack_trace = message->GetStackTrace();
if (!stack_trace.IsEmpty()) {
v8::String::Utf8Value stack_trace_str(stack_trace);
printf("%s\n", *stack_trace_str);
}
} }
} }
...@@ -2629,13 +2629,40 @@ void V8::SetGlobalGCEpilogueCallback(GCCallback callback) { ...@@ -2629,13 +2629,40 @@ void V8::SetGlobalGCEpilogueCallback(GCCallback callback) {
} }
String::Utf8Value::Utf8Value(v8::Handle<v8::Value> obj) {
EnsureInitialized("v8::String::Utf8Value::Utf8Value()");
HandleScope scope;
TryCatch try_catch;
Handle<String> str = obj->ToString();
if (str.IsEmpty()) {
str_ = NULL;
length_ = 0;
} else {
length_ = str->Utf8Length();
str_ = i::NewArray<char>(length_ + 1);
str->WriteUtf8(str_);
}
}
String::Utf8Value::~Utf8Value() {
i::DeleteArray(str_);
}
String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) { String::AsciiValue::AsciiValue(v8::Handle<v8::Value> obj) {
EnsureInitialized("v8::String::AsciiValue::AsciiValue()"); EnsureInitialized("v8::String::AsciiValue::AsciiValue()");
HandleScope scope; HandleScope scope;
TryCatch try_catch;
Handle<String> str = obj->ToString(); Handle<String> str = obj->ToString();
int length = str->Length(); if (str.IsEmpty()) {
str_ = i::NewArray<char>(length + 1); str_ = NULL;
str->WriteAscii(str_); length_ = 0;
} else {
length_ = str->Length();
str_ = i::NewArray<char>(length_ + 1);
str->WriteAscii(str_);
}
} }
...@@ -2647,10 +2674,16 @@ String::AsciiValue::~AsciiValue() { ...@@ -2647,10 +2674,16 @@ String::AsciiValue::~AsciiValue() {
String::Value::Value(v8::Handle<v8::Value> obj) { String::Value::Value(v8::Handle<v8::Value> obj) {
EnsureInitialized("v8::String::Value::Value()"); EnsureInitialized("v8::String::Value::Value()");
HandleScope scope; HandleScope scope;
TryCatch try_catch;
Handle<String> str = obj->ToString(); Handle<String> str = obj->ToString();
int length = str->Length(); if (str.IsEmpty()) {
str_ = i::NewArray<uint16_t>(length + 1); str_ = NULL;
str->Write(str_); length_ = 0;
} else {
length_ = str->Length();
str_ = i::NewArray<uint16_t>(length_ + 1);
str->Write(str_);
}
} }
......
...@@ -74,8 +74,8 @@ void CheckEqualsHelper(const char* file, ...@@ -74,8 +74,8 @@ void CheckEqualsHelper(const char* file,
const char* value_source, const char* value_source,
v8::Handle<v8::Value> value) { v8::Handle<v8::Value> value) {
if (!expected->Equals(value)) { if (!expected->Equals(value)) {
v8::String::AsciiValue value_str(value); v8::String::Utf8Value value_str(value);
v8::String::AsciiValue expected_str(expected); v8::String::Utf8Value expected_str(expected);
V8_Fatal(file, line, V8_Fatal(file, line,
"CHECK_EQ(%s, %s) failed\n# Expected: %s\n# Found: %s", "CHECK_EQ(%s, %s) failed\n# Expected: %s\n# Found: %s",
expected_source, value_source, *expected_str, *value_str); expected_source, value_source, *expected_str, *value_str);
...@@ -90,7 +90,7 @@ void CheckNonEqualsHelper(const char* file, ...@@ -90,7 +90,7 @@ void CheckNonEqualsHelper(const char* file,
const char* value_source, const char* value_source,
v8::Handle<v8::Value> value) { v8::Handle<v8::Value> value) {
if (unexpected->Equals(value)) { if (unexpected->Equals(value)) {
v8::String::AsciiValue value_str(value); v8::String::Utf8Value value_str(value);
V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %s", V8_Fatal(file, line, "CHECK_NE(%s, %s) failed\n# Value: %s",
unexpected_source, value_source, *value_str); unexpected_source, value_source, *value_str);
} }
......
...@@ -148,6 +148,8 @@ function MakeGenericError(constructor, type, args) { ...@@ -148,6 +148,8 @@ function MakeGenericError(constructor, type, args) {
args[i] = elem.slice(0,20).concat("..."); args[i] = elem.slice(0,20).concat("...");
} }
} }
} else if (IS_UNDEFINED(args)) {
args = [];
} }
var e = new constructor(); var e = new constructor();
......
...@@ -439,7 +439,7 @@ function ToObject(x) { ...@@ -439,7 +439,7 @@ function ToObject(x) {
if (IS_STRING(x)) return new $String(x); if (IS_STRING(x)) return new $String(x);
if (IS_NUMBER(x)) return new $Number(x); if (IS_NUMBER(x)) return new $Number(x);
if (IS_BOOLEAN(x)) return new $Boolean(x); if (IS_BOOLEAN(x)) return new $Boolean(x);
if (x == null) throw %MakeTypeError('null_to_object'); if (x == null) throw %MakeTypeError('null_to_object', []);
return x; return x;
}; };
......
try {
delete (void 0).x;
} catch (e) {
print(e.toString());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment