author | Norbert Lindenberg <mozilladev@lindenbergsoftware.com> |
Thu, 14 Mar 2013 14:22:24 -0700 | |
changeset 124949 | e1cc50bfee41a2d6486e77f2714a1eaa2833a482 |
parent 124948 | 9ea11ddff33b37316fab484873f228f36ae3b41a |
child 124950 | f723856dac075cae03c17ab8c8532a69e37b4732 |
push id | 24696 |
push user | jwalden@mit.edu |
push date | Fri, 15 Mar 2013 17:45:29 +0000 |
treeherder | mozilla-inbound@ba0b144c146f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jwalden |
bugs | 837957 |
milestone | 22.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -4,31 +4,49 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * The Intl module specified by standard ECMA-402, * ECMAScript Internationalization API Specification. */ +#include <string.h> + #include "jsapi.h" #include "jsatom.h" #include "jscntxt.h" #include "jsinterp.h" #include "jsobj.h" #include "builtin/Intl.h" #include "vm/GlobalObject.h" #include "vm/Stack.h" +#if ENABLE_INTL_API +#include "unicode/locid.h" +#include "unicode/numsys.h" +#include "unicode/ucal.h" +#include "unicode/ucol.h" +#include "unicode/udat.h" +#include "unicode/udatpg.h" +#include "unicode/uenum.h" +#include "unicode/unum.h" +#include "unicode/ustring.h" +#endif +#include "unicode/utypes.h" + #include "jsobjinlines.h" -#include "unicode/utypes.h" +using namespace js; -using namespace js; +#if ENABLE_INTL_API +using icu::Locale; +using icu::NumberingSystem; +#endif /******************** ICU stubs ********************/ #if !ENABLE_INTL_API /* * When the Internationalization API isn't enabled, we also shouldn't link @@ -419,16 +437,140 @@ IntlInitialize(JSContext *cx, HandleObje args.setThis(NullValue()); args[0] = ObjectValue(*obj); args[1] = locales; args[2] = options; return Invoke(cx, args); } +// CountAvailable and GetAvailable describe the signatures used for ICU API +// to determine available locales for various functionality. +typedef int32_t +(* CountAvailable)(void); + +typedef const char * +(* GetAvailable)(int32_t localeIndex); + +SUPPRESS_UNUSED_WARNING static bool +intl_availableLocales(JSContext *cx, CountAvailable countAvailable, + GetAvailable getAvailable, MutableHandleValue result) +{ + RootedObject locales(cx, NewObjectWithGivenProto(cx, &ObjectClass, NULL, NULL)); + if (!locales) + return false; + +#if ENABLE_INTL_API + uint32_t count = countAvailable(); + RootedValue t(cx, BooleanValue(true)); + for (uint32_t i = 0; i < count; i++) { + const char *locale = getAvailable(i); + ScopedJSFreePtr<char> lang(JS_strdup(cx, locale)); + if (!lang) + return false; + char *p; + while ((p = strchr(lang, '_'))) + *p = '-'; + RootedAtom a(cx, Atomize(cx, lang, strlen(lang))); + if (!a) + return false; + if (!JSObject::defineProperty(cx, locales, a->asPropertyName(), t, + JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE)) + { + return false; + } + } +#endif + result.setObject(*locales); + return true; +} + +/** + * Returns the object holding the internal properties for obj. + */ +SUPPRESS_UNUSED_WARNING static bool +GetInternals(JSContext *cx, HandleObject obj, MutableHandleObject internals) +{ + RootedValue getInternalsValue(cx); + if (!cx->global()->getIntrinsicValue(cx, cx->names().getInternals, &getInternalsValue)) + return false; + JS_ASSERT(getInternalsValue.isObject()); + JS_ASSERT(getInternalsValue.toObject().isFunction()); + + InvokeArgsGuard args; + if (!cx->stack.pushInvokeArgs(cx, 1, &args)) + return false; + + args.setCallee(getInternalsValue); + args.setThis(NullValue()); + args[0] = ObjectValue(*obj); + + if (!Invoke(cx, args)) + return false; + internals.set(&args.rval().toObject()); + return true; +} + +static bool +equal(const char *s1, const char *s2) +{ + return !strcmp(s1, s2); +} + +SUPPRESS_UNUSED_WARNING static bool +equal(JSAutoByteString &s1, const char *s2) +{ + return !strcmp(s1.ptr(), s2); +} + +SUPPRESS_UNUSED_WARNING static const char * +icuLocale(const char *locale) +{ + if (equal(locale, "und")) + return ""; // ICU root locale + return locale; +} + +// Simple RAII for ICU objects. MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE +// unfortunately doesn't work because of namespace incompatibilities +// (TypeSpecificDelete cannot be in icu and mozilla at the same time) +// and because ICU declares both UNumberFormat and UDateTimePatternGenerator +// as void*. +template <typename T> +class ScopedICUObject +{ + T *ptr_; + void (* deleter_)(T*); + + public: + ScopedICUObject(T *ptr, void (*deleter)(T*)) + : ptr_(ptr), + deleter_(deleter) + {} + + ~ScopedICUObject() { + if (ptr_) + deleter_(ptr_); + } + + // In cases where an object should be deleted on abnormal exits, + // but returned to the caller if everything goes well, call forget() + // to transfer the object just before returning. + T *forget() { + T *tmp = ptr_; + ptr_ = NULL; + return tmp; + } +}; + +static const size_t STACK_STRING_SIZE = 50; + +static const uint32_t ICU_OBJECT_SLOT = 0; + + /******************** Collator ********************/ static Class CollatorClass = { js_Object_str, 0, JS_PropertyStub, /* addProperty */ JS_PropertyStub, /* delProperty */ JS_PropertyStub, /* getProperty */
--- a/js/src/js.msg +++ b/js/src/js.msg @@ -242,17 +242,17 @@ MSG_DEF(JSMSG_INCOMPATIBLE_METHOD, 18 MSG_DEF(JSMSG_UNUSED189, 189, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED190, 190, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED191, 191, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED192, 192, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_BAD_FOR_EACH_LOOP, 193, 0, JSEXN_SYNTAXERR, "invalid for each loop") MSG_DEF(JSMSG_UNUSED194, 194, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED195, 195, 0, JSEXN_NONE, "") MSG_DEF(JSMSG_UNUSED196, 196, 0, JSEXN_NONE, "") -MSG_DEF(JSMSG_UNUSED197, 197, 0, JSEXN_NONE, "") +MSG_DEF(JSMSG_INTERNAL_INTL_ERROR, 197, 0, JSEXN_ERR, "internal error while computing Intl data") MSG_DEF(JSMSG_DEFAULT_LOCALE_ERROR, 198, 0, JSEXN_ERR, "internal error getting the default locale") MSG_DEF(JSMSG_TOO_MANY_LOCALS, 199, 0, JSEXN_SYNTAXERR, "too many local variables") MSG_DEF(JSMSG_ARRAY_INIT_TOO_BIG, 200, 0, JSEXN_INTERNALERR, "array initialiser too large") MSG_DEF(JSMSG_REGEXP_TOO_COMPLEX, 201, 0, JSEXN_INTERNALERR, "regular expression too complex") MSG_DEF(JSMSG_BUFFER_TOO_SMALL, 202, 0, JSEXN_INTERNALERR, "buffer too small") MSG_DEF(JSMSG_BAD_SURROGATE_CHAR, 203, 1, JSEXN_TYPEERR, "bad surrogate character {0}") MSG_DEF(JSMSG_UTF8_CHAR_TOO_LARGE, 204, 1, JSEXN_TYPEERR, "UTF-8 character {0} too large") MSG_DEF(JSMSG_MALFORMED_UTF8_CHAR, 205, 1, JSEXN_TYPEERR, "malformed UTF-8 character sequence at offset {0}")
--- a/js/src/vm/CommonPropertyNames.h +++ b/js/src/vm/CommonPropertyNames.h @@ -51,16 +51,17 @@ macro(enumerate, enumerate, "enumerate") \ macro(escape, escape, "escape") \ macro(eval, eval, "eval") \ macro(false, false_, "false") \ macro(fileName, fileName, "fileName") \ macro(fix, fix, "fix") \ macro(format, format, "format") \ macro(get, get, "get") \ + macro(getInternals, getInternals, "getInternals") \ macro(getOwnPropertyDescriptor, getOwnPropertyDescriptor, "getOwnPropertyDescriptor") \ macro(getOwnPropertyNames, getOwnPropertyNames, "getOwnPropertyNames") \ macro(getPropertyDescriptor, getPropertyDescriptor, "getPropertyDescriptor") \ macro(global, global, "global") \ macro(has, has, "has") \ macro(hasOwn, hasOwn, "hasOwn") \ macro(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \ macro(ignoreCase, ignoreCase, "ignoreCase") \