Don't copy Persistent handles in callbacks.

Persistent handles will become uncopyable in the near future,
see crbug.com/236290 .


git-svn-id: http://v8-i18n.googlecode.com/svn/trunk@181 24c52dca-d3ef-abce-e343-6dbe4d066545
diff --git a/src/break-iterator.cc b/src/break-iterator.cc
index d54d997..73e45b6 100644
--- a/src/break-iterator.cc
+++ b/src/break-iterator.cc
@@ -96,22 +96,22 @@
   return text;
 }
 
-v8::Handle<v8::Value> BreakIterator::JSInternalBreakIteratorAdoptText(
-    const v8::Arguments& args) {
+void BreakIterator::JSInternalBreakIteratorAdoptText(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 2 || !args[0]->IsObject() || !args[1]->IsString()) {
-    return v8::ThrowException(v8::Exception::Error(
+    v8::ThrowException(v8::Exception::Error(
         v8::String::New(
             "Internal error. Iterator and text have to be specified.")));
+    return;
   }
 
   icu::BreakIterator* break_iterator = UnpackBreakIterator(args[0]->ToObject());
   if (!break_iterator) {
-    return ThrowUnexpectedObjectError();
+    ThrowUnexpectedObjectError();
+    return;
   }
 
   break_iterator->setText(*ResetAdoptedText(args[0]->ToObject(), args[1]));
-
-  return v8::Undefined();
 }
 
 v8::Handle<v8::Value> BreakIterator::JSInternalBreakIteratorFirst(
@@ -171,14 +171,13 @@
   }
 }
 
-v8::Handle<v8::Value> BreakIterator::JSCreateBreakIterator(
-    const v8::Arguments& args) {
-  if (args.Length() != 3 ||
-      !args[0]->IsString() ||
-      !args[1]->IsObject() ||
+void BreakIterator::JSCreateBreakIterator(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsObject() ||
       !args[2]->IsObject()) {
-    return v8::ThrowException(v8::Exception::Error(
+    v8::ThrowException(v8::Exception::Error(
         v8::String::New("Internal error, wrong parameters.")));
+    return;
   }
 
   v8::Isolate* isolate = args.GetIsolate();
@@ -190,7 +189,8 @@
   // But the handle shouldn't be empty.
   // That can happen if there was a stack overflow when creating the object.
   if (local_object.IsEmpty()) {
-    return local_object;
+    args.GetReturnValue().Set(local_object);
+    return;
   }
 
   // Set break iterator as internal field of the resulting JS object.
@@ -198,8 +198,9 @@
       args[0]->ToString(), args[1]->ToObject(), args[2]->ToObject());
 
   if (!break_iterator) {
-    return v8::ThrowException(v8::Exception::Error(v8::String::New(
+    v8::ThrowException(v8::Exception::Error(v8::String::New(
         "Internal error. Couldn't create ICU break iterator.")));
+    return;
   } else {
     local_object->SetAlignedPointerInInternalField(0, break_iterator);
     // Make sure that the pointer to adopted text is NULL.
@@ -208,16 +209,17 @@
     v8::TryCatch try_catch;
     local_object->Set(v8::String::New("breakIterator"), v8::String::New("valid"));
     if (try_catch.HasCaught()) {
-      return v8::ThrowException(v8::Exception::Error(
+      v8::ThrowException(v8::Exception::Error(
           v8::String::New("Internal error, couldn't set property.")));
+      return;
     }
   }
 
   v8::Persistent<v8::Object> wrapper(isolate, local_object);
   // Make object handle weak so we can delete iterator once GC kicks in.
   wrapper.MakeWeak<void>(isolate, NULL, &DeleteBreakIterator);
-
-  return wrapper;
+  args.GetReturnValue().Set(wrapper);
+  wrapper.ClearAndLeak();
 }
 
 static icu::BreakIterator* InitializeBreakIterator(
diff --git a/src/break-iterator.h b/src/break-iterator.h
index 7c1970c..f7d02f9 100644
--- a/src/break-iterator.h
+++ b/src/break-iterator.h
@@ -27,7 +27,8 @@
 
 class BreakIterator {
  public:
-  static v8::Handle<v8::Value> JSCreateBreakIterator(const v8::Arguments& args);
+  static void JSCreateBreakIterator(
+      const v8::FunctionCallbackInfo<v8::Value>& args);
 
   // Helper methods for various bindings.
 
@@ -41,8 +42,8 @@
 				  void* param);
 
   // Assigns new text to the iterator.
-  static v8::Handle<v8::Value> JSInternalBreakIteratorAdoptText(
-      const v8::Arguments& args);
+  static void JSInternalBreakIteratorAdoptText(
+      const v8::FunctionCallbackInfo<v8::Value>& args);
 
   // Moves iterator to the beginning of the string and returns new position.
   static v8::Handle<v8::Value> JSInternalBreakIteratorFirst(
diff --git a/src/collator.cc b/src/collator.cc
index 735e921..8460aee 100644
--- a/src/collator.cc
+++ b/src/collator.cc
@@ -76,17 +76,19 @@
 }
 
 // static
-v8::Handle<v8::Value> Collator::JSInternalCompare(
-    const v8::Arguments& args) {
+void Collator::JSInternalCompare(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 3 || !args[0]->IsObject() ||
       !args[1]->IsString() || !args[2]->IsString()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
+    v8::ThrowException(v8::Exception::SyntaxError(
         v8::String::New("Collator and two string arguments are required.")));
+    return;
   }
 
   icu::Collator* collator = UnpackCollator(args[0]->ToObject());
   if (!collator) {
-    return ThrowUnexpectedObjectError();
+    ThrowUnexpectedObjectError();
+    return;
   }
 
   v8::String::Value string_value1(args[1]);
@@ -98,21 +100,21 @@
       string1, string_value1.length(), string2, string_value2.length(), status);
 
   if (U_FAILURE(status)) {
-    return ThrowExceptionForICUError(
+    ThrowExceptionForICUError(
         "Internal error. Unexpected failure in Collator.compare.");
+    return;
   }
 
-  return v8::Int32::New(result);
+  args.GetReturnValue().Set(result);
 }
 
-v8::Handle<v8::Value> Collator::JSCreateCollator(
-    const v8::Arguments& args) {
-  if (args.Length() != 3 ||
-      !args[0]->IsString() ||
-      !args[1]->IsObject() ||
+void Collator::JSCreateCollator(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
+  if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsObject() ||
       !args[2]->IsObject()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
+    v8::ThrowException(v8::Exception::SyntaxError(
         v8::String::New("Internal error, wrong parameters.")));
+    return;
   }
 
   v8::Isolate* isolate = args.GetIsolate();
@@ -124,7 +126,8 @@
   // But the handle shouldn't be empty.
   // That can happen if there was a stack overflow when creating the object.
   if (local_object.IsEmpty()) {
-    return local_object;
+    args.GetReturnValue().Set(local_object);
+    return;
   }
 
   // Set collator as internal field of the resulting JS object.
@@ -132,8 +135,9 @@
       args[0]->ToString(), args[1]->ToObject(), args[2]->ToObject());
 
   if (!collator) {
-    return v8::ThrowException(v8::Exception::Error(v8::String::New(
+    v8::ThrowException(v8::Exception::Error(v8::String::New(
         "Internal error. Couldn't create ICU collator.")));
+    return;
   } else {
     local_object->SetAlignedPointerInInternalField(0, collator);
 
@@ -141,16 +145,17 @@
     v8::TryCatch try_catch;
     local_object->Set(v8::String::New("collator"), v8::String::New("valid"));
     if (try_catch.HasCaught()) {
-      return v8::ThrowException(v8::Exception::Error(
+      v8::ThrowException(v8::Exception::Error(
           v8::String::New("Internal error, couldn't set property.")));
+      return;
     }
   }
 
   v8::Persistent<v8::Object> wrapper(isolate, local_object);
   // Make object handle weak so we can delete iterator once GC kicks in.
   wrapper.MakeWeak<void>(isolate, NULL, &DeleteCollator);
-
-  return wrapper;
+  args.GetReturnValue().Set(wrapper);
+  wrapper.ClearAndLeak();
 }
 
 static icu::Collator* InitializeCollator(v8::Handle<v8::String> locale,
diff --git a/src/collator.h b/src/collator.h
index a7a0f0e..2321ba2 100644
--- a/src/collator.h
+++ b/src/collator.h
@@ -27,7 +27,7 @@
 
 class Collator {
  public:
-  static v8::Handle<v8::Value> JSCreateCollator(const v8::Arguments& args);
+  static void JSCreateCollator(const v8::FunctionCallbackInfo<v8::Value>& args);
 
   // Helper methods for various bindings.
 
@@ -42,7 +42,8 @@
 
   // Compare two strings and returns -1, 0 and 1 depending on
   // whether string1 is smaller than, equal to or larger than string2.
-  static v8::Handle<v8::Value> JSInternalCompare(const v8::Arguments& args);
+  static void JSInternalCompare(
+      const v8::FunctionCallbackInfo<v8::Value>& args);
 
  private:
   Collator() {}
diff --git a/src/date-format.cc b/src/date-format.cc
index 96e61c4..12b0639 100644
--- a/src/date-format.cc
+++ b/src/date-format.cc
@@ -117,14 +117,15 @@
   return v8::Date::New(static_cast<double>(date));
 }
 
-v8::Handle<v8::Value> DateFormat::JSCreateDateTimeFormat(
-    const v8::Arguments& args) {
+void DateFormat::JSCreateDateTimeFormat(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 3 ||
       !args[0]->IsString() ||
       !args[1]->IsObject() ||
       !args[2]->IsObject()) {
-    return v8::ThrowException(v8::Exception::Error(
+    v8::ThrowException(v8::Exception::Error(
         v8::String::New("Internal error, wrong parameters.")));
+    return;
   }
 
   v8::Isolate* isolate = args.GetIsolate();
@@ -136,7 +137,8 @@
   // But the handle shouldn't be empty.
   // That can happen if there was a stack overflow when creating the object.
   if (local_object.IsEmpty()) {
-    return local_object;
+    args.GetReturnValue().Set(local_object);
+    return;
   }
 
   // Set date time formatter as internal field of the resulting JS object.
@@ -144,24 +146,26 @@
       args[0]->ToString(), args[1]->ToObject(), args[2]->ToObject());
 
   if (!date_format) {
-    return v8::ThrowException(v8::Exception::Error(v8::String::New(
+    v8::ThrowException(v8::Exception::Error(v8::String::New(
         "Internal error. Couldn't create ICU date time formatter.")));
+    return;
   } else {
     local_object->SetAlignedPointerInInternalField(0, date_format);
 
     v8::TryCatch try_catch;
     local_object->Set(v8::String::New("dateFormat"), v8::String::New("valid"));
     if (try_catch.HasCaught()) {
-      return v8::ThrowException(v8::Exception::Error(
+      v8::ThrowException(v8::Exception::Error(
           v8::String::New("Internal error, couldn't set property.")));
+      return;
     }
   }
 
   v8::Persistent<v8::Object> wrapper(isolate, local_object);
   // Make object handle weak so we can delete iterator once GC kicks in.
   wrapper.MakeWeak<void>(isolate, NULL, &DeleteDateFormat);
-
-  return wrapper;
+  args.GetReturnValue().Set(wrapper);
+  wrapper.ClearAndLeak();
 }
 
 static icu::SimpleDateFormat* InitializeDateTimeFormat(
diff --git a/src/date-format.h b/src/date-format.h
index 28e2541..510eff2 100644
--- a/src/date-format.h
+++ b/src/date-format.h
@@ -26,8 +26,8 @@
 
 class DateFormat {
  public:
-  static v8::Handle<v8::Value> JSCreateDateTimeFormat(
-      const v8::Arguments& args);
+  static void JSCreateDateTimeFormat(
+      const v8::FunctionCallbackInfo<v8::Value>& args);
 
   // Helper methods for various bindings.
 
diff --git a/src/locale.cc b/src/locale.cc
index fe14568..595db53 100644
--- a/src/locale.cc
+++ b/src/locale.cc
@@ -25,11 +25,12 @@
 
 namespace v8_i18n {
 
-v8::Handle<v8::Value> JSCanonicalizeLanguageTag(const v8::Arguments& args) {
+void JSCanonicalizeLanguageTag(const v8::FunctionCallbackInfo<v8::Value>& args) {
   // Expect locale id which is a string.
   if (args.Length() != 1 || !args[0]->IsString()) {
-    return v8::ThrowException(v8::Exception::SyntaxError(
+    v8::ThrowException(v8::Exception::SyntaxError(
         v8::String::New("Locale identifier, as a string, is required.")));
+    return;
   }
 
   UErrorCode error = U_ZERO_ERROR;
@@ -42,13 +43,15 @@
 
   v8::String::AsciiValue locale_id(args[0]->ToString());
   if (*locale_id == NULL) {
-    return v8::String::New(kInvalidTag);
+    args.GetReturnValue().Set(v8::String::New(kInvalidTag));
+    return;
   }
 
   uloc_forLanguageTag(*locale_id, icu_result, ULOC_FULLNAME_CAPACITY,
                       &icu_length, &error);
   if (U_FAILURE(error) || icu_length == 0) {
-    return v8::String::New(kInvalidTag);
+    args.GetReturnValue().Set(v8::String::New(kInvalidTag));
+    return;
   }
 
   char result[ULOC_FULLNAME_CAPACITY];
@@ -57,10 +60,11 @@
   uloc_toLanguageTag(icu_result, result, ULOC_FULLNAME_CAPACITY, TRUE, &error);
 
   if (U_FAILURE(error)) {
-    return v8::String::New(kInvalidTag);
+    args.GetReturnValue().Set(v8::String::New(kInvalidTag));
+    return;
   }
 
-  return v8::String::New(result);
+  args.GetReturnValue().Set(v8::String::New(result));
 }
 
 v8::Handle<v8::Value> JSAvailableLocalesOf(const v8::Arguments& args) {
diff --git a/src/locale.h b/src/locale.h
index 4d12d24..c128fd2 100644
--- a/src/locale.h
+++ b/src/locale.h
@@ -22,7 +22,7 @@
 
 // Canonicalizes the BCP47 language tag using BCP47 rules.
 // Returns 'invalid-tag' in case input was not well formed.
-v8::Handle<v8::Value> JSCanonicalizeLanguageTag(const v8::Arguments& args);
+void JSCanonicalizeLanguageTag(const v8::FunctionCallbackInfo<v8::Value>& args);
 
 // Returns a list of available locales for collator, date or number formatter.
 v8::Handle<v8::Value> JSAvailableLocalesOf(const v8::Arguments& args);
diff --git a/src/number-format.cc b/src/number-format.cc
index 129c3c1..c2ee618 100644
--- a/src/number-format.cc
+++ b/src/number-format.cc
@@ -143,14 +143,15 @@
   return v8::Undefined();
 }
 
-v8::Handle<v8::Value> NumberFormat::JSCreateNumberFormat(
-    const v8::Arguments& args) {
+void NumberFormat::JSCreateNumberFormat(
+    const v8::FunctionCallbackInfo<v8::Value>& args) {
   if (args.Length() != 3 ||
       !args[0]->IsString() ||
       !args[1]->IsObject() ||
       !args[2]->IsObject()) {
-    return v8::ThrowException(v8::Exception::Error(
+    v8::ThrowException(v8::Exception::Error(
         v8::String::New("Internal error, wrong parameters.")));
+    return;
   }
 
   v8::Isolate* isolate = args.GetIsolate();
@@ -162,7 +163,8 @@
   // But the handle shouldn't be empty.
   // That can happen if there was a stack overflow when creating the object.
   if (local_object.IsEmpty()) {
-    return local_object;
+    args.GetReturnValue().Set(local_object);
+    return;
   }
 
   // Set number formatter as internal field of the resulting JS object.
@@ -170,24 +172,26 @@
       args[0]->ToString(), args[1]->ToObject(), args[2]->ToObject());
 
   if (!number_format) {
-    return v8::ThrowException(v8::Exception::Error(v8::String::New(
+    v8::ThrowException(v8::Exception::Error(v8::String::New(
         "Internal error. Couldn't create ICU number formatter.")));
+    return;
   } else {
     local_object->SetAlignedPointerInInternalField(0, number_format);
 
     v8::TryCatch try_catch;
     local_object->Set(v8::String::New("numberFormat"), v8::String::New("valid"));
     if (try_catch.HasCaught()) {
-      return v8::ThrowException(v8::Exception::Error(
+      v8::ThrowException(v8::Exception::Error(
           v8::String::New("Internal error, couldn't set property.")));
+      return;
     }
   }
 
   v8::Persistent<v8::Object> wrapper(isolate, local_object);
   // Make object handle weak so we can delete iterator once GC kicks in.
   wrapper.MakeWeak<void>(isolate, NULL, &DeleteNumberFormat);
-
-  return wrapper;
+  args.GetReturnValue().Set(wrapper);
+  wrapper.ClearAndLeak();
 }
 
 static icu::DecimalFormat* InitializeNumberFormat(
diff --git a/src/number-format.h b/src/number-format.h
index 275099a..8306ce3 100644
--- a/src/number-format.h
+++ b/src/number-format.h
@@ -26,7 +26,8 @@
 
 class NumberFormat {
  public:
-  static v8::Handle<v8::Value> JSCreateNumberFormat(const v8::Arguments& args);
+  static void JSCreateNumberFormat(
+      const v8::FunctionCallbackInfo<v8::Value>& args);
 
   // Helper methods for various bindings.