Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Stage 3 proposal Intl.Locale #5675

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/Parser/rterrors.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@ RT_ERROR_MSG(JSERR_MissingCurrencyCode, 5123, "", "Currency code was not specifi
RT_ERROR_MSG(JSERR_InvalidDate, 5124, "", "Invalid Date", kjstRangeError, 0)
RT_ERROR_MSG(JSERR_IntlNotAvailable, 5125, "", "Intl is not available.", kjstTypeError, 0)
RT_ERROR_MSG(JSERR_IntlNotImplemented, 5126, "", "Intl operation '%s' is not implemented.", kjstTypeError, 0)
RT_ERROR_MSG(JSERR_InvalidPrivateOrGrandfatheredTag, 5127, "", "The arguments provided to Intl.Locale form an invalid privateuse or grandfathered language tag", kjstRangeError, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

invalid privateuse or grandfathered language tag [](start = 110, length = 48)

nit: This language confuses me, but it might make sense with the algo, or we can fix the message later -- so meh

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any suggestion? From the spec, I would suggest its fairly clear -- there are specific cases where the spec says "if tag matches the grandfathered production or the privateuse production, throw a RangeError"


RT_ERROR_MSG(JSERR_ArgumentOutOfRange, 5130, "%s: argument out of range", "argument out of range", kjstRangeError, 0)
RT_ERROR_MSG(JSERR_ErrorOnNew, 5131, "", "Function is not a constructor", kjstTypeError, 0)
Expand Down
3 changes: 2 additions & 1 deletion lib/Runtime/Base/JnDirectFields.h
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,7 @@ ENTRY(builtInJavascriptArrayEntryMap)
ENTRY(builtInJavascriptArrayEntryPush)
ENTRY(builtInJavascriptArrayEntryReduce)
ENTRY(builtInJavascriptArrayEntrySlice)
ENTRY(builtInJavascriptArrayEntrySort)
ENTRY(builtInJavascriptDateEntryGetDate)
ENTRY(builtInJavascriptDateEntryNow)
ENTRY(builtInJavascriptFunctionEntryApply)
Expand All @@ -671,7 +672,6 @@ ENTRY(builtInJavascriptObjectEntryIsExtensible)
ENTRY(builtInJavascriptObjectEntryKeys)
ENTRY(builtInJavascriptObjectGetOwnPropertyDescriptor)
ENTRY(builtInJavascriptObjectPreventExtensions)
ENTRY(builtInJavascriptRegExpEntryTest) // TODO(jahorto): is this needed?
ENTRY(builtInJavascriptStringEntryIndexOf)
ENTRY(builtInJavascriptStringEntryMatch)
ENTRY(builtInJavascriptStringEntryRepeat)
Expand Down Expand Up @@ -708,6 +708,7 @@ ENTRY(raiseOptionValueOutOfRange_3)
ENTRY(raiseOptionValueOutOfRange)
ENTRY(raiseThis_NullOrUndefined)
ENTRY(raiseFunctionArgument_NeedFunction)
ENTRY(raiseInvalidPrivateOrGrandfatheredTag)

// Promise (ChakraFull)
ENTRY(Promise)
Expand Down
1 change: 1 addition & 0 deletions lib/Runtime/Library/Chakra.Runtime.Library.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
<ClInclude Include="..\SerializableFunctionFields.h" />
<ClInclude Include="AtomicsObject.h" />
<ClInclude Include="AtomicsOperations.h" />
<ClInclude Include="EngineInterfaceObjectBuiltIns.h" />
<ClInclude Include="PropertyRecordUsageCache.h" />
<ClInclude Include="CustomExternalIterator.h" />
<ClInclude Include="JsBuiltInEngineInterfaceExtensionObject.h" />
Expand Down
5 changes: 4 additions & 1 deletion lib/Runtime/Library/Chakra.Runtime.Library.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@
<ClInclude Include="JsBuiltIn\JsBuiltIn.js.nojit.bc.64b.h" />
<ClInclude Include="PropertyRecordUsageCache.h" />
<ClInclude Include="..\LibraryFunction.h" />
<ClInclude Include="IntlExtensionObjectBuiltIns.h" />
<ClInclude Include="StringCacheList.h" />
<ClInclude Include="EngineInterfaceObjectBuiltIns.h" />
</ItemGroup>
<ItemGroup>
<None Include="ConcatString.inl" />
Expand Down Expand Up @@ -286,4 +289,4 @@
<ARMASM Include="$(MSBuildThisFileDirectory)arm64\arm64_CallFunction.asm" />
<ARMASM Include="$(MSBuildThisFileDirectory)arm64\arm64_DeferredParsingThunk.asm" />
</ItemGroup>
</Project>
</Project>
2 changes: 2 additions & 0 deletions lib/Runtime/Library/EngineInterfaceObjectBuiltIns.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ GlobalBuiltIn(JavascriptArray, EntryMap)
GlobalBuiltIn(JavascriptArray, EntryReduce)
GlobalBuiltIn(JavascriptArray, EntrySlice)
GlobalBuiltIn(JavascriptArray, EntryConcat)
GlobalBuiltIn(JavascriptArray, EntrySort)

GlobalBuiltIn(JavascriptFunction, EntryBind)
GlobalBuiltIn(JavascriptFunction, EntryApply)
Expand Down Expand Up @@ -64,3 +65,4 @@ BuiltInRaiseException1(RangeError, InvalidCurrencyCode)
BuiltInRaiseException(TypeError, MissingCurrencyCode)
BuiltInRaiseException(RangeError, InvalidDate)
BuiltInRaiseException1(TypeError, FunctionArgument_NeedFunction)
BuiltInRaiseException(RangeError, InvalidPrivateOrGrandfatheredTag)
877 changes: 766 additions & 111 deletions lib/Runtime/Library/InJavascript/Intl.js

Large diffs are not rendered by default.

16,983 changes: 9,355 additions & 7,628 deletions lib/Runtime/Library/InJavascript/Intl.js.bc.32b.h

Large diffs are not rendered by default.

16,981 changes: 9,354 additions & 7,627 deletions lib/Runtime/Library/InJavascript/Intl.js.bc.64b.h

Large diffs are not rendered by default.

15,567 changes: 8,603 additions & 6,964 deletions lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.32b.h

Large diffs are not rendered by default.

15,565 changes: 8,602 additions & 6,963 deletions lib/Runtime/Library/InJavascript/Intl.js.nojit.bc.64b.h

Large diffs are not rendered by default.

73 changes: 71 additions & 2 deletions lib/Runtime/Library/IntlEngineInterfaceExtensionObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,8 +944,7 @@ PROJECTED_ENUMS(PROJECTED_ENUM)
// of caution and say it is invalid.
// We also check for parsedLength < langtag->GetLength() because there are cases when status == U_ZERO_ERROR
// but the langtag was not valid, such as "en-tesTER-TESter" (OSS-Fuzz #6657).
// NOTE: make sure we check for `undefined` at the platform.normalizeLanguageTag callsite.
return scriptContext->GetLibrary()->GetUndefined();
JavascriptError::ThrowRangeError(scriptContext, JSERR_LocaleNotWellFormed, langtag);
}

// forLangTagResultLength can be 0 if langtag is "und".
Expand Down Expand Up @@ -3157,6 +3156,76 @@ DEFINE_ISXLOCALEAVAILABLE(PR, uloc)
#endif
}

