Back out bug 1216150 for Linux x64 opt bustage

This commit is contained in:
Zibi Braniecki 2015-12-31 15:32:20 -08:00
parent 3d1467ce1b
commit 7e19d432dd
7 changed files with 13 additions and 488 deletions

View File

@ -101,7 +101,7 @@ function Date_toLocaleString() {
}
// Step 7.
return intl_FormatDateTime(dateTimeFormat, x, false);
return intl_FormatDateTime(dateTimeFormat, x);
}
@ -134,7 +134,7 @@ function Date_toLocaleDateString() {
}
// Step 7.
return intl_FormatDateTime(dateTimeFormat, x, false);
return intl_FormatDateTime(dateTimeFormat, x);
}
@ -167,5 +167,5 @@ function Date_toLocaleTimeString() {
}
// Step 7.
return intl_FormatDateTime(dateTimeFormat, x, false);
return intl_FormatDateTime(dateTimeFormat, x);
}

View File

@ -12,7 +12,6 @@
#include "builtin/Intl.h"
#include "mozilla/Range.h"
#include "mozilla/ScopeExit.h"
#include <string.h>
@ -46,7 +45,6 @@ using namespace js;
using mozilla::IsFinite;
using mozilla::IsNegativeZero;
using mozilla::MakeScopeExit;
#if ENABLE_INTL_API
using icu::Locale;
@ -385,14 +383,6 @@ udat_format(const UDateFormat* format, UDate dateToFormat, UChar* result,
MOZ_CRASH("udat_format: Intl API disabled");
}
static int32_t
udat_formatForFields(const UDateFormat* format, UDate dateToFormat,
UChar* result, int32_t resultLength, UFieldPositionIterator* fpositer,
UErrorCode* status)
{
MOZ_CRASH("udat_formatForFields: Intl API disabled");
}
static void
udat_close(UDateFormat* format)
{
@ -1679,9 +1669,11 @@ InitDateTimeFormatClass(JSContext* cx, HandleObject Intl, Handle<GlobalObject*>
if (!JS_DefineFunctions(cx, proto, dateTimeFormat_methods))
return nullptr;
// Install a getter for DateTimeFormat.prototype.format that returns a
// formatting function bound to a specified DateTimeFormat object (suitable
// for passing to methods like Array.prototype.map).
/*
* Install the getter for DateTimeFormat.prototype.format, which returns a
* bound formatting function for the specified DateTimeFormat object
* (suitable for passing to methods like Array.prototype.map).
*/
RootedValue getter(cx);
if (!GlobalObject::getIntrinsicValue(cx, cx->global(), cx->names().DateTimeFormatFormatGet,
&getter))
@ -1695,22 +1687,6 @@ InitDateTimeFormatClass(JSContext* cx, HandleObject Intl, Handle<GlobalObject*>
return nullptr;
}
// If the still-experimental DateTimeFormat.prototype.formatToParts method
// is enabled, also add its getter.
if (cx->compartment()->creationOptions().experimentalDateTimeFormatFormatToPartsEnabled()) {
if (!GlobalObject::getIntrinsicValue(cx, cx->global(),
cx->names().DateTimeFormatFormatToPartsGet, &getter))
{
return nullptr;
}
if (!DefineProperty(cx, proto, cx->names().formatToParts, UndefinedHandleValue,
JS_DATA_TO_FUNC_PTR(JSGetterOp, &getter.toObject()),
nullptr, JSPROP_GETTER | JSPROP_SHARED))
{
return nullptr;
}
}
RootedValue options(cx);
if (!CreateDefaultOptions(cx, &options))
return nullptr;
@ -2010,211 +1986,6 @@ intl_FormatDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue
return false;
result.setString(str);
return true;
}
using FieldType = ImmutablePropertyNamePtr JSAtomState::*;
static FieldType
GetFieldTypeForFormatField(UDateFormatField fieldName)
{
// See intl/icu/source/i18n/unicode/udat.h for a detailed field list. This
// switch is deliberately exhaustive: cases might have to be added/removed
// if this code is compiled with a different ICU with more
// UDateFormatField enum initializers. Please guard such cases with
// appropriate ICU version-testing #ifdefs, should cross-version divergence
// occur.
switch (fieldName) {
case UDAT_ERA_FIELD:
return &JSAtomState::era;
case UDAT_YEAR_FIELD:
case UDAT_YEAR_WOY_FIELD:
case UDAT_EXTENDED_YEAR_FIELD:
case UDAT_YEAR_NAME_FIELD:
return &JSAtomState::year;
case UDAT_MONTH_FIELD:
case UDAT_STANDALONE_MONTH_FIELD:
return &JSAtomState::month;
case UDAT_DATE_FIELD:
case UDAT_JULIAN_DAY_FIELD:
return &JSAtomState::day;
case UDAT_HOUR_OF_DAY1_FIELD:
case UDAT_HOUR_OF_DAY0_FIELD:
case UDAT_HOUR1_FIELD:
case UDAT_HOUR0_FIELD:
return &JSAtomState::hour;
case UDAT_MINUTE_FIELD:
return &JSAtomState::minute;
case UDAT_SECOND_FIELD:
return &JSAtomState::second;
case UDAT_DAY_OF_WEEK_FIELD:
case UDAT_STANDALONE_DAY_FIELD:
case UDAT_DOW_LOCAL_FIELD:
case UDAT_DAY_OF_WEEK_IN_MONTH_FIELD:
return &JSAtomState::weekday;
case UDAT_AM_PM_FIELD:
return &JSAtomState::dayperiod;
case UDAT_TIMEZONE_FIELD:
return &JSAtomState::timeZoneName;
case UDAT_FRACTIONAL_SECOND_FIELD:
case UDAT_DAY_OF_YEAR_FIELD:
case UDAT_WEEK_OF_YEAR_FIELD:
case UDAT_WEEK_OF_MONTH_FIELD:
case UDAT_MILLISECONDS_IN_DAY_FIELD:
case UDAT_TIMEZONE_RFC_FIELD:
case UDAT_TIMEZONE_GENERIC_FIELD:
case UDAT_QUARTER_FIELD:
case UDAT_STANDALONE_QUARTER_FIELD:
case UDAT_TIMEZONE_SPECIAL_FIELD:
case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD:
case UDAT_TIMEZONE_ISO_FIELD:
case UDAT_TIMEZONE_ISO_LOCAL_FIELD:
#ifndef U_HIDE_INTERNAL_API
case UDAT_RELATED_YEAR_FIELD:
#endif
#ifndef U_HIDE_DRAFT_API
case UDAT_TIME_SEPARATOR_FIELD:
#endif
// These fields are all unsupported.
return nullptr;
case UDAT_FIELD_COUNT:
MOZ_ASSERT_UNREACHABLE("format field sentinel value returned by "
"iterator!");
}
MOZ_ASSERT_UNREACHABLE("unenumerated, undocumented format field returned "
"by iterator");
return nullptr;
}
static bool
intl_FormatToPartsDateTime(JSContext* cx, UDateFormat* df, double x, MutableHandleValue result)
{
if (!IsFinite(x)) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_DATE_NOT_FINITE);
return false;
}
Vector<char16_t, INITIAL_CHAR_BUFFER_SIZE> chars(cx);
if (!chars.resize(INITIAL_CHAR_BUFFER_SIZE))
return false;
UErrorCode status = U_ZERO_ERROR;
UFieldPositionIterator* fpositer = ufieldpositer_open(&status);
if (U_FAILURE(status)) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
return false;
}
auto closeFieldPosIter = MakeScopeExit([&]() { ufieldpositer_close(fpositer); });
int resultSize =
udat_formatForFields(df, x, Char16ToUChar(chars.begin()), INITIAL_CHAR_BUFFER_SIZE,
fpositer, &status);
if (status == U_BUFFER_OVERFLOW_ERROR) {
if (!chars.resize(resultSize))
return false;
status = U_ZERO_ERROR;
udat_formatForFields(df, x, Char16ToUChar(chars.begin()), resultSize, fpositer, &status);
}
if (U_FAILURE(status)) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_INTERNAL_INTL_ERROR);
return false;
}
RootedArrayObject partsArray(cx, NewDenseEmptyArray(cx));
if (!partsArray)
return false;
if (resultSize == 0) {
// An empty string contains no parts, so avoid extra work below.
result.setObject(*partsArray);
return true;
}
RootedString overallResult(cx, NewStringCopyN<CanGC>(cx, chars.begin(), resultSize));
if (!overallResult)
return false;
size_t lastEndIndex = 0;
uint32_t partIndex = 0;
RootedObject singlePart(cx);
RootedValue partType(cx);
RootedString partSubstr(cx);
RootedValue val(cx);
auto AppendPart = [&](FieldType type, size_t beginIndex, size_t endIndex) {
singlePart = NewBuiltinClassInstance<PlainObject>(cx);
if (!singlePart)
return false;
partType = StringValue(cx->names().*type);
if (!DefineProperty(cx, singlePart, cx->names().type, partType))
return false;
partSubstr = SubstringKernel(cx, overallResult, beginIndex, endIndex - beginIndex);
if (!partSubstr)
return false;
val = StringValue(partSubstr);
if (!DefineProperty(cx, singlePart, cx->names().value, val))
return false;
val = ObjectValue(*singlePart);
if (!DefineElement(cx, partsArray, partIndex, val))
return false;
lastEndIndex = endIndex;
partIndex++;
return true;
};
int32_t fieldInt, beginIndexInt, endIndexInt;
while ((fieldInt = ufieldpositer_next(fpositer, &beginIndexInt, &endIndexInt)) >= 0) {
MOZ_ASSERT(beginIndexInt >= 0);
MOZ_ASSERT(endIndexInt >= 0);
MOZ_ASSERT(beginIndexInt <= endIndexInt,
"field iterator returning invalid range");
size_t beginIndex(beginIndexInt);
size_t endIndex(endIndexInt);
// Technically this isn't guaranteed. But it appears true in pratice,
// and http://bugs.icu-project.org/trac/ticket/12024 is expected to
// correct the documentation lapse.
MOZ_ASSERT(lastEndIndex <= beginIndex,
"field iteration didn't return fields in order start to "
"finish as expected");
if (FieldType type = GetFieldTypeForFormatField(static_cast<UDateFormatField>(fieldInt))) {
if (lastEndIndex < beginIndex) {
if (!AppendPart(&JSAtomState::separator, lastEndIndex, beginIndex))
return false;
}
if (!AppendPart(type, beginIndex, endIndex))
return false;
}
}
// Append any final separator.
if (lastEndIndex < overallResult->length()) {
if (!AppendPart(&JSAtomState::separator, lastEndIndex, overallResult->length()))
return false;
}
result.setObject(*partsArray);
return true;
}
@ -2222,10 +1993,9 @@ bool
js::intl_FormatDateTime(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
MOZ_ASSERT(args.length() == 3);
MOZ_ASSERT(args.length() == 2);
MOZ_ASSERT(args[0].isObject());
MOZ_ASSERT(args[1].isNumber());
MOZ_ASSERT(args[2].isBoolean());
RootedObject dateTimeFormat(cx, &args[0].toObject());
@ -2254,9 +2024,7 @@ js::intl_FormatDateTime(JSContext* cx, unsigned argc, Value* vp)
// Use the UDateFormat to actually format the time stamp.
RootedValue result(cx);
bool success = args[2].toBoolean()
? intl_FormatToPartsDateTime(cx, df, args[1].toNumber(), &result)
: intl_FormatDateTime(cx, df, args[1].toNumber(), &result);
bool success = intl_FormatDateTime(cx, df, args[1].toNumber(), &result);
if (!isDateTimeFormatInstance)
udat_close(df);

View File

@ -2712,9 +2712,10 @@ function dateTimeFormatFormatToBind() {
var x = (date === undefined) ? std_Date_now() : ToNumber(date);
// Step 1.a.iii.
return intl_FormatDateTime(this, x, false);
return intl_FormatDateTime(this, x);
}
/**
* Returns a function bound to this DateTimeFormat that returns a String value
* representing the result of calling ToNumber(date) according to the
@ -2741,35 +2742,6 @@ function Intl_DateTimeFormat_format_get() {
}
function dateTimeFormatFormatToPartsToBind() {
// Steps 1.a.i-ii
var date = arguments.length > 0 ? arguments[0] : undefined;
var x = (date === undefined) ? std_Date_now() : ToNumber(date);
// Step 1.a.iii.
return intl_FormatDateTime(this, x, true);
}
function Intl_DateTimeFormat_formatToParts_get() {
// Check "this DateTimeFormat object" per introduction of section 12.3.
var internals = getDateTimeFormatInternals(this, "formatToParts");
// Step 1.
if (internals.boundFormatToParts === undefined) {
// Step 1.a.
var F = dateTimeFormatFormatToPartsToBind;
// Step 1.b-d.
var bf = callFunction(std_Function_bind, F, this);
internals.boundFormatToParts = bf;
}
// Step 2.
return internals.boundFormatToParts;
}
/**
* Returns the resolved options for a DateTimeFormat object.
*

View File

@ -2180,8 +2180,7 @@ class JS_PUBLIC_API(CompartmentCreationOptions)
invisibleToDebugger_(false),
mergeable_(false),
preserveJitCode_(false),
cloneSingletons_(false),
experimentalDateTimeFormatFormatToPartsEnabled_(false)
cloneSingletons_(false)
{
zone_.spec = JS::FreshZone;
}
@ -2244,24 +2243,6 @@ class JS_PUBLIC_API(CompartmentCreationOptions)
return *this;
}
// ECMA-402 is considering adding a "formatToParts" DateTimeFormat method,
// that exposes not just a formatted string but its ordered subcomponents.
// The method, its semantics, and its name are all well short of being
// finalized, so for now it's exposed *only* if requested.
//
// Until "formatToParts" is included in a final specification edition, it's
// subject to change or removal at any time. Do *not* rely on it in
// mission-critical code that can't be changed if ECMA-402 decides not to
// accept the method in its current form.
bool experimentalDateTimeFormatFormatToPartsEnabled() const {
return experimentalDateTimeFormatFormatToPartsEnabled_;
}
CompartmentCreationOptions& setExperimentalDateTimeFormatFormatToPartsEnabled(bool flag) {
experimentalDateTimeFormatFormatToPartsEnabled_ = flag;
return *this;
}
private:
JSAddonId* addonId_;
JSTraceOp traceGlobal_;
@ -2273,7 +2254,6 @@ class JS_PUBLIC_API(CompartmentCreationOptions)
bool mergeable_;
bool preserveJitCode_;
bool cloneSingletons_;
bool experimentalDateTimeFormatFormatToPartsEnabled_;
};
/**

View File

@ -3977,11 +3977,6 @@ NewGlobal(JSContext* cx, unsigned argc, Value* vp)
if (v.isBoolean())
creationOptions.setCloneSingletons(v.toBoolean());
if (!JS_GetProperty(cx, opts, "experimentalDateTimeFormatFormatToPartsEnabled", &v))
return true;
if (v.isBoolean())
creationOptions.setExperimentalDateTimeFormatFormatToPartsEnabled(v.toBoolean());
if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
return false;
if (v.isObject())

View File

@ -1,176 +0,0 @@
// |reftest| skip-if(!this.hasOwnProperty("Intl")||!this.newGlobal||!newGlobal({experimentalDateTimeFormatFormatToPartsEnabled:true}).Intl.DateTimeFormat().formatToParts)
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
// Tests the format function with a diverse set of locales and options.
// Always use UTC to avoid dependencies on test environment.
/*
* Return true if A is equal to B, where equality on arrays and objects
* means that they have the same set of enumerable properties, the values
* of each property are deep_equal, and their 'length' properties are
* equal. Equality on other types is ==.
*/
function deepEqual(a, b) {
if (typeof a !== typeof b)
return false;
if (a === null)
return b === null;
if (typeof a === 'object') {
// For every property of a, does b have that property with an equal value?
var props = {};
for (var prop in a) {
if (!deepEqual(a[prop], b[prop]))
return false;
props[prop] = true;
}
// Are all of b's properties present on a?
for (var prop in b)
if (!props[prop])
return false;
// length isn't enumerable, but we want to check it, too.
return a.length === b.length;
}
return Object.is(a, b);
}
function composeDate(parts) {
return parts.map(({value}) => value)
.reduce((string, part) => string + part);
}
var format;
var date = Date.UTC(2012, 11, 17, 3, 0, 42);
// The experimental formatToParts method is only exposed if specifically
// requested. Perform all tests using DateTimeFormat instances from a global
// object with this method enabled.
var DateTimeFormat =
newGlobal({experimentalDateTimeFormatFormatToPartsEnabled:true}).Intl.DateTimeFormat;
// Locale en-US; default options.
format = new DateTimeFormat("en-us", {timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'month', value: '12' },
{ type: 'separator', value: '/' },
{ type: 'day', value: '17' },
{ type: 'separator', value: '/' },
{ type: 'year', value: '2012' }
]), true);
// Just date
format = new DateTimeFormat("en-us", {
year: 'numeric',
month: 'numeric',
day: 'numeric',
timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'month', value: '12' },
{ type: 'separator', value: '/' },
{ type: 'day', value: '17' },
{ type: 'separator', value: '/' },
{ type: 'year', value: '2012' }
]), true);
assertEq(composeDate(format.formatToParts(date)), format.format(date));
// Just time in hour24
format = new DateTimeFormat("en-us", {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hour12: false,
timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'hour', value: '03' },
{ type: 'separator', value: ':' },
{ type: 'minute', value: '00' },
{ type: 'separator', value: ':' },
{ type: 'second', value: '42' }
]), true);
assertEq(composeDate(format.formatToParts(date)), format.format(date));
// Just time in hour12
format = new DateTimeFormat("en-us", {
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hour12: true,
timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'hour', value: '3' },
{ type: 'separator', value: ':' },
{ type: 'minute', value: '00' },
{ type: 'separator', value: ':' },
{ type: 'second', value: '42' },
{ type: 'separator', value: ' ' },
{ type: 'dayperiod', value: 'AM' }
]), true);
assertEq(composeDate(format.formatToParts(date)), format.format(date));
// Just month.
format = new DateTimeFormat("en-us", {
month: "narrow",
timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'month', value: 'D' }
]), true);
assertEq(composeDate(format.formatToParts(date)), format.format(date));
// Just weekday.
format = new DateTimeFormat("en-us", {
weekday: "narrow",
timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'weekday', value: 'M' }
]), true);
assertEq(composeDate(format.formatToParts(date)), format.format(date));
// Year and era.
format = new DateTimeFormat("en-us", {
year: "numeric",
era: "short",
timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'year', value: '2012' },
{ type: 'separator', value: ' ' },
{ type: 'era', value: 'AD' }
]), true);
assertEq(composeDate(format.formatToParts(date)), format.format(date));
// Time and date
format = new DateTimeFormat("en-us", {
weekday: 'long',
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
second: 'numeric',
hour12: true,
timeZone: "UTC"});
assertEq(deepEqual(format.formatToParts(date), [
{ type: 'weekday', value: 'Monday' },
{ type: 'separator', value: ', ' },
{ type: 'month', value: '12' },
{ type: 'separator', value: '/' },
{ type: 'day', value: '17' },
{ type: 'separator', value: '/' },
{ type: 'year', value: '2012' },
{ type: 'separator', value: ', ' },
{ type: 'hour', value: '3' },
{ type: 'separator', value: ':' },
{ type: 'minute', value: '00' },
{ type: 'separator', value: ':' },
{ type: 'second', value: '42' },
{ type: 'separator', value: ' ' },
{ type: 'dayperiod', value: 'AM' }
]), true);
assertEq(composeDate(format.formatToParts(date)), format.format(date));
if (typeof reportCompare === "function")
reportCompare(0, 0, 'ok');

