Commit 02914097 authored by jochen@chromium.org's avatar jochen@chromium.org

Move i18n extension's date-format C++ code to runtime

BUG=v8:2745
R=dcarney@chromium.org, mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/22411003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16086 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 213fd4b6
...@@ -235,7 +235,6 @@ function toDateTimeOptions(options, required, defaults) { ...@@ -235,7 +235,6 @@ function toDateTimeOptions(options, required, defaults) {
* Useful for subclassing. * Useful for subclassing.
*/ */
function initializeDateTimeFormat(dateFormat, locales, options) { function initializeDateTimeFormat(dateFormat, locales, options) {
native function NativeJSCreateDateTimeFormat();
if (dateFormat.hasOwnProperty('__initializedIntlObject')) { if (dateFormat.hasOwnProperty('__initializedIntlObject')) {
throw new TypeError('Trying to re-initialize DateTimeFormat object.'); throw new TypeError('Trying to re-initialize DateTimeFormat object.');
...@@ -292,7 +291,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) { ...@@ -292,7 +291,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
year: {writable: true} year: {writable: true}
}); });
var formatter = NativeJSCreateDateTimeFormat( var formatter = %CreateDateTimeFormat(
requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved); requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved);
if (tz !== undefined && tz !== resolved.timeZone) { if (tz !== undefined && tz !== resolved.timeZone) {
...@@ -409,8 +408,6 @@ function initializeDateTimeFormat(dateFormat, locales, options) { ...@@ -409,8 +408,6 @@ function initializeDateTimeFormat(dateFormat, locales, options) {
* DateTimeFormat. * DateTimeFormat.
*/ */
function formatDate(formatter, dateValue) { function formatDate(formatter, dateValue) {
native function NativeJSInternalDateFormat();
var dateMs; var dateMs;
if (dateValue === undefined) { if (dateValue === undefined) {
dateMs = Date.now(); dateMs = Date.now();
...@@ -422,7 +419,7 @@ function formatDate(formatter, dateValue) { ...@@ -422,7 +419,7 @@ function formatDate(formatter, dateValue) {
throw new RangeError('Provided date is not in valid range.'); throw new RangeError('Provided date is not in valid range.');
} }
return NativeJSInternalDateFormat(formatter.formatter, new Date(dateMs)); return %InternalDateFormat(formatter.formatter, new Date(dateMs));
} }
...@@ -433,8 +430,7 @@ function formatDate(formatter, dateValue) { ...@@ -433,8 +430,7 @@ function formatDate(formatter, dateValue) {
* Returns undefined if date string cannot be parsed. * Returns undefined if date string cannot be parsed.
*/ */
function parseDate(formatter, value) { function parseDate(formatter, value) {
native function NativeJSInternalDateParse(); return %InternalDateParse(formatter.formatter, String(value));
return NativeJSInternalDateParse(formatter.formatter, String(value));
} }
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#include "break-iterator.h" #include "break-iterator.h"
#include "collator.h" #include "collator.h"
#include "date-format.h"
#include "natives.h" #include "natives.h"
#include "number-format.h" #include "number-format.h"
...@@ -48,15 +47,6 @@ Extension::Extension() ...@@ -48,15 +47,6 @@ Extension::Extension()
v8::Handle<v8::FunctionTemplate> Extension::GetNativeFunction( v8::Handle<v8::FunctionTemplate> Extension::GetNativeFunction(
v8::Handle<v8::String> name) { v8::Handle<v8::String> name) {
// Date format and parse.
if (name->Equals(v8::String::New("NativeJSCreateDateTimeFormat"))) {
return v8::FunctionTemplate::New(DateFormat::JSCreateDateTimeFormat);
} else if (name->Equals(v8::String::New("NativeJSInternalDateFormat"))) {
return v8::FunctionTemplate::New(DateFormat::JSInternalFormat);
} else if (name->Equals(v8::String::New("NativeJSInternalDateParse"))) {
return v8::FunctionTemplate::New(DateFormat::JSInternalParse);
}
// Number format and parse. // Number format and parse.
if (name->Equals(v8::String::New("NativeJSCreateNumberFormat"))) { if (name->Equals(v8::String::New("NativeJSCreateNumberFormat"))) {
return v8::FunctionTemplate::New(NumberFormat::JSCreateNumberFormat); return v8::FunctionTemplate::New(NumberFormat::JSCreateNumberFormat);
......
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// limitations under the License. // limitations under the License.
#ifndef V8_EXTENSIONS_I18N_DATE_FORMAT_H_ #ifndef V8_I18N_H_
#define V8_EXTENSIONS_I18N_DATE_FORMAT_H_ #define V8_I18N_H_
#include "unicode/uversion.h" #include "unicode/uversion.h"
#include "v8.h" #include "v8.h"
...@@ -36,36 +36,44 @@ namespace U_ICU_NAMESPACE { ...@@ -36,36 +36,44 @@ namespace U_ICU_NAMESPACE {
class SimpleDateFormat; class SimpleDateFormat;
} }
namespace v8_i18n { namespace v8 {
namespace internal {
class DateFormat { class I18N {
public: public:
static void JSCreateDateTimeFormat( // Creates an ObjectTemplate with one internal field.
const v8::FunctionCallbackInfo<v8::Value>& args); static Handle<ObjectTemplateInfo> GetTemplate(Isolate* isolate);
// Creates an ObjectTemplate with two internal fields.
static Handle<ObjectTemplateInfo> GetTemplate2(Isolate* isolate);
private:
I18N();
};
// Helper methods for various bindings. class DateFormat {
public:
// Create a formatter for the specificied locale and options. Returns the
// resolved settings for the locale / options.
static icu::SimpleDateFormat* InitializeDateTimeFormat(
Isolate* isolate,
Handle<String> locale,
Handle<JSObject> options,
Handle<JSObject> resolved);
// Unpacks date format object from corresponding JavaScript object. // Unpacks date format object from corresponding JavaScript object.
static icu::SimpleDateFormat* UnpackDateFormat( static icu::SimpleDateFormat* UnpackDateFormat(Isolate* isolate,
v8::Handle<v8::Object> obj); Handle<JSObject> obj);
// Release memory we allocated for the DateFormat once the JS object that // Release memory we allocated for the DateFormat once the JS object that
// holds the pointer gets garbage collected. // holds the pointer gets garbage collected.
static void DeleteDateFormat(v8::Isolate* isolate, static void DeleteDateFormat(v8::Isolate* isolate,
v8::Persistent<v8::Object>* object, Persistent<v8::Object>* object,
void* param); void* param);
// Formats date and returns corresponding string.
static void JSInternalFormat(const v8::FunctionCallbackInfo<v8::Value>& args);
// Parses date and returns corresponding Date object or undefined if parse
// failed.
static void JSInternalParse(const v8::FunctionCallbackInfo<v8::Value>& args);
private: private:
DateFormat(); DateFormat();
}; };
} // namespace v8_i18n } } // namespace v8::internal
#endif // V8_EXTENSIONS_I18N_DATE_FORMAT_H_ #endif // V8_I18N_H_
...@@ -67,10 +67,18 @@ ...@@ -67,10 +67,18 @@
#include "vm-state-inl.h" #include "vm-state-inl.h"
#ifdef V8_I18N_SUPPORT #ifdef V8_I18N_SUPPORT
#include "i18n.h"
#include "unicode/brkiter.h" #include "unicode/brkiter.h"
#include "unicode/calendar.h"
#include "unicode/coll.h" #include "unicode/coll.h"
#include "unicode/datefmt.h" #include "unicode/datefmt.h"
#include "unicode/dtfmtsym.h"
#include "unicode/dtptngen.h"
#include "unicode/locid.h"
#include "unicode/numfmt.h" #include "unicode/numfmt.h"
#include "unicode/numsys.h"
#include "unicode/smpdtfmt.h"
#include "unicode/timezone.h"
#include "unicode/uloc.h" #include "unicode/uloc.h"
#include "unicode/uversion.h" #include "unicode/uversion.h"
#endif #endif
...@@ -13553,6 +13561,110 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) { ...@@ -13553,6 +13561,110 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetLanguageTagVariants) {
result->set_length(Smi::FromInt(length)); result->set_length(Smi::FromInt(length));
return *result; 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 #endif // V8_I18N_SUPPORT
......
...@@ -543,6 +543,11 @@ namespace internal { ...@@ -543,6 +543,11 @@ namespace internal {
F(AvailableLocalesOf, 1, 1) \ F(AvailableLocalesOf, 1, 1) \
F(GetDefaultICULocale, 0, 1) \ F(GetDefaultICULocale, 0, 1) \
F(GetLanguageTagVariants, 1, 1) \ F(GetLanguageTagVariants, 1, 1) \
\
/* Date format and parse. */ \
F(CreateDateTimeFormat, 3, 1) \
F(InternalDateFormat, 2, 1) \
F(InternalDateParse, 2, 1) \
#else #else
#define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F) #define RUNTIME_FUNCTION_LIST_I18N_SUPPORT(F)
......
...@@ -823,12 +823,12 @@ ...@@ -823,12 +823,12 @@
}], }],
['v8_enable_i18n_support==1', { ['v8_enable_i18n_support==1', {
'sources': [ 'sources': [
'../../src/i18n.cc',
'../../src/i18n.h',
'../../src/extensions/i18n/break-iterator.cc', '../../src/extensions/i18n/break-iterator.cc',
'../../src/extensions/i18n/break-iterator.h', '../../src/extensions/i18n/break-iterator.h',
'../../src/extensions/i18n/collator.cc', '../../src/extensions/i18n/collator.cc',
'../../src/extensions/i18n/collator.h', '../../src/extensions/i18n/collator.h',
'../../src/extensions/i18n/date-format.cc',
'../../src/extensions/i18n/date-format.h',
'../../src/extensions/i18n/i18n-extension.cc', '../../src/extensions/i18n/i18n-extension.cc',
'../../src/extensions/i18n/i18n-extension.h', '../../src/extensions/i18n/i18n-extension.h',
'../../src/extensions/i18n/i18n-utils.cc', '../../src/extensions/i18n/i18n-utils.cc',
......
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