#ifdef INTL_ICU
template <bool minimize>
static JavascriptString *MinMaxImpl(JavascriptString *langtag, ScriptContext *scriptContext)
{
UErrorCode status = U_ZERO_ERROR;
char localeID[ULOC_FULLNAME_CAPACITY] = { 0 };
LangtagToLocaleID(langtag, localeID);

char minmaxLocaleID[ULOC_FULLNAME_CAPACITY] = { 0 };
int32_t minmaxLocaleIDLength = 0;
if (minimize)
{
minmaxLocaleIDLength = uloc_minimizeSubtags(localeID, minmaxLocaleID, ULOC_FULLNAME_CAPACITY, &status);
INTL_TRACE("Minimizing localeID %S to %S", localeID, minmaxLocaleID);
}
else
{
minmaxLocaleIDLength = uloc_addLikelySubtags(localeID, minmaxLocaleID, ULOC_FULLNAME_CAPACITY, &status);
INTL_TRACE("Maximizing localeID %S to %S", localeID, minmaxLocaleID);
}
ICU_ASSERT(status, minmaxLocaleIDLength < ULOC_FULLNAME_CAPACITY);

char minmaxLangtag[ULOC_FULLNAME_CAPACITY] = { 0 };
int minmaxLangtagLength = uloc_toLanguageTag(minmaxLocaleID, minmaxLangtag, ULOC_FULLNAME_CAPACITY, true, &status);
ICU_ASSERT(status, minmaxLangtagLength > 0);

// allocate maximizedLangtagLength + 1 to leave room for null terminator
char16 *minmaxLangtag16 = RecyclerNewArrayLeaf(scriptContext->GetRecycler(), char16, minmaxLangtagLength + 1);
charcount_t minmaxLangtag16Length = 0;
HRESULT hr = utf8::NarrowStringToWideNoAlloc(
minmaxLangtag,
minmaxLangtagLength,
minmaxLangtag16,
minmaxLangtagLength + 1,
&minmaxLangtag16Length
);
AssertOrFailFast(hr == S_OK && ((int)minmaxLangtag16Length) == minmaxLangtagLength);

return JavascriptString::NewWithBuffer(minmaxLangtag16, minmaxLangtagLength, scriptContext);
}
#endif