View File

@ -59,9 +59,6 @@
macro(currencyDisplay, currencyDisplay, "currencyDisplay") \
macro(DateTimeFormat, DateTimeFormat, "DateTimeFormat") \
macro(DateTimeFormatFormatGet, DateTimeFormatFormatGet, "Intl_DateTimeFormat_format_get") \
macro(DateTimeFormatFormatToPartsGet, DateTimeFormatFormatToPartsGet, "Intl_DateTimeFormat_formatToParts_get") \
macro(day, day, "day") \
macro(dayperiod, dayperiod, "dayperiod") \
macro(decodeURI, decodeURI, "decodeURI") \
macro(decodeURIComponent, decodeURIComponent, "decodeURIComponent") \
macro(default_, default_, "default") \
@ -83,7 +80,6 @@
macro(endTimestamp, endTimestamp, "endTimestamp") \
macro(enumerable, enumerable, "enumerable") \
macro(enumerate, enumerate, "enumerate") \
macro(era, era, "era") \
macro(escape, escape, "escape") \
macro(eval, eval, "eval") \
macro(false, false_, "false") \
@ -99,7 +95,6 @@
macro(forceInterpreter, forceInterpreter, "forceInterpreter") \
macro(forEach, forEach, "forEach") \
macro(format, format, "format") \
macro(formatToParts, formatToParts, "formatToParts") \
macro(frame, frame, "frame") \
macro(from, from, "from") \
macro(gcCycleNumber, gcCycleNumber, "gcCycleNumber") \
@ -114,7 +109,6 @@
macro(has, has, "has") \
macro(hasOwn, hasOwn, "hasOwn") \
macro(hasOwnProperty, hasOwnProperty, "hasOwnProperty") \
macro(hour, hour, "hour") \
macro(ignoreCase, ignoreCase, "ignoreCase") \
macro(ignorePunctuation, ignorePunctuation, "ignorePunctuation") \
macro(index, index, "index") \
@ -158,10 +152,8 @@
macro(minimumFractionDigits, minimumFractionDigits, "minimumFractionDigits") \
macro(minimumIntegerDigits, minimumIntegerDigits, "minimumIntegerDigits") \
macro(minimumSignificantDigits, minimumSignificantDigits, "minimumSignificantDigits") \
macro(minute, minute, "minute") \
macro(missingArguments, missingArguments, "missingArguments") \
macro(module, module, "module") \
macro(month, month, "month") \
macro(multiline, multiline, "multiline") \
macro(name, name, "name") \
macro(NaN, NaN, "NaN") \
@ -208,9 +200,7 @@
macro(revoke, revoke, "revoke") \
macro(script, script, "script") \
macro(scripts, scripts, "scripts") \
macro(second, second, "second") \
macro(sensitivity, sensitivity, "sensitivity") \
macro(separator, separator, "separator") \
macro(set, set, "set") \
macro(shape, shape, "shape") \
macro(size, size, "size") \
@ -231,7 +221,6 @@
macro(throw, throw_, "throw") \
macro(timestamp, timestamp, "timestamp") \
macro(timeZone, timeZone, "timeZone") \
macro(timeZoneName, timeZoneName, "timeZoneName") \
macro(toGMTString, toGMTString, "toGMTString") \
macro(toISOString, toISOString, "toISOString") \
macro(toJSON, toJSON, "toJSON") \
@ -240,7 +229,6 @@
macro(toString, toString, "toString") \
macro(toUTCString, toUTCString, "toUTCString") \
macro(true, true_, "true") \
macro(type, type, "type") \
macro(unescape, unescape, "unescape") \
macro(uneval, uneval, "uneval") \
macro(unicode, unicode, "unicode") \
@ -267,9 +255,7 @@
macro(void0, void0, "(void 0)") \
macro(watch, watch, "watch") \
macro(WeakSet_add, WeakSet_add, "WeakSet_add") \
macro(weekday, weekday, "weekday") \
macro(writable, writable, "writable") \
macro(year, year, "year") \
macro(yield, yield, "yield") \
macro(raw, raw, "raw") \
/* Type names must be contiguous and ordered; see js::TypeName. */ \