[builtins] Refactor the remaining Date builtins.
This migrates the remaining Date builtins to C++ and removes obsolete intrinsics and JavaScript wrappers. This reduces the overhead imposed by the Date builtins, and will allow us to optimize them later in the TurboFan compiler, while the interpreter doesn't need to worry about them. R=yangguo@chromium.org BUG=chromium:576574 LOG=n Review URL: https://codereview.chromium.org/1579613002 Cr-Commit-Position: refs/heads/master@{#33228}
This commit is contained in:
parent
c22f68d659
commit
1e51af1a5c
1
BUILD.gn
1
BUILD.gn
@ -222,7 +222,6 @@ action("js2c") {
|
||||
"src/js/uri.js",
|
||||
"src/js/math.js",
|
||||
"src/third_party/fdlibm/fdlibm.js",
|
||||
"src/js/date.js",
|
||||
"src/js/regexp.js",
|
||||
"src/js/arraybuffer.js",
|
||||
"src/js/typedarray.js",
|
||||
|
@ -1246,15 +1246,133 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
|
||||
{ // --- D a t e ---
|
||||
// Builtin functions for Date.prototype.
|
||||
Handle<JSFunction> date_fun = InstallFunction(
|
||||
global, "Date", JS_DATE_TYPE, JSDate::kSize,
|
||||
isolate->initial_object_prototype(), Builtins::kDateConstructor);
|
||||
Handle<JSObject> prototype =
|
||||
factory->NewJSObject(isolate->object_function(), TENURED);
|
||||
Handle<JSFunction> date_fun =
|
||||
InstallFunction(global, "Date", JS_DATE_TYPE, JSDate::kSize, prototype,
|
||||
Builtins::kDateConstructor);
|
||||
InstallWithIntrinsicDefaultProto(isolate, date_fun,
|
||||
Context::DATE_FUNCTION_INDEX);
|
||||
date_fun->shared()->set_construct_stub(
|
||||
*isolate->builtins()->DateConstructor_ConstructStub());
|
||||
date_fun->shared()->set_length(7);
|
||||
date_fun->shared()->DontAdaptArguments();
|
||||
|
||||
// Install the Date.now, Date.parse and Date.UTC functions.
|
||||
SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
|
||||
SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
|
||||
SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
|
||||
|
||||
// Install the "constructor" property on the {prototype}.
|
||||
JSObject::AddProperty(prototype, factory->constructor_string(), date_fun,
|
||||
DONT_ENUM);
|
||||
|
||||
// Install the Date.prototype methods.
|
||||
SimpleInstallFunction(prototype, "toString",
|
||||
Builtins::kDatePrototypeToString, 0, false);
|
||||
SimpleInstallFunction(prototype, "toDateString",
|
||||
Builtins::kDatePrototypeToDateString, 0, false);
|
||||
SimpleInstallFunction(prototype, "toTimeString",
|
||||
Builtins::kDatePrototypeToTimeString, 0, false);
|
||||
SimpleInstallFunction(prototype, "toGMTString",
|
||||
Builtins::kDatePrototypeToUTCString, 0, false);
|
||||
SimpleInstallFunction(prototype, "toISOString",
|
||||
Builtins::kDatePrototypeToISOString, 0, false);
|
||||
SimpleInstallFunction(prototype, "toUTCString",
|
||||
Builtins::kDatePrototypeToUTCString, 0, false);
|
||||
SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
|
||||
0, true);
|
||||
SimpleInstallFunction(prototype, "setDate", Builtins::kDatePrototypeSetDate,
|
||||
1, false);
|
||||
SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
|
||||
0, true);
|
||||
SimpleInstallFunction(prototype, "getFullYear",
|
||||
Builtins::kDatePrototypeGetFullYear, 0, true);
|
||||
SimpleInstallFunction(prototype, "setFullYear",
|
||||
Builtins::kDatePrototypeSetFullYear, 3, false);
|
||||
SimpleInstallFunction(prototype, "getHours",
|
||||
Builtins::kDatePrototypeGetHours, 0, true);
|
||||
SimpleInstallFunction(prototype, "setHours",
|
||||
Builtins::kDatePrototypeSetHours, 4, false);
|
||||
SimpleInstallFunction(prototype, "getMilliseconds",
|
||||
Builtins::kDatePrototypeGetMilliseconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "setMilliseconds",
|
||||
Builtins::kDatePrototypeSetMilliseconds, 1, false);
|
||||
SimpleInstallFunction(prototype, "getMinutes",
|
||||
Builtins::kDatePrototypeGetMinutes, 0, true);
|
||||
SimpleInstallFunction(prototype, "setMinutes",
|
||||
Builtins::kDatePrototypeSetMinutes, 3, false);
|
||||
SimpleInstallFunction(prototype, "getMonth",
|
||||
Builtins::kDatePrototypeGetMonth, 0, true);
|
||||
SimpleInstallFunction(prototype, "setMonth",
|
||||
Builtins::kDatePrototypeSetMonth, 2, false);
|
||||
SimpleInstallFunction(prototype, "getSeconds",
|
||||
Builtins::kDatePrototypeGetSeconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "setSeconds",
|
||||
Builtins::kDatePrototypeSetSeconds, 2, false);
|
||||
SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
|
||||
0, true);
|
||||
SimpleInstallFunction(prototype, "setTime", Builtins::kDatePrototypeSetTime,
|
||||
1, false);
|
||||
SimpleInstallFunction(prototype, "getTimezoneOffset",
|
||||
Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCDate",
|
||||
Builtins::kDatePrototypeGetUTCDate, 0, true);
|
||||
SimpleInstallFunction(prototype, "setUTCDate",
|
||||
Builtins::kDatePrototypeSetUTCDate, 1, false);
|
||||
SimpleInstallFunction(prototype, "getUTCDay",
|
||||
Builtins::kDatePrototypeGetUTCDay, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCFullYear",
|
||||
Builtins::kDatePrototypeGetUTCFullYear, 0, true);
|
||||
SimpleInstallFunction(prototype, "setUTCFullYear",
|
||||
Builtins::kDatePrototypeSetUTCFullYear, 3, false);
|
||||
SimpleInstallFunction(prototype, "getUTCHours",
|
||||
Builtins::kDatePrototypeGetUTCHours, 0, true);
|
||||
SimpleInstallFunction(prototype, "setUTCHours",
|
||||
Builtins::kDatePrototypeSetUTCHours, 4, false);
|
||||
SimpleInstallFunction(prototype, "getUTCMilliseconds",
|
||||
Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "setUTCMilliseconds",
|
||||
Builtins::kDatePrototypeSetUTCMilliseconds, 1, false);
|
||||
SimpleInstallFunction(prototype, "getUTCMinutes",
|
||||
Builtins::kDatePrototypeGetUTCMinutes, 0, true);
|
||||
SimpleInstallFunction(prototype, "setUTCMinutes",
|
||||
Builtins::kDatePrototypeSetUTCMinutes, 3, false);
|
||||
SimpleInstallFunction(prototype, "getUTCMonth",
|
||||
Builtins::kDatePrototypeGetUTCMonth, 0, true);
|
||||
SimpleInstallFunction(prototype, "setUTCMonth",
|
||||
Builtins::kDatePrototypeSetUTCMonth, 2, false);
|
||||
SimpleInstallFunction(prototype, "getUTCSeconds",
|
||||
Builtins::kDatePrototypeGetUTCSeconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "setUTCSeconds",
|
||||
Builtins::kDatePrototypeSetUTCSeconds, 2, false);
|
||||
SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
|
||||
0, false);
|
||||
SimpleInstallFunction(prototype, "getYear", Builtins::kDatePrototypeGetYear,
|
||||
0, true);
|
||||
SimpleInstallFunction(prototype, "setYear", Builtins::kDatePrototypeSetYear,
|
||||
1, false);
|
||||
|
||||
// Install i18n fallback functions.
|
||||
SimpleInstallFunction(prototype, "toLocaleString",
|
||||
Builtins::kDatePrototypeToString, 0, false);
|
||||
SimpleInstallFunction(prototype, "toLocaleDateString",
|
||||
Builtins::kDatePrototypeToDateString, 0, false);
|
||||
SimpleInstallFunction(prototype, "toLocaleTimeString",
|
||||
Builtins::kDatePrototypeToTimeString, 0, false);
|
||||
|
||||
// Install the @@toPrimitive function.
|
||||
Handle<JSFunction> to_primitive = InstallFunction(
|
||||
prototype, factory->to_primitive_symbol(), JS_OBJECT_TYPE,
|
||||
JSObject::kHeaderSize, MaybeHandle<JSObject>(),
|
||||
Builtins::kDatePrototypeToPrimitive,
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
|
||||
|
||||
// Set the expected parameters for @@toPrimitive to 1; required by builtin.
|
||||
to_primitive->shared()->set_internal_formal_parameter_count(1);
|
||||
|
||||
// Set the length for the function to satisfy ECMA-262.
|
||||
to_primitive->shared()->set_length(1);
|
||||
}
|
||||
|
||||
{ // -- R e g E x p
|
||||
@ -1627,7 +1745,7 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object,
|
||||
native_context()->set_call_as_constructor_delegate(*delegate);
|
||||
delegate->shared()->DontAdaptArguments();
|
||||
}
|
||||
}
|
||||
} // NOLINT(readability/fn_size)
|
||||
|
||||
|
||||
void Genesis::InstallTypedArray(const char* name, ElementsKind elements_kind,
|
||||
@ -2531,80 +2649,6 @@ bool Genesis::InstallNatives(ContextType context_type) {
|
||||
native_context()->set_global_eval_fun(*eval);
|
||||
}
|
||||
|
||||
// Setup the Date constructor.
|
||||
{
|
||||
Handle<String> key = factory()->Date_string();
|
||||
Handle<JSFunction> date_fun = Handle<JSFunction>::cast(
|
||||
Object::GetProperty(handle(native_context()->global_object()), key)
|
||||
.ToHandleChecked());
|
||||
Handle<JSObject> prototype =
|
||||
Handle<JSObject>(JSObject::cast(date_fun->instance_prototype()));
|
||||
|
||||
// Install the Date.now, Date.parse and Date.UTC functions.
|
||||
SimpleInstallFunction(date_fun, "now", Builtins::kDateNow, 0, false);
|
||||
SimpleInstallFunction(date_fun, "parse", Builtins::kDateParse, 1, false);
|
||||
SimpleInstallFunction(date_fun, "UTC", Builtins::kDateUTC, 7, false);
|
||||
|
||||
// Install the "constructor" property on the {prototype}.
|
||||
JSObject::AddProperty(prototype, factory()->constructor_string(), date_fun,
|
||||
DONT_ENUM);
|
||||
|
||||
// Install the toISOString and valueOf functions.
|
||||
SimpleInstallFunction(prototype, "toISOString",
|
||||
Builtins::kDatePrototypeToISOString, 0, false);
|
||||
SimpleInstallFunction(prototype, "getDate", Builtins::kDatePrototypeGetDate,
|
||||
0, true);
|
||||
SimpleInstallFunction(prototype, "getDay", Builtins::kDatePrototypeGetDay,
|
||||
0, true);
|
||||
SimpleInstallFunction(prototype, "getFullYear",
|
||||
Builtins::kDatePrototypeGetFullYear, 0, true);
|
||||
SimpleInstallFunction(prototype, "getHours",
|
||||
Builtins::kDatePrototypeGetHours, 0, true);
|
||||
SimpleInstallFunction(prototype, "getMilliseconds",
|
||||
Builtins::kDatePrototypeGetMilliseconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "getMinutes",
|
||||
Builtins::kDatePrototypeGetMinutes, 0, true);
|
||||
SimpleInstallFunction(prototype, "getMonth",
|
||||
Builtins::kDatePrototypeGetMonth, 0, true);
|
||||
SimpleInstallFunction(prototype, "getSeconds",
|
||||
Builtins::kDatePrototypeGetSeconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "getTime", Builtins::kDatePrototypeGetTime,
|
||||
0, true);
|
||||
SimpleInstallFunction(prototype, "getTimezoneOffset",
|
||||
Builtins::kDatePrototypeGetTimezoneOffset, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCDate",
|
||||
Builtins::kDatePrototypeGetUTCDate, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCDay",
|
||||
Builtins::kDatePrototypeGetUTCDay, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCFullYear",
|
||||
Builtins::kDatePrototypeGetUTCFullYear, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCHours",
|
||||
Builtins::kDatePrototypeGetUTCHours, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCMilliseconds",
|
||||
Builtins::kDatePrototypeGetUTCMilliseconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCMinutes",
|
||||
Builtins::kDatePrototypeGetUTCMinutes, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCMonth",
|
||||
Builtins::kDatePrototypeGetUTCMonth, 0, true);
|
||||
SimpleInstallFunction(prototype, "getUTCSeconds",
|
||||
Builtins::kDatePrototypeGetUTCSeconds, 0, true);
|
||||
SimpleInstallFunction(prototype, "valueOf", Builtins::kDatePrototypeValueOf,
|
||||
0, false);
|
||||
|
||||
// Install the @@toPrimitive function.
|
||||
Handle<JSFunction> to_primitive = InstallFunction(
|
||||
prototype, factory()->to_primitive_symbol(), JS_OBJECT_TYPE,
|
||||
JSObject::kHeaderSize, MaybeHandle<JSObject>(),
|
||||
Builtins::kDatePrototypeToPrimitive,
|
||||
static_cast<PropertyAttributes>(DONT_ENUM | READ_ONLY));
|
||||
|
||||
// Set the expected parameters for @@toPrimitive to 1; required by builtin.
|
||||
to_primitive->shared()->set_internal_formal_parameter_count(1);
|
||||
|
||||
// Set the length for the function to satisfy ECMA-262.
|
||||
to_primitive->shared()->set_length(1);
|
||||
}
|
||||
|
||||
// Install Array.prototype.concat
|
||||
{
|
||||
Handle<JSFunction> array_constructor(native_context()->array_function());
|
||||
|
560
src/builtins.cc
560
src/builtins.cc
@ -2122,25 +2122,55 @@ double ParseDateTimeString(Handle<String> str) {
|
||||
}
|
||||
|
||||
|
||||
enum ToDateStringMode { kDateOnly, kTimeOnly, kDateAndTime };
|
||||
|
||||
|
||||
// ES6 section 20.3.4.41.1 ToDateString(tv)
|
||||
void ToDateString(double time_val, Vector<char> str, DateCache* date_cache) {
|
||||
void ToDateString(double time_val, Vector<char> str, DateCache* date_cache,
|
||||
ToDateStringMode mode = kDateAndTime) {
|
||||
if (std::isnan(time_val)) {
|
||||
SNPrintF(str, "Invalid Date");
|
||||
} else {
|
||||
int64_t time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = date_cache->ToLocal(time_ms);
|
||||
int year, month, day, weekday, hour, min, sec, ms;
|
||||
date_cache->BreakDownTime(local_time_ms, &year, &month, &day, &weekday,
|
||||
&hour, &min, &sec, &ms);
|
||||
int timezone_offset = -date_cache->TimezoneOffset(time_ms);
|
||||
int timezone_hour = std::abs(timezone_offset) / 60;
|
||||
int timezone_min = std::abs(timezone_offset) % 60;
|
||||
const char* local_timezone = date_cache->LocalTimezone(time_ms);
|
||||
SNPrintF(str, "%s %s %02d %4d %02d:%02d:%02d GMT%c%02d%02d (%s)",
|
||||
kShortWeekDays[weekday], kShortMonths[month], day, year, hour, min,
|
||||
sec, (timezone_offset < 0) ? '-' : '+', timezone_hour,
|
||||
timezone_min, local_timezone);
|
||||
return;
|
||||
}
|
||||
int64_t time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = date_cache->ToLocal(time_ms);
|
||||
int year, month, day, weekday, hour, min, sec, ms;
|
||||
date_cache->BreakDownTime(local_time_ms, &year, &month, &day, &weekday, &hour,
|
||||
&min, &sec, &ms);
|
||||
int timezone_offset = -date_cache->TimezoneOffset(time_ms);
|
||||
int timezone_hour = std::abs(timezone_offset) / 60;
|
||||
int timezone_min = std::abs(timezone_offset) % 60;
|
||||
const char* local_timezone = date_cache->LocalTimezone(time_ms);
|
||||
switch (mode) {
|
||||
case kDateOnly:
|
||||
SNPrintF(str, "%s %s %02d %4d", kShortWeekDays[weekday],
|
||||
kShortMonths[month], day, year);
|
||||
return;
|
||||
case kTimeOnly:
|
||||
SNPrintF(str, "%02d:%02d:%02d GMT%c%02d%02d (%s)", hour, min, sec,
|
||||
(timezone_offset < 0) ? '-' : '+', timezone_hour, timezone_min,
|
||||
local_timezone);
|
||||
return;
|
||||
case kDateAndTime:
|
||||
SNPrintF(str, "%s %s %02d %4d %02d:%02d:%02d GMT%c%02d%02d (%s)",
|
||||
kShortWeekDays[weekday], kShortMonths[month], day, year, hour,
|
||||
min, sec, (timezone_offset < 0) ? '-' : '+', timezone_hour,
|
||||
timezone_min, local_timezone);
|
||||
return;
|
||||
}
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
Object* SetLocalDateValue(Handle<JSDate> date, double time_val) {
|
||||
if (time_val >= -DateCache::kMaxTimeBeforeUTCInMs &&
|
||||
time_val <= DateCache::kMaxTimeBeforeUTCInMs) {
|
||||
Isolate* const isolate = date->GetIsolate();
|
||||
time_val = isolate->date_cache()->ToUTC(static_cast<int64_t>(time_val));
|
||||
} else {
|
||||
time_val = std::numeric_limits<double>::quiet_NaN();
|
||||
}
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@ -2320,6 +2350,423 @@ BUILTIN(DateUTC) {
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.20 Date.prototype.setDate ( date )
|
||||
BUILTIN(DatePrototypeSetDate) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setDate");
|
||||
Handle<Object> value = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
|
||||
int year, month, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
|
||||
time_val = MakeDate(MakeDay(year, month, value->Number()), time_within_day);
|
||||
}
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.21 Date.prototype.setFullYear (year, month, date)
|
||||
BUILTIN(DatePrototypeSetFullYear) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setFullYear");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> year = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
|
||||
double y = year->Number(), m = 0.0, dt = 1.0;
|
||||
int time_within_day = 0;
|
||||
if (!std::isnan(date->value()->Number())) {
|
||||
int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
|
||||
int year, month, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
|
||||
m = month;
|
||||
dt = day;
|
||||
}
|
||||
if (argc >= 2) {
|
||||
Handle<Object> month = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
|
||||
m = month->Number();
|
||||
if (argc >= 3) {
|
||||
Handle<Object> date = args.at<Object>(3);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
|
||||
dt = date->Number();
|
||||
}
|
||||
}
|
||||
double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.22 Date.prototype.setHours(hour, min, sec, ms)
|
||||
BUILTIN(DatePrototypeSetHours) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setHours");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> hour = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
|
||||
double h = hour->Number();
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int day = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
|
||||
double m = (time_within_day / (60 * 1000)) % 60;
|
||||
double s = (time_within_day / 1000) % 60;
|
||||
double milli = time_within_day % 1000;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> min = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
|
||||
m = min->Number();
|
||||
if (argc >= 3) {
|
||||
Handle<Object> sec = args.at<Object>(3);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
|
||||
s = sec->Number();
|
||||
if (argc >= 4) {
|
||||
Handle<Object> ms = args.at<Object>(4);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
milli = ms->Number();
|
||||
}
|
||||
}
|
||||
}
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, milli));
|
||||
}
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.23 Date.prototype.setMilliseconds(ms)
|
||||
BUILTIN(DatePrototypeSetMilliseconds) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setMilliseconds");
|
||||
Handle<Object> ms = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int day = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
|
||||
int h = time_within_day / (60 * 60 * 1000);
|
||||
int m = (time_within_day / (60 * 1000)) % 60;
|
||||
int s = (time_within_day / 1000) % 60;
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
|
||||
}
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.24 Date.prototype.setMinutes ( min, sec, ms )
|
||||
BUILTIN(DatePrototypeSetMinutes) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setMinutes");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> min = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int day = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
|
||||
int h = time_within_day / (60 * 60 * 1000);
|
||||
double m = min->Number();
|
||||
double s = (time_within_day / 1000) % 60;
|
||||
double milli = time_within_day % 1000;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> sec = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
|
||||
s = sec->Number();
|
||||
if (argc >= 3) {
|
||||
Handle<Object> ms = args.at<Object>(3);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
milli = ms->Number();
|
||||
}
|
||||
}
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, milli));
|
||||
}
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.25 Date.prototype.setMonth ( month, date )
|
||||
BUILTIN(DatePrototypeSetMonth) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setMonth");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> month = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int days = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
|
||||
int year, unused, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
|
||||
double m = month->Number();
|
||||
double dt = day;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> date = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
|
||||
dt = date->Number();
|
||||
}
|
||||
time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
|
||||
}
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.26 Date.prototype.setSeconds ( sec, ms )
|
||||
BUILTIN(DatePrototypeSetSeconds) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setSeconds");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> sec = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int day = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, day);
|
||||
int h = time_within_day / (60 * 60 * 1000);
|
||||
double m = (time_within_day / (60 * 1000)) % 60;
|
||||
double s = sec->Number();
|
||||
double milli = time_within_day % 1000;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> ms = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
milli = ms->Number();
|
||||
}
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, milli));
|
||||
}
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.27 Date.prototype.setTime ( time )
|
||||
BUILTIN(DatePrototypeSetTime) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setTime");
|
||||
Handle<Object> value = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
|
||||
return *JSDate::SetValue(date, TimeClip(value->Number()));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.28 Date.prototype.setUTCDate ( date )
|
||||
BUILTIN(DatePrototypeSetUTCDate) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCDate");
|
||||
Handle<Object> value = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, value, Object::ToNumber(value));
|
||||
if (std::isnan(date->value()->Number())) return date->value();
|
||||
int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
|
||||
int const days = isolate->date_cache()->DaysFromTime(time_ms);
|
||||
int const time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
|
||||
int year, month, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
|
||||
double const time_val =
|
||||
MakeDate(MakeDay(year, month, value->Number()), time_within_day);
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.29 Date.prototype.setUTCFullYear (year, month, date)
|
||||
BUILTIN(DatePrototypeSetUTCFullYear) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCFullYear");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> year = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
|
||||
double y = year->Number(), m = 0.0, dt = 1.0;
|
||||
int time_within_day = 0;
|
||||
if (!std::isnan(date->value()->Number())) {
|
||||
int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
|
||||
int const days = isolate->date_cache()->DaysFromTime(time_ms);
|
||||
time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
|
||||
int year, month, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
|
||||
m = month;
|
||||
dt = day;
|
||||
}
|
||||
if (argc >= 2) {
|
||||
Handle<Object> month = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
|
||||
m = month->Number();
|
||||
if (argc >= 3) {
|
||||
Handle<Object> date = args.at<Object>(3);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
|
||||
dt = date->Number();
|
||||
}
|
||||
}
|
||||
double const time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.30 Date.prototype.setUTCHours(hour, min, sec, ms)
|
||||
BUILTIN(DatePrototypeSetUTCHours) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCHours");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> hour = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, hour, Object::ToNumber(hour));
|
||||
double h = hour->Number();
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int day = isolate->date_cache()->DaysFromTime(time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
|
||||
double m = (time_within_day / (60 * 1000)) % 60;
|
||||
double s = (time_within_day / 1000) % 60;
|
||||
double milli = time_within_day % 1000;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> min = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
|
||||
m = min->Number();
|
||||
if (argc >= 3) {
|
||||
Handle<Object> sec = args.at<Object>(3);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
|
||||
s = sec->Number();
|
||||
if (argc >= 4) {
|
||||
Handle<Object> ms = args.at<Object>(4);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
milli = ms->Number();
|
||||
}
|
||||
}
|
||||
}
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, milli));
|
||||
}
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.31 Date.prototype.setUTCMilliseconds(ms)
|
||||
BUILTIN(DatePrototypeSetUTCMilliseconds) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMilliseconds");
|
||||
Handle<Object> ms = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int day = isolate->date_cache()->DaysFromTime(time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
|
||||
int h = time_within_day / (60 * 60 * 1000);
|
||||
int m = (time_within_day / (60 * 1000)) % 60;
|
||||
int s = (time_within_day / 1000) % 60;
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, ms->Number()));
|
||||
}
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.32 Date.prototype.setUTCMinutes ( min, sec, ms )
|
||||
BUILTIN(DatePrototypeSetUTCMinutes) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMinutes");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> min = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, min, Object::ToNumber(min));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int day = isolate->date_cache()->DaysFromTime(time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
|
||||
int h = time_within_day / (60 * 60 * 1000);
|
||||
double m = min->Number();
|
||||
double s = (time_within_day / 1000) % 60;
|
||||
double milli = time_within_day % 1000;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> sec = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
|
||||
s = sec->Number();
|
||||
if (argc >= 3) {
|
||||
Handle<Object> ms = args.at<Object>(3);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
milli = ms->Number();
|
||||
}
|
||||
}
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, milli));
|
||||
}
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.31 Date.prototype.setUTCMonth ( month, date )
|
||||
BUILTIN(DatePrototypeSetUTCMonth) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCMonth");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> month = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, month, Object::ToNumber(month));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int days = isolate->date_cache()->DaysFromTime(time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(time_ms, days);
|
||||
int year, unused, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &unused, &day);
|
||||
double m = month->Number();
|
||||
double dt = day;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> date = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, date, Object::ToNumber(date));
|
||||
dt = date->Number();
|
||||
}
|
||||
time_val = MakeDate(MakeDay(year, m, dt), time_within_day);
|
||||
}
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.34 Date.prototype.setUTCSeconds ( sec, ms )
|
||||
BUILTIN(DatePrototypeSetUTCSeconds) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setUTCSeconds");
|
||||
int const argc = args.length() - 1;
|
||||
Handle<Object> sec = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, sec, Object::ToNumber(sec));
|
||||
double time_val = date->value()->Number();
|
||||
if (!std::isnan(time_val)) {
|
||||
int64_t const time_ms = static_cast<int64_t>(time_val);
|
||||
int day = isolate->date_cache()->DaysFromTime(time_ms);
|
||||
int time_within_day = isolate->date_cache()->TimeInDay(time_ms, day);
|
||||
int h = time_within_day / (60 * 60 * 1000);
|
||||
double m = (time_within_day / (60 * 1000)) % 60;
|
||||
double s = sec->Number();
|
||||
double milli = time_within_day % 1000;
|
||||
if (argc >= 2) {
|
||||
Handle<Object> ms = args.at<Object>(2);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, ms, Object::ToNumber(ms));
|
||||
milli = ms->Number();
|
||||
}
|
||||
time_val = MakeDate(day, MakeTime(h, m, s, milli));
|
||||
}
|
||||
return *JSDate::SetValue(date, TimeClip(time_val));
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.35 Date.prototype.toDateString ( )
|
||||
BUILTIN(DatePrototypeToDateString) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.toDateString");
|
||||
char buffer[128];
|
||||
Vector<char> str(buffer, arraysize(buffer));
|
||||
ToDateString(date->value()->Number(), str, isolate->date_cache(), kDateOnly);
|
||||
return *isolate->factory()->NewStringFromAsciiChecked(str.start());
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.36 Date.prototype.toISOString ( )
|
||||
BUILTIN(DatePrototypeToISOString) {
|
||||
HandleScope scope(isolate);
|
||||
@ -2349,6 +2796,48 @@ BUILTIN(DatePrototypeToISOString) {
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.41 Date.prototype.toString ( )
|
||||
BUILTIN(DatePrototypeToString) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.toString");
|
||||
char buffer[128];
|
||||
Vector<char> str(buffer, arraysize(buffer));
|
||||
ToDateString(date->value()->Number(), str, isolate->date_cache());
|
||||
return *isolate->factory()->NewStringFromAsciiChecked(str.start());
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.42 Date.prototype.toTimeString ( )
|
||||
BUILTIN(DatePrototypeToTimeString) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.toTimeString");
|
||||
char buffer[128];
|
||||
Vector<char> str(buffer, arraysize(buffer));
|
||||
ToDateString(date->value()->Number(), str, isolate->date_cache(), kTimeOnly);
|
||||
return *isolate->factory()->NewStringFromAsciiChecked(str.start());
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.43 Date.prototype.toUTCString ( )
|
||||
BUILTIN(DatePrototypeToUTCString) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.toUTCString");
|
||||
double const time_val = date->value()->Number();
|
||||
if (std::isnan(time_val)) {
|
||||
return *isolate->factory()->NewStringFromAsciiChecked("Invalid Date");
|
||||
}
|
||||
char buffer[128];
|
||||
Vector<char> str(buffer, arraysize(buffer));
|
||||
int64_t time_ms = static_cast<int64_t>(time_val);
|
||||
int year, month, day, weekday, hour, min, sec, ms;
|
||||
isolate->date_cache()->BreakDownTime(time_ms, &year, &month, &day, &weekday,
|
||||
&hour, &min, &sec, &ms);
|
||||
SNPrintF(str, "%s, %02d %s %4d %02d:%02d:%02d GMT", kShortWeekDays[weekday],
|
||||
day, kShortMonths[month], year, hour, min, sec);
|
||||
return *isolate->factory()->NewStringFromAsciiChecked(str.start());
|
||||
}
|
||||
|
||||
|
||||
// ES6 section 20.3.4.44 Date.prototype.valueOf ( )
|
||||
BUILTIN(DatePrototypeValueOf) {
|
||||
HandleScope scope(isolate);
|
||||
@ -2370,6 +2859,47 @@ BUILTIN(DatePrototypeToPrimitive) {
|
||||
}
|
||||
|
||||
|
||||
// ES6 section B.2.4.1 Date.prototype.getYear ( )
|
||||
BUILTIN(DatePrototypeGetYear) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.getYear");
|
||||
double time_val = date->value()->Number();
|
||||
if (std::isnan(time_val)) return date->value();
|
||||
int64_t time_ms = static_cast<int64_t>(time_val);
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int days = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
int year, month, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
|
||||
return Smi::FromInt(year - 1900);
|
||||
}
|
||||
|
||||
|
||||
// ES6 section B.2.4.2 Date.prototype.setYear ( year )
|
||||
BUILTIN(DatePrototypeSetYear) {
|
||||
HandleScope scope(isolate);
|
||||
CHECK_RECEIVER(JSDate, date, "Date.prototype.setYear");
|
||||
Handle<Object> year = args.atOrUndefined(isolate, 1);
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, year, Object::ToNumber(year));
|
||||
double m = 0.0, dt = 1.0, y = year->Number();
|
||||
if (0.0 <= y && y <= 99.0) {
|
||||
y = 1900.0 + DoubleToInteger(y);
|
||||
}
|
||||
int time_within_day = 0;
|
||||
if (!std::isnan(date->value()->Number())) {
|
||||
int64_t const time_ms = static_cast<int64_t>(date->value()->Number());
|
||||
int64_t local_time_ms = isolate->date_cache()->ToLocal(time_ms);
|
||||
int const days = isolate->date_cache()->DaysFromTime(local_time_ms);
|
||||
time_within_day = isolate->date_cache()->TimeInDay(local_time_ms, days);
|
||||
int year, month, day;
|
||||
isolate->date_cache()->YearMonthDayFromDays(days, &year, &month, &day);
|
||||
m = month;
|
||||
dt = day;
|
||||
}
|
||||
double time_val = MakeDate(MakeDay(y, m, dt), time_within_day);
|
||||
return SetLocalDateValue(date, time_val);
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void Builtins::Generate_DatePrototypeGetDate(MacroAssembler* masm) {
|
||||
Generate_DatePrototype_GetField(masm, JSDate::kDay);
|
||||
|
@ -74,9 +74,30 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
|
||||
V(DateNow, kNone) \
|
||||
V(DateParse, kNone) \
|
||||
V(DateUTC, kNone) \
|
||||
V(DatePrototypeSetDate, kNone) \
|
||||
V(DatePrototypeSetFullYear, kNone) \
|
||||
V(DatePrototypeSetHours, kNone) \
|
||||
V(DatePrototypeSetMilliseconds, kNone) \
|
||||
V(DatePrototypeSetMinutes, kNone) \
|
||||
V(DatePrototypeSetMonth, kNone) \
|
||||
V(DatePrototypeSetSeconds, kNone) \
|
||||
V(DatePrototypeSetTime, kNone) \
|
||||
V(DatePrototypeSetUTCDate, kNone) \
|
||||
V(DatePrototypeSetUTCFullYear, kNone) \
|
||||
V(DatePrototypeSetUTCHours, kNone) \
|
||||
V(DatePrototypeSetUTCMilliseconds, kNone) \
|
||||
V(DatePrototypeSetUTCMinutes, kNone) \
|
||||
V(DatePrototypeSetUTCMonth, kNone) \
|
||||
V(DatePrototypeSetUTCSeconds, kNone) \
|
||||
V(DatePrototypeToDateString, kNone) \
|
||||
V(DatePrototypeToISOString, kNone) \
|
||||
V(DatePrototypeToPrimitive, kNone) \
|
||||
V(DatePrototypeToUTCString, kNone) \
|
||||
V(DatePrototypeToString, kNone) \
|
||||
V(DatePrototypeToTimeString, kNone) \
|
||||
V(DatePrototypeValueOf, kNone) \
|
||||
V(DatePrototypeGetYear, kNone) \
|
||||
V(DatePrototypeSetYear, kNone) \
|
||||
\
|
||||
V(FunctionConstructor, kTargetAndNewTarget) \
|
||||
V(FunctionPrototypeBind, kNone) \
|
||||
|
@ -39,8 +39,6 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
||||
return ReduceConstructDouble(node);
|
||||
case Runtime::kInlineCreateIterResultObject:
|
||||
return ReduceCreateIterResultObject(node);
|
||||
case Runtime::kInlineDateField:
|
||||
return ReduceDateField(node);
|
||||
case Runtime::kInlineDeoptimizeNow:
|
||||
return ReduceDeoptimizeNow(node);
|
||||
case Runtime::kInlineDoubleHi:
|
||||
@ -103,8 +101,6 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
|
||||
return ReduceToPrimitive(node);
|
||||
case Runtime::kInlineToString:
|
||||
return ReduceToString(node);
|
||||
case Runtime::kInlineThrowNotDateError:
|
||||
return ReduceThrowNotDateError(node);
|
||||
case Runtime::kInlineCall:
|
||||
return ReduceCall(node);
|
||||
case Runtime::kInlineTailCall:
|
||||
@ -141,24 +137,6 @@ Reduction JSIntrinsicLowering::ReduceConstructDouble(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceDateField(Node* node) {
|
||||
Node* const value = NodeProperties::GetValueInput(node, 0);
|
||||
Node* const index = NodeProperties::GetValueInput(node, 1);
|
||||
Node* const effect = NodeProperties::GetEffectInput(node);
|
||||
Node* const control = NodeProperties::GetControlInput(node);
|
||||
NumberMatcher mindex(index);
|
||||
if (mindex.Is(JSDate::kDateValue)) {
|
||||
return Change(
|
||||
node,
|
||||
simplified()->LoadField(AccessBuilder::ForJSDateField(
|
||||
static_cast<JSDate::FieldIndex>(static_cast<int>(mindex.Value())))),
|
||||
value, effect, control);
|
||||
}
|
||||
// TODO(turbofan): Optimize more patterns.
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceDeoptimizeNow(Node* node) {
|
||||
if (mode() != kDeoptimizationEnabled) return NoChange();
|
||||
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 0);
|
||||
@ -527,24 +505,6 @@ Reduction JSIntrinsicLowering::ReduceSubString(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceThrowNotDateError(Node* node) {
|
||||
if (mode() != kDeoptimizationEnabled) return NoChange();
|
||||
Node* const frame_state = NodeProperties::GetFrameStateInput(node, 1);
|
||||
Node* const effect = NodeProperties::GetEffectInput(node);
|
||||
Node* const control = NodeProperties::GetControlInput(node);
|
||||
|
||||
// TODO(bmeurer): Move MergeControlToEnd() to the AdvancedReducer.
|
||||
Node* deoptimize =
|
||||
graph()->NewNode(common()->Deoptimize(DeoptimizeKind::kEager),
|
||||
frame_state, effect, control);
|
||||
NodeProperties::MergeControlToEnd(graph(), common(), deoptimize);
|
||||
|
||||
node->TrimInputCount(0);
|
||||
NodeProperties::ChangeOp(node, common()->Dead());
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
|
||||
Reduction JSIntrinsicLowering::ReduceToInteger(Node* node) {
|
||||
Node* value = NodeProperties::GetValueInput(node, 0);
|
||||
Type* value_type = NodeProperties::GetType(value);
|
||||
|
@ -40,7 +40,6 @@ class JSIntrinsicLowering final : public AdvancedReducer {
|
||||
private:
|
||||
Reduction ReduceConstructDouble(Node* node);
|
||||
Reduction ReduceCreateIterResultObject(Node* node);
|
||||
Reduction ReduceDateField(Node* node);
|
||||
Reduction ReduceDeoptimizeNow(Node* node);
|
||||
Reduction ReduceDoubleHi(Node* node);
|
||||
Reduction ReduceDoubleLo(Node* node);
|
||||
@ -62,7 +61,6 @@ class JSIntrinsicLowering final : public AdvancedReducer {
|
||||
Reduction ReduceRegExpFlags(Node* node);
|
||||
Reduction ReduceRegExpSource(Node* node);
|
||||
Reduction ReduceSubString(Node* node);
|
||||
Reduction ReduceThrowNotDateError(Node* node);
|
||||
Reduction ReduceToInteger(Node* node);
|
||||
Reduction ReduceToLength(Node* node);
|
||||
Reduction ReduceToName(Node* node);
|
||||
|
@ -155,7 +155,6 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
|
||||
switch (function) {
|
||||
case Runtime::kAllocateInTargetSpace:
|
||||
case Runtime::kCreateIterResultObject:
|
||||
case Runtime::kDateField:
|
||||
case Runtime::kDefineClassMethod: // TODO(jarin): Is it safe?
|
||||
case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
|
||||
case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe?
|
||||
|
@ -1563,7 +1563,6 @@ Type* Typer::Visitor::TypeJSCallRuntime(Node* node) {
|
||||
case Runtime::kInlineDoubleHi:
|
||||
return Type::Signed32();
|
||||
case Runtime::kInlineConstructDouble:
|
||||
case Runtime::kInlineDateField:
|
||||
case Runtime::kInlineMathFloor:
|
||||
case Runtime::kInlineMathSqrt:
|
||||
case Runtime::kInlineMathAcos:
|
||||
|
@ -1825,14 +1825,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* object = UseFixed(instr->value(), r0);
|
||||
LDateField* result =
|
||||
new(zone()) LDateField(object, FixedTemp(r1), instr->index());
|
||||
return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
|
||||
LOperand* string = UseRegisterAtStart(instr->string());
|
||||
LOperand* index = UseRegisterOrConstantAtStart(instr->index());
|
||||
|
@ -60,7 +60,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1374,25 +1373,6 @@ class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
|
||||
inputs_[0] = date;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
||||
|
@ -1810,40 +1810,6 @@ void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
Smi* index = instr->index();
|
||||
DCHECK(object.is(result));
|
||||
DCHECK(object.is(r0));
|
||||
DCHECK(!scratch.is(scratch0()));
|
||||
DCHECK(!scratch.is(object));
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch, Operand(stamp));
|
||||
__ ldr(scratch, MemOperand(scratch));
|
||||
__ ldr(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ cmp(scratch, scratch0());
|
||||
__ b(ne, &runtime);
|
||||
__ ldr(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ mov(r1, Operand(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemOperand LCodeGen::BuildSeqStringOperand(Register string,
|
||||
LOperand* index,
|
||||
String::Encoding encoding) {
|
||||
|
@ -1368,13 +1368,6 @@ LInstruction* LChunkBuilder::DoContext(HContext* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* object = UseFixed(instr->value(), x0);
|
||||
LDateField* result = new(zone()) LDateField(object, instr->index());
|
||||
return MarkAsCall(DefineFixed(result, x0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDebugBreak(HDebugBreak* instr) {
|
||||
return new(zone()) LDebugBreak();
|
||||
}
|
||||
|
@ -64,7 +64,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1243,23 +1242,6 @@ class LContext final : public LTemplateInstruction<1, 0, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
LDateField(LOperand* date, Smi* index) : index_(index) {
|
||||
inputs_[0] = date;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LDebugBreak final : public LTemplateInstruction<0, 0, 0> {
|
||||
public:
|
||||
DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
|
||||
|
@ -2516,40 +2516,6 @@ void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register temp1 = x10;
|
||||
Register temp2 = x11;
|
||||
Smi* index = instr->index();
|
||||
|
||||
DCHECK(object.is(result) && object.Is(x0));
|
||||
DCHECK(instr->IsMarkedAsCall());
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ Mov(temp1, Operand(stamp));
|
||||
__ Ldr(temp1, MemOperand(temp1));
|
||||
__ Ldr(temp2, FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ Cmp(temp1, temp2);
|
||||
__ B(ne, &runtime);
|
||||
__ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ B(&done);
|
||||
}
|
||||
|
||||
__ Bind(&runtime);
|
||||
__ Mov(x1, Operand(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ Bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDeoptimize(LDeoptimize* instr) {
|
||||
Deoptimizer::BailoutType type = instr->hydrogen()->type();
|
||||
// TODO(danno): Stubs expect all deopts to be lazy for historical reasons (the
|
||||
|
@ -849,7 +849,6 @@ bool HInstruction::CanDeoptimize() {
|
||||
case HValue::kCheckSmi:
|
||||
case HValue::kCheckValue:
|
||||
case HValue::kClampToUint8:
|
||||
case HValue::kDateField:
|
||||
case HValue::kDeoptimize:
|
||||
case HValue::kDiv:
|
||||
case HValue::kForInCacheArray:
|
||||
|
@ -85,7 +85,6 @@ class LChunkBuilder;
|
||||
V(Constant) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -7532,28 +7531,6 @@ class HToFastProperties final : public HUnaryOperation {
|
||||
};
|
||||
|
||||
|
||||
class HDateField final : public HUnaryOperation {
|
||||
public:
|
||||
DECLARE_INSTRUCTION_FACTORY_P2(HDateField, HValue*, Smi*);
|
||||
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
Representation RequiredInputRepresentation(int index) override {
|
||||
return Representation::Tagged();
|
||||
}
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField)
|
||||
|
||||
private:
|
||||
HDateField(HValue* date, Smi* index)
|
||||
: HUnaryOperation(date), index_(index) {
|
||||
set_representation(Representation::Tagged());
|
||||
}
|
||||
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class HSeqStringGetChar final : public HTemplateInstruction<2> {
|
||||
public:
|
||||
static HInstruction* New(Isolate* isolate, Zone* zone, HValue* context,
|
||||
|
@ -12463,25 +12463,6 @@ void HOptimizedGraphBuilder::GenerateIsDate(CallRuntime* call) {
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::GenerateThrowNotDateError(CallRuntime* call) {
|
||||
DCHECK_EQ(0, call->arguments()->length());
|
||||
Add<HDeoptimize>(Deoptimizer::kNotADateObject, Deoptimizer::EAGER);
|
||||
Add<HSimulate>(call->id(), FIXED_SIMULATE);
|
||||
return ast_context()->ReturnValue(graph()->GetConstantUndefined());
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) {
|
||||
DCHECK(call->arguments()->length() == 2);
|
||||
DCHECK_NOT_NULL(call->arguments()->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value()));
|
||||
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
|
||||
HValue* date = Pop();
|
||||
HDateField* result = New<HDateField>(date, index);
|
||||
return ast_context()->ReturnInstruction(result, call->id());
|
||||
}
|
||||
|
||||
|
||||
void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar(
|
||||
CallRuntime* call) {
|
||||
DCHECK(call->arguments()->length() == 3);
|
||||
|
@ -2205,8 +2205,6 @@ class HOptimizedGraphBuilder : public HGraphBuilder, public AstVisitor {
|
||||
F(ValueOf) \
|
||||
F(SetValueOf) \
|
||||
F(IsDate) \
|
||||
F(DateField) \
|
||||
F(ThrowNotDateError) \
|
||||
F(StringCharFromCode) \
|
||||
F(StringCharAt) \
|
||||
F(OneByteSeqStringSetChar) \
|
||||
|
@ -1675,37 +1675,6 @@ void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
Smi* index = instr->index();
|
||||
DCHECK(object.is(result));
|
||||
DCHECK(object.is(eax));
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch, Operand::StaticVariable(stamp));
|
||||
__ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset));
|
||||
__ j(not_equal, &runtime, Label::kNear);
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done, Label::kNear);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ mov(Operand(esp, 0), object);
|
||||
__ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Operand LCodeGen::BuildSeqStringOperand(Register string,
|
||||
LOperand* index,
|
||||
String::Encoding encoding) {
|
||||
|
@ -1786,14 +1786,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* date = UseFixed(instr->value(), eax);
|
||||
LDateField* result =
|
||||
new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
|
||||
return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
|
||||
LOperand* string = UseRegisterAtStart(instr->string());
|
||||
LOperand* index = UseRegisterOrConstantAtStart(instr->index());
|
||||
|
@ -64,7 +64,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1351,27 +1350,6 @@ class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
LDateField(LOperand* date, LOperand* temp, Smi* index)
|
||||
: index_(index) {
|
||||
inputs_[0] = date;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
||||
|
@ -1659,39 +1659,6 @@ void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
Smi* index = instr->index();
|
||||
DCHECK(object.is(a0));
|
||||
DCHECK(result.is(v0));
|
||||
DCHECK(!scratch.is(scratch0()));
|
||||
DCHECK(!scratch.is(object));
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ li(scratch, Operand(stamp));
|
||||
__ lw(scratch, MemOperand(scratch));
|
||||
__ lw(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ Branch(&runtime, ne, scratch, Operand(scratch0()));
|
||||
__ lw(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ li(a1, Operand(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemOperand LCodeGen::BuildSeqStringOperand(Register string,
|
||||
LOperand* index,
|
||||
String::Encoding encoding) {
|
||||
|
@ -1772,14 +1772,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* object = UseFixed(instr->value(), a0);
|
||||
LDateField* result =
|
||||
new(zone()) LDateField(object, FixedTemp(a1), instr->index());
|
||||
return MarkAsCall(DefineFixed(result, v0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
|
||||
LOperand* string = UseRegisterAtStart(instr->string());
|
||||
LOperand* index = UseRegisterOrConstantAtStart(instr->index());
|
||||
|
@ -60,7 +60,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1337,25 +1336,6 @@ class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
|
||||
inputs_[0] = date;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
||||
|
@ -1756,39 +1756,6 @@ void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
Smi* index = instr->index();
|
||||
DCHECK(object.is(a0));
|
||||
DCHECK(result.is(v0));
|
||||
DCHECK(!scratch.is(scratch0()));
|
||||
DCHECK(!scratch.is(object));
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ ld(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ li(scratch, Operand(stamp));
|
||||
__ ld(scratch, MemOperand(scratch));
|
||||
__ ld(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ Branch(&runtime, ne, scratch, Operand(scratch0()));
|
||||
__ ld(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ li(a1, Operand(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemOperand LCodeGen::BuildSeqStringOperand(Register string,
|
||||
LOperand* index,
|
||||
String::Encoding encoding) {
|
||||
|
@ -1778,14 +1778,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* object = UseFixed(instr->value(), a0);
|
||||
LDateField* result =
|
||||
new(zone()) LDateField(object, FixedTemp(a1), instr->index());
|
||||
return MarkAsCall(DefineFixed(result, v0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
|
||||
LOperand* string = UseRegisterAtStart(instr->string());
|
||||
LOperand* index = UseRegisterOrConstantAtStart(instr->index());
|
||||
|
@ -62,7 +62,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1369,25 +1368,6 @@ class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
|
||||
inputs_[0] = date;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
||||
|
@ -1813,41 +1813,6 @@ void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
Smi* index = instr->index();
|
||||
DCHECK(object.is(result));
|
||||
DCHECK(object.is(r3));
|
||||
DCHECK(!scratch.is(scratch0()));
|
||||
DCHECK(!scratch.is(object));
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ LoadP(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch, Operand(stamp));
|
||||
__ LoadP(scratch, MemOperand(scratch));
|
||||
__ LoadP(scratch0(), FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ cmp(scratch, scratch0());
|
||||
__ bne(&runtime);
|
||||
__ LoadP(result,
|
||||
FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ b(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ LoadSmiLiteral(r4, index);
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MemOperand LCodeGen::BuildSeqStringOperand(Register string, LOperand* index,
|
||||
String::Encoding encoding) {
|
||||
if (index->IsConstantOperand()) {
|
||||
|
@ -1788,14 +1788,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* object = UseFixed(instr->value(), r3);
|
||||
LDateField* result =
|
||||
new (zone()) LDateField(object, FixedTemp(r4), instr->index());
|
||||
return MarkAsCall(DefineFixed(result, r3), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
|
||||
LOperand* string = UseRegisterAtStart(instr->string());
|
||||
LOperand* index = UseRegisterOrConstantAtStart(instr->index());
|
||||
|
@ -60,7 +60,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1325,25 +1324,6 @@ class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
LDateField(LOperand* date, LOperand* temp, Smi* index) : index_(index) {
|
||||
inputs_[0] = date;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
||||
|
@ -1667,44 +1667,6 @@ void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Smi* index = instr->index();
|
||||
DCHECK(object.is(result));
|
||||
DCHECK(object.is(rax));
|
||||
|
||||
if (FLAG_debug_code) {
|
||||
__ AssertNotSmi(object);
|
||||
__ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister);
|
||||
__ Check(equal, kOperandIsNotADate);
|
||||
}
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ movp(result, FieldOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
Operand stamp_operand = __ ExternalOperand(stamp);
|
||||
__ movp(kScratchRegister, stamp_operand);
|
||||
__ cmpp(kScratchRegister, FieldOperand(object,
|
||||
JSDate::kCacheStampOffset));
|
||||
__ j(not_equal, &runtime, Label::kNear);
|
||||
__ movp(result, FieldOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done, Label::kNear);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2);
|
||||
__ movp(arg_reg_1, object);
|
||||
__ Move(arg_reg_2, index, Assembler::RelocInfoNone());
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Operand LCodeGen::BuildSeqStringOperand(Register string,
|
||||
LOperand* index,
|
||||
String::Encoding encoding) {
|
||||
|
@ -1779,13 +1779,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* object = UseFixed(instr->value(), rax);
|
||||
LDateField* result = new(zone()) LDateField(object, instr->index());
|
||||
return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
|
||||
LOperand* string = UseRegisterAtStart(instr->string());
|
||||
LOperand* index = UseRegisterOrConstantAtStart(instr->index());
|
||||
|
@ -60,7 +60,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1343,23 +1342,6 @@ class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 0> {
|
||||
public:
|
||||
LDateField(LOperand* date, Smi* index) : index_(index) {
|
||||
inputs_[0] = date;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
||||
|
@ -1952,37 +1952,6 @@ void LCodeGen::DoMapEnumLength(LMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
void LCodeGen::DoDateField(LDateField* instr) {
|
||||
Register object = ToRegister(instr->date());
|
||||
Register result = ToRegister(instr->result());
|
||||
Register scratch = ToRegister(instr->temp());
|
||||
Smi* index = instr->index();
|
||||
DCHECK(object.is(result));
|
||||
DCHECK(object.is(eax));
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch, Operand::StaticVariable(stamp));
|
||||
__ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset));
|
||||
__ j(not_equal, &runtime, Label::kNear);
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done, Label::kNear);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ mov(Operand(esp, 0), object);
|
||||
__ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Operand LCodeGen::BuildSeqStringOperand(Register string,
|
||||
LOperand* index,
|
||||
String::Encoding encoding) {
|
||||
|
@ -1791,14 +1791,6 @@ LInstruction* LChunkBuilder::DoMapEnumLength(HMapEnumLength* instr) {
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoDateField(HDateField* instr) {
|
||||
LOperand* date = UseFixed(instr->value(), eax);
|
||||
LDateField* result =
|
||||
new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
|
||||
return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoSeqStringGetChar(HSeqStringGetChar* instr) {
|
||||
LOperand* string = UseRegisterAtStart(instr->string());
|
||||
LOperand* index = UseRegisterOrConstantAtStart(instr->index());
|
||||
|
@ -65,7 +65,6 @@ class LCodeGen;
|
||||
V(ConstantT) \
|
||||
V(ConstructDouble) \
|
||||
V(Context) \
|
||||
V(DateField) \
|
||||
V(DebugBreak) \
|
||||
V(DeclareGlobals) \
|
||||
V(Deoptimize) \
|
||||
@ -1357,27 +1356,6 @@ class LMapEnumLength final : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LDateField final : public LTemplateInstruction<1, 1, 1> {
|
||||
public:
|
||||
LDateField(LOperand* date, LOperand* temp, Smi* index)
|
||||
: index_(index) {
|
||||
inputs_[0] = date;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* date() { return inputs_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(DateField, "date-field")
|
||||
DECLARE_HYDROGEN_ACCESSOR(DateField)
|
||||
|
||||
Smi* index() const { return index_; }
|
||||
|
||||
private:
|
||||
Smi* index_;
|
||||
};
|
||||
|
||||
|
||||
class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
|
||||
public:
|
||||
LSeqStringGetChar(LOperand* string, LOperand* index) {
|
||||
|
@ -3430,45 +3430,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = r0;
|
||||
Register result = r0;
|
||||
Register scratch0 = r9;
|
||||
Register scratch1 = r1;
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch1, Operand(stamp));
|
||||
__ ldr(scratch1, MemOperand(scratch1));
|
||||
__ ldr(scratch0, FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ cmp(scratch1, scratch0);
|
||||
__ b(ne, &runtime);
|
||||
__ ldr(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch1);
|
||||
__ mov(r1, Operand(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
@ -3145,45 +3145,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = x0;
|
||||
Register result = x0;
|
||||
Register stamp_addr = x10;
|
||||
Register stamp_cache = x11;
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ Mov(stamp_addr, stamp);
|
||||
__ Ldr(stamp_addr, MemOperand(stamp_addr));
|
||||
__ Ldr(stamp_cache, FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ Cmp(stamp_addr, stamp_cache);
|
||||
__ B(ne, &runtime);
|
||||
__ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ B(&done);
|
||||
}
|
||||
|
||||
__ Bind(&runtime);
|
||||
__ Mov(x1, index);
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ Bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
@ -482,7 +482,6 @@ class FullCodeGenerator: public AstVisitor {
|
||||
F(ValueOf) \
|
||||
F(SetValueOf) \
|
||||
F(IsDate) \
|
||||
F(DateField) \
|
||||
F(StringCharFromCode) \
|
||||
F(StringCharAt) \
|
||||
F(OneByteSeqStringSetChar) \
|
||||
|
@ -3310,43 +3310,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = eax;
|
||||
Register result = eax;
|
||||
Register scratch = ecx;
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch, Operand::StaticVariable(stamp));
|
||||
__ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset));
|
||||
__ j(not_equal, &runtime, Label::kNear);
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done, Label::kNear);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ mov(Operand(esp, 0), object);
|
||||
__ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
@ -3426,45 +3426,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = v0;
|
||||
Register result = v0;
|
||||
Register scratch0 = t5;
|
||||
Register scratch1 = a1;
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ li(scratch1, Operand(stamp));
|
||||
__ lw(scratch1, MemOperand(scratch1));
|
||||
__ lw(scratch0, FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ Branch(&runtime, ne, scratch1, Operand(scratch0));
|
||||
__ lw(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch1);
|
||||
__ li(a1, Operand(index));
|
||||
__ Move(a0, object);
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
@ -3431,45 +3431,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = v0;
|
||||
Register result = v0;
|
||||
Register scratch0 = t1;
|
||||
Register scratch1 = a1;
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ ld(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ li(scratch1, Operand(stamp));
|
||||
__ ld(scratch1, MemOperand(scratch1));
|
||||
__ ld(scratch0, FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ Branch(&runtime, ne, scratch1, Operand(scratch0));
|
||||
__ ld(result, FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch1);
|
||||
__ li(a1, Operand(index));
|
||||
__ Move(a0, object);
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
@ -3431,47 +3431,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = r3;
|
||||
Register result = r3;
|
||||
Register scratch0 = r11;
|
||||
Register scratch1 = r4;
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ LoadP(result, FieldMemOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch1, Operand(stamp));
|
||||
__ LoadP(scratch1, MemOperand(scratch1));
|
||||
__ LoadP(scratch0, FieldMemOperand(object, JSDate::kCacheStampOffset));
|
||||
__ cmp(scratch1, scratch0);
|
||||
__ bne(&runtime);
|
||||
__ LoadP(result,
|
||||
FieldMemOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()),
|
||||
scratch0);
|
||||
__ b(&done);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch1);
|
||||
__ LoadSmiLiteral(r4, index);
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
@ -3298,49 +3298,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = rax;
|
||||
Register result = rax;
|
||||
Register scratch = rcx;
|
||||
|
||||
if (FLAG_debug_code) {
|
||||
__ AssertNotSmi(object);
|
||||
__ CmpObjectType(object, JS_DATE_TYPE, scratch);
|
||||
__ Check(equal, kOperandIsNotADate);
|
||||
}
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ movp(result, FieldOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
__ Load(scratch, ExternalReference::date_cache_stamp(isolate()));
|
||||
__ cmpp(scratch, FieldOperand(object, JSDate::kCacheStampOffset));
|
||||
__ j(not_equal, &runtime, Label::kNear);
|
||||
__ movp(result, FieldOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done, Label::kNear);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2);
|
||||
__ movp(arg_reg_1, object);
|
||||
__ Move(arg_reg_2, index, Assembler::RelocInfoNone());
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(rax);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
@ -3302,43 +3302,6 @@ void FullCodeGenerator::EmitIsDate(CallRuntime* expr) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK(args->length() == 2);
|
||||
DCHECK_NOT_NULL(args->at(1)->AsLiteral());
|
||||
Smi* index = Smi::cast(*(args->at(1)->AsLiteral()->value()));
|
||||
|
||||
VisitForAccumulatorValue(args->at(0)); // Load the object.
|
||||
|
||||
Register object = eax;
|
||||
Register result = eax;
|
||||
Register scratch = ecx;
|
||||
|
||||
if (index->value() == 0) {
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
|
||||
} else {
|
||||
Label runtime, done;
|
||||
if (index->value() < JSDate::kFirstUncachedField) {
|
||||
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
|
||||
__ mov(scratch, Operand::StaticVariable(stamp));
|
||||
__ cmp(scratch, FieldOperand(object, JSDate::kCacheStampOffset));
|
||||
__ j(not_equal, &runtime, Label::kNear);
|
||||
__ mov(result, FieldOperand(object, JSDate::kValueOffset +
|
||||
kPointerSize * index->value()));
|
||||
__ jmp(&done, Label::kNear);
|
||||
}
|
||||
__ bind(&runtime);
|
||||
__ PrepareCallCFunction(2, scratch);
|
||||
__ mov(Operand(esp, 0), object);
|
||||
__ mov(Operand(esp, 1 * kPointerSize), Immediate(index));
|
||||
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
context()->Plug(result);
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitOneByteSeqStringSetChar(CallRuntime* expr) {
|
||||
ZoneList<Expression*>* args = expr->arguments();
|
||||
DCHECK_EQ(3, args->length());
|
||||
|
547
src/js/date.js
547
src/js/date.js
@ -1,547 +0,0 @@
|
||||
// Copyright 2006-2008 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
(function(global, utils) {
|
||||
|
||||
"use strict";
|
||||
|
||||
%CheckIsBootstrapping();
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Imports
|
||||
|
||||
var GlobalDate = global.Date;
|
||||
var GlobalObject = global.Object;
|
||||
var InternalArray = utils.InternalArray;
|
||||
var IsFinite;
|
||||
var MakeRangeError;
|
||||
var MathAbs;
|
||||
var MathFloor;
|
||||
var NaN = %GetRootNaN();
|
||||
|
||||
utils.Import(function(from) {
|
||||
IsFinite = from.IsFinite;
|
||||
MakeRangeError = from.MakeRangeError;
|
||||
MathAbs = from.MathAbs;
|
||||
MathFloor = from.MathFloor;
|
||||
});
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// This file contains date support implemented in JavaScript.
|
||||
|
||||
var timezone_cache_time = NaN;
|
||||
var timezone_cache_timezone;
|
||||
|
||||
function LocalTimezone(t) {
|
||||
if (NUMBER_IS_NAN(t)) return "";
|
||||
CheckDateCacheCurrent();
|
||||
if (t == timezone_cache_time) {
|
||||
return timezone_cache_timezone;
|
||||
}
|
||||
var timezone = %DateLocalTimezone(t);
|
||||
timezone_cache_time = t;
|
||||
timezone_cache_timezone = timezone;
|
||||
return timezone;
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.1.11
|
||||
function MakeTime(hour, min, sec, ms) {
|
||||
if (!IsFinite(hour)) return NaN;
|
||||
if (!IsFinite(min)) return NaN;
|
||||
if (!IsFinite(sec)) return NaN;
|
||||
if (!IsFinite(ms)) return NaN;
|
||||
return TO_INTEGER(hour) * msPerHour
|
||||
+ TO_INTEGER(min) * msPerMinute
|
||||
+ TO_INTEGER(sec) * msPerSecond
|
||||
+ TO_INTEGER(ms);
|
||||
}
|
||||
|
||||
|
||||
// Compute number of days given a year, month, date.
|
||||
// Note that month and date can lie outside the normal range.
|
||||
// For example:
|
||||
// MakeDay(2007, -4, 20) --> MakeDay(2006, 8, 20)
|
||||
// MakeDay(2007, -33, 1) --> MakeDay(2004, 3, 1)
|
||||
// MakeDay(2007, 14, -50) --> MakeDay(2007, 8, 11)
|
||||
function MakeDay(year, month, date) {
|
||||
if (!IsFinite(year) || !IsFinite(month) || !IsFinite(date)) return NaN;
|
||||
|
||||
// Convert to integer and map -0 to 0.
|
||||
year = TO_INTEGER_MAP_MINUS_ZERO(year);
|
||||
month = TO_INTEGER_MAP_MINUS_ZERO(month);
|
||||
date = TO_INTEGER_MAP_MINUS_ZERO(date);
|
||||
|
||||
if (year < kMinYear || year > kMaxYear ||
|
||||
month < kMinMonth || month > kMaxMonth) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
// Now we rely on year and month being SMIs.
|
||||
return %DateMakeDay(year | 0, month | 0) + date - 1;
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.1.13
|
||||
function MakeDate(day, time) {
|
||||
var time = day * msPerDay + time;
|
||||
// Some of our runtime funtions for computing UTC(time) rely on
|
||||
// times not being significantly larger than MAX_TIME_MS. If there
|
||||
// is no way that the time can be within range even after UTC
|
||||
// conversion we return NaN immediately instead of relying on
|
||||
// TimeClip to do it.
|
||||
if (MathAbs(time) > MAX_TIME_BEFORE_UTC) return NaN;
|
||||
return time;
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.1.14
|
||||
function TimeClip(time) {
|
||||
if (!IsFinite(time)) return NaN;
|
||||
if (MathAbs(time) > MAX_TIME_MS) return NaN;
|
||||
return TO_INTEGER(time) + 0;
|
||||
}
|
||||
|
||||
|
||||
var WeekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||
var Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
|
||||
|
||||
function TwoDigitString(value) {
|
||||
return value < 10 ? "0" + value : "" + value;
|
||||
}
|
||||
|
||||
|
||||
function DateString(date) {
|
||||
CHECK_DATE(date);
|
||||
return WeekDays[LOCAL_WEEKDAY(date)] + ' '
|
||||
+ Months[LOCAL_MONTH(date)] + ' '
|
||||
+ TwoDigitString(LOCAL_DAY(date)) + ' '
|
||||
+ LOCAL_YEAR(date);
|
||||
}
|
||||
|
||||
|
||||
var LongWeekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
|
||||
'Thursday', 'Friday', 'Saturday'];
|
||||
var LongMonths = ['January', 'February', 'March', 'April', 'May', 'June',
|
||||
'July', 'August', 'September', 'October', 'November', 'December'];
|
||||
|
||||
|
||||
function LongDateString(date) {
|
||||
CHECK_DATE(date);
|
||||
return LongWeekDays[LOCAL_WEEKDAY(date)] + ', '
|
||||
+ LongMonths[LOCAL_MONTH(date)] + ' '
|
||||
+ TwoDigitString(LOCAL_DAY(date)) + ', '
|
||||
+ LOCAL_YEAR(date);
|
||||
}
|
||||
|
||||
|
||||
function TimeString(date) {
|
||||
CHECK_DATE(date);
|
||||
return TwoDigitString(LOCAL_HOUR(date)) + ':'
|
||||
+ TwoDigitString(LOCAL_MIN(date)) + ':'
|
||||
+ TwoDigitString(LOCAL_SEC(date));
|
||||
}
|
||||
|
||||
|
||||
function TimeStringUTC(date) {
|
||||
CHECK_DATE(date);
|
||||
return TwoDigitString(UTC_HOUR(date)) + ':'
|
||||
+ TwoDigitString(UTC_MIN(date)) + ':'
|
||||
+ TwoDigitString(UTC_SEC(date));
|
||||
}
|
||||
|
||||
|
||||
function LocalTimezoneString(date) {
|
||||
CHECK_DATE(date);
|
||||
var timezone = LocalTimezone(UTC_DATE_VALUE(date));
|
||||
|
||||
var timezoneOffset = -TIMEZONE_OFFSET(date);
|
||||
var sign = (timezoneOffset >= 0) ? 1 : -1;
|
||||
var hours = MathFloor((sign * timezoneOffset)/60);
|
||||
var min = MathFloor((sign * timezoneOffset)%60);
|
||||
var gmt = ' GMT' + ((sign == 1) ? '+' : '-') +
|
||||
TwoDigitString(hours) + TwoDigitString(min);
|
||||
return gmt + ' (' + timezone + ')';
|
||||
}
|
||||
|
||||
|
||||
function DatePrintString(date) {
|
||||
CHECK_DATE(date);
|
||||
return DateString(date) + ' ' + TimeString(date);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// ECMA 262 - 15.9.5.2
|
||||
function DateToString() {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this)
|
||||
if (NUMBER_IS_NAN(t)) return kInvalidDate;
|
||||
var time_zone_string = LocalTimezoneString(this)
|
||||
return DatePrintString(this) + time_zone_string;
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.3
|
||||
function DateToDateString() {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
if (NUMBER_IS_NAN(t)) return kInvalidDate;
|
||||
return DateString(this);
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.4
|
||||
function DateToTimeString() {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
if (NUMBER_IS_NAN(t)) return kInvalidDate;
|
||||
var time_zone_string = LocalTimezoneString(this);
|
||||
return TimeString(this) + time_zone_string;
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.5
|
||||
function DateToLocaleString() {
|
||||
CHECK_DATE(this);
|
||||
return %_Call(DateToString, this);
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.6
|
||||
function DateToLocaleDateString() {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
if (NUMBER_IS_NAN(t)) return kInvalidDate;
|
||||
return LongDateString(this);
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.7
|
||||
function DateToLocaleTimeString() {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
if (NUMBER_IS_NAN(t)) return kInvalidDate;
|
||||
return TimeString(this);
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.27
|
||||
function DateSetTime(ms) {
|
||||
CHECK_DATE(this);
|
||||
SET_UTC_DATE_VALUE(this, TO_NUMBER(ms));
|
||||
return UTC_DATE_VALUE(this);
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.28
|
||||
function DateSetMilliseconds(ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
ms = TO_NUMBER(ms);
|
||||
var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.29
|
||||
function DateSetUTCMilliseconds(ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
ms = TO_NUMBER(ms);
|
||||
var time = MakeTime(UTC_HOUR(this),
|
||||
UTC_MIN(this),
|
||||
UTC_SEC(this),
|
||||
ms);
|
||||
return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.30
|
||||
function DateSetSeconds(sec, ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
sec = TO_NUMBER(sec);
|
||||
ms = %_ArgumentsLength() < 2 ? LOCAL_MS(this) : TO_NUMBER(ms);
|
||||
var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), sec, ms);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.31
|
||||
function DateSetUTCSeconds(sec, ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
sec = TO_NUMBER(sec);
|
||||
ms = %_ArgumentsLength() < 2 ? UTC_MS(this) : TO_NUMBER(ms);
|
||||
var time = MakeTime(UTC_HOUR(this), UTC_MIN(this), sec, ms);
|
||||
return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.33
|
||||
function DateSetMinutes(min, sec, ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
min = TO_NUMBER(min);
|
||||
var argc = %_ArgumentsLength();
|
||||
sec = argc < 2 ? LOCAL_SEC(this) : TO_NUMBER(sec);
|
||||
ms = argc < 3 ? LOCAL_MS(this) : TO_NUMBER(ms);
|
||||
var time = MakeTime(LOCAL_HOUR(this), min, sec, ms);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.34
|
||||
function DateSetUTCMinutes(min, sec, ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
min = TO_NUMBER(min);
|
||||
var argc = %_ArgumentsLength();
|
||||
sec = argc < 2 ? UTC_SEC(this) : TO_NUMBER(sec);
|
||||
ms = argc < 3 ? UTC_MS(this) : TO_NUMBER(ms);
|
||||
var time = MakeTime(UTC_HOUR(this), min, sec, ms);
|
||||
return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.35
|
||||
function DateSetHours(hour, min, sec, ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
hour = TO_NUMBER(hour);
|
||||
var argc = %_ArgumentsLength();
|
||||
min = argc < 2 ? LOCAL_MIN(this) : TO_NUMBER(min);
|
||||
sec = argc < 3 ? LOCAL_SEC(this) : TO_NUMBER(sec);
|
||||
ms = argc < 4 ? LOCAL_MS(this) : TO_NUMBER(ms);
|
||||
var time = MakeTime(hour, min, sec, ms);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(LOCAL_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.34
|
||||
function DateSetUTCHours(hour, min, sec, ms) {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
hour = TO_NUMBER(hour);
|
||||
var argc = %_ArgumentsLength();
|
||||
min = argc < 2 ? UTC_MIN(this) : TO_NUMBER(min);
|
||||
sec = argc < 3 ? UTC_SEC(this) : TO_NUMBER(sec);
|
||||
ms = argc < 4 ? UTC_MS(this) : TO_NUMBER(ms);
|
||||
var time = MakeTime(hour, min, sec, ms);
|
||||
return SET_UTC_DATE_VALUE(this, MakeDate(UTC_DAYS(this), time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.36
|
||||
function DateSetDate(date) {
|
||||
CHECK_DATE(this);
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
date = TO_NUMBER(date);
|
||||
var day = MakeDay(LOCAL_YEAR(this), LOCAL_MONTH(this), date);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.37
|
||||
function DateSetUTCDate(date) {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
date = TO_NUMBER(date);
|
||||
var day = MakeDay(UTC_YEAR(this), UTC_MONTH(this), date);
|
||||
return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.38
|
||||
function DateSetMonth(month, date) {
|
||||
CHECK_DATE(this);
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
month = TO_NUMBER(month);
|
||||
date = %_ArgumentsLength() < 2 ? LOCAL_DAY(this) : TO_NUMBER(date);
|
||||
var day = MakeDay(LOCAL_YEAR(this), month, date);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(day, LOCAL_TIME_IN_DAY(this)));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.39
|
||||
function DateSetUTCMonth(month, date) {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
month = TO_NUMBER(month);
|
||||
date = %_ArgumentsLength() < 2 ? UTC_DAY(this) : TO_NUMBER(date);
|
||||
var day = MakeDay(UTC_YEAR(this), month, date);
|
||||
return SET_UTC_DATE_VALUE(this, MakeDate(day, UTC_TIME_IN_DAY(this)));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.40
|
||||
function DateSetFullYear(year, month, date) {
|
||||
CHECK_DATE(this);
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
year = TO_NUMBER(year);
|
||||
var argc = %_ArgumentsLength();
|
||||
var time ;
|
||||
if (NUMBER_IS_NAN(t)) {
|
||||
month = argc < 2 ? 0 : TO_NUMBER(month);
|
||||
date = argc < 3 ? 1 : TO_NUMBER(date);
|
||||
time = 0;
|
||||
} else {
|
||||
month = argc < 2 ? LOCAL_MONTH(this) : TO_NUMBER(month);
|
||||
date = argc < 3 ? LOCAL_DAY(this) : TO_NUMBER(date);
|
||||
time = LOCAL_TIME_IN_DAY(this);
|
||||
}
|
||||
var day = MakeDay(year, month, date);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.41
|
||||
function DateSetUTCFullYear(year, month, date) {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
year = TO_NUMBER(year);
|
||||
var argc = %_ArgumentsLength();
|
||||
var time ;
|
||||
if (NUMBER_IS_NAN(t)) {
|
||||
month = argc < 2 ? 0 : TO_NUMBER(month);
|
||||
date = argc < 3 ? 1 : TO_NUMBER(date);
|
||||
time = 0;
|
||||
} else {
|
||||
month = argc < 2 ? UTC_MONTH(this) : TO_NUMBER(month);
|
||||
date = argc < 3 ? UTC_DAY(this) : TO_NUMBER(date);
|
||||
time = UTC_TIME_IN_DAY(this);
|
||||
}
|
||||
var day = MakeDay(year, month, date);
|
||||
return SET_UTC_DATE_VALUE(this, MakeDate(day, time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - 15.9.5.42
|
||||
function DateToUTCString() {
|
||||
CHECK_DATE(this);
|
||||
var t = UTC_DATE_VALUE(this);
|
||||
if (NUMBER_IS_NAN(t)) return kInvalidDate;
|
||||
// Return UTC string of the form: Sat, 31 Jan 1970 23:00:00 GMT
|
||||
return WeekDays[UTC_WEEKDAY(this)] + ', '
|
||||
+ TwoDigitString(UTC_DAY(this)) + ' '
|
||||
+ Months[UTC_MONTH(this)] + ' '
|
||||
+ UTC_YEAR(this) + ' '
|
||||
+ TimeStringUTC(this) + ' GMT';
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - B.2.4
|
||||
function DateGetYear() {
|
||||
CHECK_DATE(this);
|
||||
return LOCAL_YEAR(this) - 1900;
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - B.2.5
|
||||
function DateSetYear(year) {
|
||||
CHECK_DATE(this);
|
||||
year = TO_NUMBER(year);
|
||||
if (NUMBER_IS_NAN(year)) return SET_UTC_DATE_VALUE(this, NaN);
|
||||
year = (0 <= TO_INTEGER(year) && TO_INTEGER(year) <= 99)
|
||||
? 1900 + TO_INTEGER(year) : year;
|
||||
var t = LOCAL_DATE_VALUE(this);
|
||||
var month, date, time;
|
||||
if (NUMBER_IS_NAN(t)) {
|
||||
month = 0;
|
||||
date = 1;
|
||||
time = 0;
|
||||
} else {
|
||||
month = LOCAL_MONTH(this);
|
||||
date = LOCAL_DAY(this);
|
||||
time = LOCAL_TIME_IN_DAY(this);
|
||||
}
|
||||
var day = MakeDay(year, month, date);
|
||||
return SET_LOCAL_DATE_VALUE(this, MakeDate(day, time));
|
||||
}
|
||||
|
||||
|
||||
// ECMA 262 - B.2.6
|
||||
//
|
||||
// Notice that this does not follow ECMA 262 completely. ECMA 262
|
||||
// says that toGMTString should be the same Function object as
|
||||
// toUTCString. JSC does not do this, so for compatibility we do not
|
||||
// do that either. Instead, we create a new function whose name
|
||||
// property will return toGMTString.
|
||||
function DateToGMTString() {
|
||||
return %_Call(DateToUTCString, this);
|
||||
}
|
||||
|
||||
|
||||
// 20.3.4.37 Date.prototype.toJSON ( key )
|
||||
function DateToJSON(key) {
|
||||
var o = TO_OBJECT(this);
|
||||
var tv = TO_PRIMITIVE_NUMBER(o);
|
||||
if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
|
||||
return null;
|
||||
}
|
||||
return o.toISOString();
|
||||
}
|
||||
|
||||
|
||||
var date_cache_version_holder;
|
||||
var date_cache_version = NaN;
|
||||
|
||||
|
||||
function CheckDateCacheCurrent() {
|
||||
if (!date_cache_version_holder) {
|
||||
date_cache_version_holder = %DateCacheVersion();
|
||||
if (!date_cache_version_holder) return;
|
||||
}
|
||||
if (date_cache_version_holder[0] == date_cache_version) {
|
||||
return;
|
||||
}
|
||||
date_cache_version = date_cache_version_holder[0];
|
||||
|
||||
// Reset the timezone cache:
|
||||
timezone_cache_time = NaN;
|
||||
timezone_cache_timezone = UNDEFINED;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
%FunctionSetPrototype(GlobalDate, new GlobalObject());
|
||||
|
||||
// Set up non-enumerable functions of the Date prototype object and
|
||||
// set their names.
|
||||
utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
|
||||
"toString", DateToString,
|
||||
"toDateString", DateToDateString,
|
||||
"toTimeString", DateToTimeString,
|
||||
"toLocaleString", DateToLocaleString,
|
||||
"toLocaleDateString", DateToLocaleDateString,
|
||||
"toLocaleTimeString", DateToLocaleTimeString,
|
||||
"setTime", DateSetTime,
|
||||
"setMilliseconds", DateSetMilliseconds,
|
||||
"setUTCMilliseconds", DateSetUTCMilliseconds,
|
||||
"setSeconds", DateSetSeconds,
|
||||
"setUTCSeconds", DateSetUTCSeconds,
|
||||
"setMinutes", DateSetMinutes,
|
||||
"setUTCMinutes", DateSetUTCMinutes,
|
||||
"setHours", DateSetHours,
|
||||
"setUTCHours", DateSetUTCHours,
|
||||
"setDate", DateSetDate,
|
||||
"setUTCDate", DateSetUTCDate,
|
||||
"setMonth", DateSetMonth,
|
||||
"setUTCMonth", DateSetUTCMonth,
|
||||
"setFullYear", DateSetFullYear,
|
||||
"setUTCFullYear", DateSetUTCFullYear,
|
||||
"toGMTString", DateToGMTString,
|
||||
"toUTCString", DateToUTCString,
|
||||
"getYear", DateGetYear,
|
||||
"setYear", DateSetYear,
|
||||
"toJSON", DateToJSON
|
||||
]);
|
||||
|
||||
})
|
@ -11,6 +11,7 @@
|
||||
// -------------------------------------------------------------------
|
||||
// Imports
|
||||
|
||||
var GlobalDate = global.Date;
|
||||
var GlobalJSON = global.JSON;
|
||||
var GlobalSet = global.Set;
|
||||
var InternalArray = utils.InternalArray;
|
||||
@ -246,6 +247,24 @@ utils.InstallFunctions(GlobalJSON, DONT_ENUM, [
|
||||
"stringify", JSONStringify
|
||||
]);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Date.toJSON
|
||||
|
||||
// 20.3.4.37 Date.prototype.toJSON ( key )
|
||||
function DateToJSON(key) {
|
||||
var o = TO_OBJECT(this);
|
||||
var tv = TO_PRIMITIVE_NUMBER(o);
|
||||
if (IS_NUMBER(tv) && !NUMBER_IS_FINITE(tv)) {
|
||||
return null;
|
||||
}
|
||||
return o.toISOString();
|
||||
}
|
||||
|
||||
// Set up non-enumerable functions of the Date prototype object.
|
||||
utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
|
||||
"toJSON", DateToJSON
|
||||
]);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// JSON Builtins
|
||||
|
||||
|
@ -39,32 +39,6 @@ define NEW_TWO_BYTE_STRING = false;
|
||||
define GETTER = 0;
|
||||
define SETTER = 1;
|
||||
|
||||
# For date.js.
|
||||
define HoursPerDay = 24;
|
||||
define MinutesPerHour = 60;
|
||||
define SecondsPerMinute = 60;
|
||||
define msPerSecond = 1000;
|
||||
define msPerMinute = 60000;
|
||||
define msPerHour = 3600000;
|
||||
define msPerDay = 86400000;
|
||||
define msPerMonth = 2592000000;
|
||||
|
||||
# Note: kDayZeroInJulianDay = ToJulianDay(1970, 0, 1).
|
||||
define kInvalidDate = 'Invalid Date';
|
||||
define kDayZeroInJulianDay = 2440588;
|
||||
define kMonthMask = 0x1e0;
|
||||
define kDayMask = 0x01f;
|
||||
define kYearShift = 9;
|
||||
define kMonthShift = 5;
|
||||
|
||||
# Limits for parts of the date, so that we support all the dates that
|
||||
# ECMA 262 - 15.9.1.1 requires us to, but at the same time be sure that
|
||||
# the date (days since 1970) is in SMI range.
|
||||
define kMinYear = -1000000;
|
||||
define kMaxYear = 1000000;
|
||||
define kMinMonth = -10000000;
|
||||
define kMaxMonth = 10000000;
|
||||
|
||||
# Safe maximum number of arguments to push to stack, when multiplied by
|
||||
# pointer size. Used by Function.prototype.apply(), Reflect.apply() and
|
||||
# Reflect.construct().
|
||||
@ -183,44 +157,6 @@ macro REGEXP_SOURCE(regexp) = (%_RegExpSource(regexp));
|
||||
# REGEXP_NUMBER_OF_CAPTURES
|
||||
macro NUMBER_OF_CAPTURES(array) = ((array)[0]);
|
||||
|
||||
# Limit according to ECMA 262 15.9.1.1
|
||||
define MAX_TIME_MS = 8640000000000000;
|
||||
# Limit which is MAX_TIME_MS + msPerMonth.
|
||||
define MAX_TIME_BEFORE_UTC = 8640002592000000;
|
||||
|
||||
# Gets the value of a Date object. If arg is not a Date object
|
||||
# a type error is thrown.
|
||||
macro CHECK_DATE(arg) = if (!%_IsDate(arg)) %_ThrowNotDateError();
|
||||
macro LOCAL_DATE_VALUE(arg) = (%_DateField(arg, 0) + %_DateField(arg, 21));
|
||||
macro UTC_DATE_VALUE(arg) = (%_DateField(arg, 0));
|
||||
|
||||
macro LOCAL_YEAR(arg) = (%_DateField(arg, 1));
|
||||
macro LOCAL_MONTH(arg) = (%_DateField(arg, 2));
|
||||
macro LOCAL_DAY(arg) = (%_DateField(arg, 3));
|
||||
macro LOCAL_WEEKDAY(arg) = (%_DateField(arg, 4));
|
||||
macro LOCAL_HOUR(arg) = (%_DateField(arg, 5));
|
||||
macro LOCAL_MIN(arg) = (%_DateField(arg, 6));
|
||||
macro LOCAL_SEC(arg) = (%_DateField(arg, 7));
|
||||
macro LOCAL_MS(arg) = (%_DateField(arg, 8));
|
||||
macro LOCAL_DAYS(arg) = (%_DateField(arg, 9));
|
||||
macro LOCAL_TIME_IN_DAY(arg) = (%_DateField(arg, 10));
|
||||
|
||||
macro UTC_YEAR(arg) = (%_DateField(arg, 11));
|
||||
macro UTC_MONTH(arg) = (%_DateField(arg, 12));
|
||||
macro UTC_DAY(arg) = (%_DateField(arg, 13));
|
||||
macro UTC_WEEKDAY(arg) = (%_DateField(arg, 14));
|
||||
macro UTC_HOUR(arg) = (%_DateField(arg, 15));
|
||||
macro UTC_MIN(arg) = (%_DateField(arg, 16));
|
||||
macro UTC_SEC(arg) = (%_DateField(arg, 17));
|
||||
macro UTC_MS(arg) = (%_DateField(arg, 18));
|
||||
macro UTC_DAYS(arg) = (%_DateField(arg, 19));
|
||||
macro UTC_TIME_IN_DAY(arg) = (%_DateField(arg, 20));
|
||||
|
||||
macro TIMEZONE_OFFSET(arg) = (%_DateField(arg, 21));
|
||||
|
||||
macro SET_UTC_DATE_VALUE(arg, value) = (%DateSetValue(arg, value, 1));
|
||||
macro SET_LOCAL_DATE_VALUE(arg, value) = (%DateSetValue(arg, value, 0));
|
||||
|
||||
# Last input and last subject of regexp matches.
|
||||
define LAST_SUBJECT_INDEX = 1;
|
||||
macro LAST_SUBJECT(array) = ((array)[1]);
|
||||
|
@ -19333,6 +19333,16 @@ Object* JSDate::GetUTCField(FieldIndex index,
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
Handle<Object> JSDate::SetValue(Handle<JSDate> date, double v) {
|
||||
Isolate* const isolate = date->GetIsolate();
|
||||
Handle<Object> value = isolate->factory()->NewNumber(v);
|
||||
bool value_is_nan = std::isnan(v);
|
||||
date->SetValue(*value, value_is_nan);
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void JSDate::SetValue(Object* value, bool is_value_nan) {
|
||||
set_value(value);
|
||||
if (is_value_nan) {
|
||||
|
@ -7575,6 +7575,8 @@ class JSDate: public JSObject {
|
||||
// See FieldIndex for the list of date fields.
|
||||
static Object* GetField(Object* date, Smi* index);
|
||||
|
||||
static Handle<Object> SetValue(Handle<JSDate> date, double v);
|
||||
|
||||
void SetValue(Object* value, bool is_value_nan);
|
||||
|
||||
// ES6 section 20.3.4.45 Date.prototype [ @@toPrimitive ]
|
||||
|
@ -14,52 +14,6 @@
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_DateMakeDay) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK(args.length() == 2);
|
||||
|
||||
CONVERT_SMI_ARG_CHECKED(year, 0);
|
||||
CONVERT_SMI_ARG_CHECKED(month, 1);
|
||||
|
||||
int days = isolate->date_cache()->DaysFromYearMonth(year, month);
|
||||
RUNTIME_ASSERT(Smi::IsValid(days));
|
||||
return Smi::FromInt(days);
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_DateSetValue) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 3);
|
||||
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSDate, date, 0);
|
||||
CONVERT_DOUBLE_ARG_CHECKED(time, 1);
|
||||
CONVERT_SMI_ARG_CHECKED(is_utc, 2);
|
||||
|
||||
DateCache* date_cache = isolate->date_cache();
|
||||
|
||||
Handle<Object> value;
|
||||
bool is_value_nan = false;
|
||||
if (std::isnan(time)) {
|
||||
value = isolate->factory()->nan_value();
|
||||
is_value_nan = true;
|
||||
} else if (!is_utc && (time < -DateCache::kMaxTimeBeforeUTCInMs ||
|
||||
time > DateCache::kMaxTimeBeforeUTCInMs)) {
|
||||
value = isolate->factory()->nan_value();
|
||||
is_value_nan = true;
|
||||
} else {
|
||||
time = is_utc ? time : date_cache->ToUTC(static_cast<int64_t>(time));
|
||||
if (time < -DateCache::kMaxTimeInMs || time > DateCache::kMaxTimeInMs) {
|
||||
value = isolate->factory()->nan_value();
|
||||
is_value_nan = true;
|
||||
} else {
|
||||
value = isolate->factory()->NewNumber(DoubleToInteger(time));
|
||||
}
|
||||
}
|
||||
date->SetValue(*value, is_value_nan);
|
||||
return *value;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_IsDate) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
@ -70,7 +24,7 @@ RUNTIME_FUNCTION(Runtime_IsDate) {
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 0);
|
||||
DCHECK_EQ(0, args.length());
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(isolate,
|
||||
NewTypeError(MessageTemplate::kNotDateObject));
|
||||
}
|
||||
@ -82,53 +36,5 @@ RUNTIME_FUNCTION(Runtime_DateCurrentTime) {
|
||||
return *isolate->factory()->NewNumber(JSDate::CurrentTimeValue(isolate));
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_DateLocalTimezone) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 1);
|
||||
|
||||
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
|
||||
RUNTIME_ASSERT(x >= -DateCache::kMaxTimeBeforeUTCInMs &&
|
||||
x <= DateCache::kMaxTimeBeforeUTCInMs);
|
||||
const char* zone =
|
||||
isolate->date_cache()->LocalTimezone(static_cast<int64_t>(x));
|
||||
Handle<String> result =
|
||||
isolate->factory()->NewStringFromUtf8(CStrVector(zone)).ToHandleChecked();
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_DateCacheVersion) {
|
||||
HandleScope hs(isolate);
|
||||
DCHECK(args.length() == 0);
|
||||
if (isolate->serializer_enabled()) return isolate->heap()->undefined_value();
|
||||
if (!isolate->eternal_handles()->Exists(EternalHandles::DATE_CACHE_VERSION)) {
|
||||
Handle<FixedArray> date_cache_version =
|
||||
isolate->factory()->NewFixedArray(1, TENURED);
|
||||
date_cache_version->set(0, Smi::FromInt(0));
|
||||
isolate->eternal_handles()->CreateSingleton(
|
||||
isolate, *date_cache_version, EternalHandles::DATE_CACHE_VERSION);
|
||||
}
|
||||
Handle<FixedArray> date_cache_version =
|
||||
Handle<FixedArray>::cast(isolate->eternal_handles()->GetSingleton(
|
||||
EternalHandles::DATE_CACHE_VERSION));
|
||||
// Return result as a JS array.
|
||||
Handle<JSObject> result =
|
||||
isolate->factory()->NewJSObject(isolate->array_function());
|
||||
JSArray::SetContent(Handle<JSArray>::cast(result), date_cache_version);
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_DateField) {
|
||||
SealHandleScope shs(isolate);
|
||||
DCHECK_EQ(2, args.length());
|
||||
CONVERT_ARG_CHECKED(JSDate, date, 0);
|
||||
CONVERT_SMI_ARG_CHECKED(index, 1);
|
||||
DCHECK_LE(0, index);
|
||||
if (index == 0) return date->value();
|
||||
return JSDate::GetField(date, Smi::FromInt(index));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -137,14 +137,9 @@ namespace internal {
|
||||
|
||||
|
||||
#define FOR_EACH_INTRINSIC_DATE(F) \
|
||||
F(DateMakeDay, 2, 1) \
|
||||
F(DateSetValue, 3, 1) \
|
||||
F(IsDate, 1, 1) \
|
||||
F(ThrowNotDateError, 0, 1) \
|
||||
F(DateCurrentTime, 0, 1) \
|
||||
F(DateLocalTimezone, 1, 1) \
|
||||
F(DateCacheVersion, 0, 1) \
|
||||
F(DateField, 2 /* date object, field index */, 1)
|
||||
F(ThrowNotDateError, 0, 1)
|
||||
|
||||
|
||||
#define FOR_EACH_INTRINSIC_DEBUG(F) \
|
||||
|
@ -166,31 +166,3 @@ TEST(DaylightSavingsTime) {
|
||||
CheckDST(august_20 + 2 * 3600 - 1000);
|
||||
CheckDST(august_20);
|
||||
}
|
||||
|
||||
|
||||
TEST(DateCacheVersion) {
|
||||
FLAG_allow_natives_syntax = true;
|
||||
v8::Isolate* isolate = CcTest::isolate();
|
||||
v8::Isolate::Scope isolate_scope(isolate);
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate);
|
||||
v8::Context::Scope context_scope(context);
|
||||
v8::Local<v8::Array> date_cache_version =
|
||||
v8::Local<v8::Array>::Cast(CompileRun("%DateCacheVersion()"));
|
||||
|
||||
CHECK_EQ(1, static_cast<int32_t>(date_cache_version->Length()));
|
||||
CHECK(date_cache_version->Get(context, 0).ToLocalChecked()->IsNumber());
|
||||
CHECK_EQ(0.0, date_cache_version->Get(context, 0)
|
||||
.ToLocalChecked()
|
||||
->NumberValue(context)
|
||||
.FromJust());
|
||||
|
||||
v8::Date::DateTimeConfigurationChangeNotification(isolate);
|
||||
|
||||
CHECK_EQ(1, static_cast<int32_t>(date_cache_version->Length()));
|
||||
CHECK(date_cache_version->Get(context, 0).ToLocalChecked()->IsNumber());
|
||||
CHECK_EQ(1.0, date_cache_version->Get(context, 0)
|
||||
.ToLocalChecked()
|
||||
->NumberValue(context)
|
||||
.FromJust());
|
||||
}
|
||||
|
@ -85,8 +85,8 @@ assertEquals('native math.js', math_script.name);
|
||||
assertEquals(Debug.ScriptType.Native, math_script.type);
|
||||
|
||||
// Test a builtins delay loaded script.
|
||||
var date_delay_script = Debug.findScript('native date.js');
|
||||
assertEquals('native date.js', date_delay_script.name);
|
||||
var date_delay_script = Debug.findScript('native json.js');
|
||||
assertEquals('native json.js', date_delay_script.name);
|
||||
assertEquals(Debug.ScriptType.Native, date_delay_script.type);
|
||||
|
||||
// Test a debugger script.
|
||||
|
@ -109,11 +109,6 @@ test(function() {
|
||||
new DataView(1);
|
||||
}, "First argument to DataView constructor must be an ArrayBuffer", TypeError);
|
||||
|
||||
// kDateType
|
||||
test(function() {
|
||||
Date.prototype.setYear.call({}, 1);
|
||||
}, "this is not a Date object.", TypeError);
|
||||
|
||||
// kDefineDisallowed
|
||||
test(function() {
|
||||
"use strict";
|
||||
@ -189,7 +184,7 @@ test(function() {
|
||||
|
||||
// kNotDateObject
|
||||
test(function() {
|
||||
Date.prototype.setHours.call(1);
|
||||
Date.prototype.getHours.call(1);
|
||||
}, "this is not a Date object.", TypeError);
|
||||
|
||||
// kNotGeneric
|
||||
|
@ -1,34 +0,0 @@
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Flags: --allow-natives-syntax
|
||||
|
||||
var _d = new Date();
|
||||
_d.setHours(0,0,0,0);
|
||||
_d.setHours(0,0,0,0);
|
||||
%OptimizeFunctionOnNextCall(_d.setHours);
|
||||
_d.setHours(0,0,0,0);
|
@ -1899,7 +1899,6 @@
|
||||
'../../src/js/uri.js',
|
||||
'../../src/js/math.js',
|
||||
'../../src/third_party/fdlibm/fdlibm.js',
|
||||
'../../src/js/date.js',
|
||||
'../../src/js/regexp.js',
|
||||
'../../src/js/arraybuffer.js',
|
||||
'../../src/js/typedarray.js',
|
||||
|
Loading…
Reference in New Issue
Block a user