Var IntlEngineInterfaceExtensionObject::EntryIntl_MinimizeLocale(RecyclableObject *function, CallInfo callInfo, ...)
{
#ifdef INTL_ICU
EngineInterfaceObject_CommonFunctionProlog(function, callInfo);

INTL_CHECK_ARGS(args.Info.Count == 2 && JavascriptString::Is(args.Values[1]));

return MinMaxImpl<true>(JavascriptString::UnsafeFromVar(args.Values[1]), scriptContext);
#else
AssertOrFailFastMsg(false, "Intl-WinGlob should not be using MinimizeLocale");
return nullptr;
#endif
}

Var IntlEngineInterfaceExtensionObject::EntryIntl_MaximizeLocale(RecyclableObject *function, CallInfo callInfo, ...)
{
#ifdef INTL_ICU
EngineInterfaceObject_CommonFunctionProlog(function, callInfo);

INTL_CHECK_ARGS(args.Info.Count == 2 && JavascriptString::Is(args.Values[1]));

return MinMaxImpl<false>(JavascriptString::UnsafeFromVar(args.Values[1]), scriptContext);
#else
AssertOrFailFastMsg(false, "Intl-WinGlob should not be using MaximizeLocale");
return nullptr;
#endif
}

/*
* This function registers built in functions when Intl initializes.
* Call with (Function : toRegister, integer : id)
Expand Down
2 changes: 2 additions & 0 deletions lib/Runtime/Library/IntlExtensionObjectBuiltIns.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ INTL_ENTRY(getLocaleData, GetLocaleData)
INTL_ENTRY(localeCompare, LocaleCompare)
INTL_ENTRY(pluralRulesSelect, PluralRulesSelect)
INTL_ENTRY(pluralRulesKeywords, PluralRulesKeywords)
INTL_ENTRY(minimizeLocale, MinimizeLocale)
INTL_ENTRY(maximizeLocale, MaximizeLocale)

INTL_ENTRY(registerBuiltInFunction, RegisterBuiltInFunction)
INTL_ENTRY(getHiddenObject, GetHiddenObject)
Expand Down
Loading