Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index c9d3f49ca9087e1cff82cfe1194fc413a0056278..0916b9398950ac5d4285b2652b7af461cce2cd5a 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -67,10 +67,18 @@ |
#include "vm-state-inl.h" |
#ifdef V8_I18N_SUPPORT |
+#include "i18n.h" |
#include "unicode/brkiter.h" |
+#include "unicode/calendar.h" |
#include "unicode/coll.h" |
#include "unicode/datefmt.h" |
+#include "unicode/dtfmtsym.h" |
+#include "unicode/dtptngen.h" |
+#include "unicode/locid.h" |
#include "unicode/numfmt.h" |
+#include "unicode/numsys.h" |
+#include "unicode/smpdtfmt.h" |
+#include "unicode/timezone.h" |
#include "unicode/uloc.h" |
#include "unicode/uversion.h" |
#endif |
@@ -13553,6 +13561,110 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) { |
result->set_length(Smi::FromInt(length)); |
return *result; |
} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateDateTimeFormat) { |
+ HandleScope scope(isolate); |
+ |
+ ASSERT(args.length() == 3); |
+ |
+ CONVERT_ARG_HANDLE_CHECKED(String, locale, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, options, 1); |
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, resolved, 2); |
+ |
+ Handle<ObjectTemplateInfo> date_format_template = |
+ I18N::GetTemplate(isolate); |
+ |
+ // Create an empty object wrapper. |
+ bool has_pending_exception = false; |
+ Handle<JSObject> local_object = Execution::InstantiateObject( |
+ date_format_template, &has_pending_exception); |
+ if (has_pending_exception) { |
+ ASSERT(isolate->has_pending_exception()); |
+ return Failure::Exception(); |
+ } |
+ |
+ // Set date time formatter as internal field of the resulting JS object. |
+ icu::SimpleDateFormat* date_format = DateFormat::InitializeDateTimeFormat( |
+ isolate, locale, options, resolved); |
+ |
+ if (!date_format) return isolate->ThrowIllegalOperation(); |
+ |
+ local_object->SetInternalField(0, reinterpret_cast<Smi*>(date_format)); |
+ |
+ RETURN_IF_EMPTY_HANDLE(isolate, |
+ JSObject::SetLocalPropertyIgnoreAttributes( |
+ local_object, |
+ isolate->factory()->NewStringFromAscii(CStrVector("dateFormat")), |
+ isolate->factory()->NewStringFromAscii(CStrVector("valid")), |
+ NONE)); |
+ |
+ Persistent<v8::Object> wrapper(reinterpret_cast<v8::Isolate*>(isolate), |
+ v8::Utils::ToLocal(local_object)); |
+ // Make object handle weak so we can delete the data format once GC kicks in. |
+ wrapper.MakeWeak<void>(NULL, &DateFormat::DeleteDateFormat); |
+ Handle<Object> result = Utils::OpenPersistent(wrapper); |
+ wrapper.ClearAndLeak(); |
+ return *result; |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateFormat) { |
+ HandleScope scope(isolate); |
+ |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 1); |
+ |
+ bool has_pending_exception = false; |
+ double millis = Execution::ToNumber(date, &has_pending_exception)->Number(); |
+ if (has_pending_exception) { |
+ ASSERT(isolate->has_pending_exception()); |
+ return Failure::Exception(); |
+ } |
+ |
+ icu::SimpleDateFormat* date_format = |
+ DateFormat::UnpackDateFormat(isolate, date_format_holder); |
+ if (!date_format) return isolate->ThrowIllegalOperation(); |
+ |
+ icu::UnicodeString result; |
+ date_format->format(millis, result); |
+ |
+ return *isolate->factory()->NewStringFromTwoByte( |
+ Vector<const uint16_t>( |
+ reinterpret_cast<const uint16_t*>(result.getBuffer()), |
+ result.length())); |
+} |
+ |
+ |
+RUNTIME_FUNCTION(MaybeObject*, Runtime_InternalDateParse) { |
+ HandleScope scope(isolate); |
+ |
+ ASSERT(args.length() == 2); |
+ |
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, date_format_holder, 0); |
+ CONVERT_ARG_HANDLE_CHECKED(String, date_string, 1); |
+ |
+ v8::String::Utf8Value utf8_date(v8::Utils::ToLocal(date_string)); |
+ icu::UnicodeString u_date(icu::UnicodeString::fromUTF8(*utf8_date)); |
+ icu::SimpleDateFormat* date_format = |
+ DateFormat::UnpackDateFormat(isolate, date_format_holder); |
+ if (!date_format) return isolate->ThrowIllegalOperation(); |
+ |
+ UErrorCode status = U_ZERO_ERROR; |
+ UDate date = date_format->parse(u_date, status); |
+ if (U_FAILURE(status)) return isolate->heap()->undefined_value(); |
+ |
+ bool has_pending_exception = false; |
+ Handle<JSDate> result = Handle<JSDate>::cast( |
+ Execution::NewDate(static_cast<double>(date), &has_pending_exception)); |
+ if (has_pending_exception) { |
+ ASSERT(isolate->has_pending_exception()); |
+ return Failure::Exception(); |
+ } |
+ return *result; |
+} |
#endif // V8_I18N_SUPPORT |