Fixed bug #57. Introduced String::Utf8Value and replaced a bunch of
authorchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 10 Sep 2008 11:41:48 +0000 (11:41 +0000)
committerchristian.plesner.hansen@gmail.com <christian.plesner.hansen@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 10 Sep 2008 11:41:48 +0000 (11:41 +0000)
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

include/v8.h
samples/process.cc
samples/shell.cc
src/api.cc
src/checks.cc
src/messages.js
src/runtime.js
test/mjsunit/regress/regress-57.js [new file with mode: 0644]

index c72bb2e..430165a 100644 (file)
@@ -880,6 +880,21 @@ class EXPORT String : public Primitive {
   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.
    * Useful if you want to print the object.
    */
@@ -888,8 +903,10 @@ class EXPORT String : public Primitive {
     explicit AsciiValue(Handle<v8::Value> obj);
     ~AsciiValue();
     char* operator*() { return str_; }
+    int length() { return length_; }
    private:
     char* str_;
+    int length_;
   };
 
   /**
@@ -900,8 +917,10 @@ class EXPORT String : public Primitive {
     explicit Value(Handle<v8::Value> obj);
     ~Value();
     uint16_t* operator*() { return str_; }
+    int length() { return length_; }
    private:
     uint16_t* str_;
+    int length_;
   };
 };
 
index 57710b3..6567f08 100644 (file)
@@ -137,7 +137,7 @@ static Handle<Value> LogCallback(const Arguments& args) {
   if (args.Length() < 1) return v8::Undefined();
   HandleScope scope;
   Handle<Value> arg = args[0];
-  String::AsciiValue value(arg);
+  String::Utf8Value value(arg);
   HttpRequestProcessor::Log(*value);
   return v8::Undefined();
 }
@@ -206,7 +206,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
   // Compile the script and check for errors.
   Handle<Script> compiled_script = Script::Compile(script);
   if (compiled_script.IsEmpty()) {
-    String::AsciiValue error(try_catch.Exception());
+    String::Utf8Value error(try_catch.Exception());
     Log(*error);
     // The script failed to compile; bail out.
     return false;
@@ -216,7 +216,7 @@ bool JsHttpRequestProcessor::ExecuteScript(Handle<String> script) {
   Handle<Value> result = compiled_script->Run();
   if (result.IsEmpty()) {
     // 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);
     // Running the script failed; bail out.
     return false;
@@ -262,7 +262,7 @@ bool JsHttpRequestProcessor::Process(HttpRequest* request) {
   Handle<Value> argv[argc] = { request_obj };
   Handle<Value> result = process_->Call(context_->Global(), argc, argv);
   if (result.IsEmpty()) {
-    String::AsciiValue error(try_catch.Exception());
+    String::Utf8Value error(try_catch.Exception());
     Log(*error);
     return false;
   } else {
@@ -332,8 +332,8 @@ map<string, string>* JsHttpRequestProcessor::UnwrapMap(Handle<Object> obj) {
 // Convert a JavaScript string to a std::string.  To not bother too
 // much with string encodings we just use ascii.
 string ObjectToString(Local<Value> value) {
-  String::AsciiValue ascii_value(value);
-  return string(*ascii_value);
+  String::Utf8Value utf8_value(value);
+  return string(*utf8_value);
 }
 
 
index be5d0c6..704cfa9 100644 (file)
@@ -34,7 +34,8 @@
 void RunShell(v8::Handle<v8::Context> context);
 bool ExecuteString(v8::Handle<v8::String> source,
                    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> Load(const v8::Arguments& args);
 v8::Handle<v8::Value> Quit(const v8::Arguments& args);
@@ -81,7 +82,7 @@ int main(int argc, char* argv[]) {
         printf("Error reading '%s'\n", str);
         return 1;
       }
-      if (!ExecuteString(source, file_name, false))
+      if (!ExecuteString(source, file_name, false, true))
         return 1;
     }
   }
@@ -102,7 +103,7 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) {
     } else {
       printf(" ");
     }
-    v8::String::AsciiValue str(args[i]);
+    v8::String::Utf8Value str(args[i]);
     printf("%s", *str);
   }
   printf("\n");
@@ -116,12 +117,14 @@ v8::Handle<v8::Value> Print(const v8::Arguments& args) {
 v8::Handle<v8::Value> Load(const v8::Arguments& args) {
   for (int i = 0; i < args.Length(); i++) {
     v8::HandleScope handle_scope;
-    v8::String::AsciiValue file(args[i]);
+    v8::String::Utf8Value file(args[i]);
     v8::Handle<v8::String> source = ReadFile(*file);
     if (source.IsEmpty()) {
       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();
 }
@@ -175,7 +178,10 @@ void RunShell(v8::Handle<v8::Context> context) {
     char* str = fgets(buffer, kBufferSize, stdin);
     if (str == NULL) break;
     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");
 }
@@ -184,25 +190,28 @@ void RunShell(v8::Handle<v8::Context> context) {
 // Executes a string within the current v8 context.
 bool ExecuteString(v8::Handle<v8::String> source,
                    v8::Handle<v8::Value> name,
-                   bool print_result) {
+                   bool print_result,
+                   bool report_exceptions) {
   v8::HandleScope handle_scope;
   v8::TryCatch try_catch;
   v8::Handle<v8::Script> script = v8::Script::Compile(source, name);
   if (script.IsEmpty()) {
     // Print errors that happened during compilation.
-    ReportException(&try_catch);
+    if (report_exceptions)
+      ReportException(&try_catch);
     return false;
   } else {
     v8::Handle<v8::Value> result = script->Run();
     if (result.IsEmpty()) {
       // Print errors that happened during execution.
-      ReportException(&try_catch);
+      if (report_exceptions)
+        ReportException(&try_catch);
       return false;
     } else {
       if (print_result && !result->IsUndefined()) {
         // If all went well and the result wasn't undefined then print
         // the returned value.
-        v8::String::AsciiValue str(result);
+        v8::String::Utf8Value str(result);
         printf("%s\n", *str);
       }
       return true;
@@ -213,7 +222,7 @@ bool ExecuteString(v8::Handle<v8::String> source,
 
 void ReportException(v8::TryCatch* try_catch) {
   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();
   if (message.IsEmpty()) {
     // V8 didn't provide any extra information about this error; just
@@ -221,11 +230,11 @@ void ReportException(v8::TryCatch* try_catch) {
     printf("%s\n", *exception);
   } else {
     // Print (filename):(line number): (message).
-    v8::String::AsciiValue filename(message->GetScriptResourceName());
+    v8::String::Utf8Value filename(message->GetScriptResourceName());
     int linenum = message->GetLineNumber();
     printf("%s:%i: %s\n", *filename, linenum, *exception);
     // Print line of source code.
-    v8::String::AsciiValue sourceline(message->GetSourceLine());
+    v8::String::Utf8Value sourceline(message->GetSourceLine());
     printf("%s\n", *sourceline);
     // Print wavy underline (GetUnderline is deprecated).
     int start = message->GetStartColumn();
@@ -237,5 +246,10 @@ void ReportException(v8::TryCatch* try_catch) {
       printf("^");
     }
     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);
+    }
   }
 }
index 5637018..6d4904d 100644 (file)
@@ -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) {
   EnsureInitialized("v8::String::AsciiValue::AsciiValue()");
   HandleScope scope;
+  TryCatch try_catch;
   Handle<String> str = obj->ToString();
-  int length = str->Length();
-  str_ = i::NewArray<char>(length + 1);
-  str->WriteAscii(str_);
+  if (str.IsEmpty()) {
+    str_ = NULL;
+    length_ = 0;
+  } else {
+    length_ = str->Length();
+    str_ = i::NewArray<char>(length_ + 1);
+    str->WriteAscii(str_);
+  }
 }
 
 
@@ -2647,10 +2674,16 @@ String::AsciiValue::~AsciiValue() {
 String::Value::Value(v8::Handle<v8::Value> obj) {
   EnsureInitialized("v8::String::Value::Value()");
   HandleScope scope;
+  TryCatch try_catch;
   Handle<String> str = obj->ToString();
-  int length = str->Length();
-  str_ = i::NewArray<uint16_t>(length + 1);
-  str->Write(str_);
+  if (str.IsEmpty()) {
+    str_ = NULL;
+    length_ = 0;
+  } else {
+    length_ = str->Length();
+    str_ = i::NewArray<uint16_t>(length_ + 1);
+    str->Write(str_);
+  }
 }
 
 
index 22b7b7a..c01c9b2 100644 (file)
@@ -74,8 +74,8 @@ void CheckEqualsHelper(const char* file,
                        const char* value_source,
                        v8::Handle<v8::Value> value) {
   if (!expected->Equals(value)) {
-    v8::String::AsciiValue value_str(value);
-    v8::String::AsciiValue expected_str(expected);
+    v8::String::Utf8Value value_str(value);
+    v8::String::Utf8Value expected_str(expected);
     V8_Fatal(file, line,
              "CHECK_EQ(%s, %s) failed\n#   Expected: %s\n#   Found: %s",
              expected_source, value_source, *expected_str, *value_str);
@@ -90,7 +90,7 @@ void CheckNonEqualsHelper(const char* file,
                           const char* value_source,
                           v8::Handle<v8::Value> 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",
              unexpected_source, value_source, *value_str);
   }
index 994270d..d27502d 100644 (file)
@@ -148,6 +148,8 @@ function MakeGenericError(constructor, type, args) {
         args[i] = elem.slice(0,20).concat("...");
       }
     }
+  } else if (IS_UNDEFINED(args)) {
+    args = [];
   }
 
   var e = new constructor();
index 195d83d..46a61d8 100644 (file)
@@ -439,7 +439,7 @@ function ToObject(x) {
   if (IS_STRING(x)) return new $String(x);
   if (IS_NUMBER(x)) return new $Number(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;
 };
 
diff --git a/test/mjsunit/regress/regress-57.js b/test/mjsunit/regress/regress-57.js
new file mode 100644 (file)
index 0000000..58a592b
--- /dev/null
@@ -0,0 +1,5 @@
+try {
+  delete (void 0).x;
+} catch (e) {
+  print(e.toString());
+}