Commit fc5c7e04 authored by bmeurer's avatar bmeurer Committed by Commit bot

[date] Migrate Date field accessors to native builtins.

There's no reason to have JavaScript wrappers for those accessors,
since the meat is already in hand-written native code (via %_DateField).
First step now to put them into native builtins. Next step will be to
completely remove %_DateField.

R=yangguo@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#33172}
parent 3c716641
......@@ -1383,6 +1383,53 @@ void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
}
// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
// -- lr : return address
// -- sp[0] : receiver
// -----------------------------------
// 1. Pop receiver into r0 and check that it's actually a JSDate object.
Label receiver_not_date;
{
__ Pop(r0);
__ JumpIfSmi(r0, &receiver_not_date);
__ CompareObjectType(r0, r1, r2, JS_DATE_TYPE);
__ b(ne, &receiver_not_date);
}
// 2. Load the specified date field, falling back to the runtime as necessary.
if (field_index == JSDate::kDateValue) {
__ ldr(r0, FieldMemOperand(r0, JSDate::kValueOffset));
} else {
if (field_index < JSDate::kFirstUncachedField) {
Label stamp_mismatch;
__ mov(r1, Operand(ExternalReference::date_cache_stamp(masm->isolate())));
__ ldr(r1, MemOperand(r1));
__ ldr(ip, FieldMemOperand(r0, JSDate::kCacheStampOffset));
__ cmp(r1, ip);
__ b(ne, &stamp_mismatch);
__ ldr(r0, FieldMemOperand(
r0, JSDate::kValueOffset + field_index * kPointerSize));
__ Ret();
__ bind(&stamp_mismatch);
}
FrameScope scope(masm, StackFrame::INTERNAL);
__ PrepareCallCFunction(2, r1);
__ mov(r1, Operand(Smi::FromInt(field_index)));
__ CallCFunction(
ExternalReference::get_date_field_function(masm->isolate()), 2);
}
__ Ret();
// 3. Raise a TypeError if the receiver is not a date.
__ bind(&receiver_not_date);
__ TailCallRuntime(Runtime::kThrowNotDateError);
}
// static
void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
// ----------- S t a t e -------------
......
......@@ -1354,6 +1354,52 @@ void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
}
// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
// -- lr : return address
// -- jssp[0] : receiver
// -----------------------------------
ASM_LOCATION("Builtins::Generate_DatePrototype_GetField");
// 1. Pop receiver into x0 and check that it's actually a JSDate object.
Label receiver_not_date;
{
__ Pop(x0);
__ JumpIfSmi(x0, &receiver_not_date);
__ JumpIfNotObjectType(x0, x1, x2, JS_DATE_TYPE, &receiver_not_date);
}
// 2. Load the specified date field, falling back to the runtime as necessary.
if (field_index == JSDate::kDateValue) {
__ Ldr(x0, FieldMemOperand(x0, JSDate::kValueOffset));
} else {
if (field_index < JSDate::kFirstUncachedField) {
Label stamp_mismatch;
__ Mov(x1, ExternalReference::date_cache_stamp(masm->isolate()));
__ Ldr(x1, MemOperand(x1));
__ Ldr(x2, FieldMemOperand(x0, JSDate::kCacheStampOffset));
__ Cmp(x1, x2);
__ B(ne, &stamp_mismatch);
__ Ldr(x0, FieldMemOperand(
x0, JSDate::kValueOffset + field_index * kPointerSize));
__ Ret();
__ Bind(&stamp_mismatch);
}
FrameScope scope(masm, StackFrame::INTERNAL);
__ Mov(x1, Smi::FromInt(field_index));
__ CallCFunction(
ExternalReference::get_date_field_function(masm->isolate()), 2);
}
__ Ret();
// 3. Raise a TypeError if the receiver is not a date.
__ Bind(&receiver_not_date);
__ TailCallRuntime(Runtime::kThrowNotDateError);
}
// static
void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
// ----------- S t a t e -------------
......
......@@ -2552,6 +2552,42 @@ bool Genesis::InstallNatives(ContextType context_type) {
// 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);
......
......@@ -2370,6 +2370,114 @@ BUILTIN(DatePrototypeToPrimitive) {
}
// static
void Builtins::Generate_DatePrototypeGetDate(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kDay);
}
// static
void Builtins::Generate_DatePrototypeGetDay(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kWeekday);
}
// static
void Builtins::Generate_DatePrototypeGetFullYear(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kYear);
}
// static
void Builtins::Generate_DatePrototypeGetHours(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kHour);
}
// static
void Builtins::Generate_DatePrototypeGetMilliseconds(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kMillisecond);
}
// static
void Builtins::Generate_DatePrototypeGetMinutes(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kMinute);
}
// static
void Builtins::Generate_DatePrototypeGetMonth(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kMonth);
}
// static
void Builtins::Generate_DatePrototypeGetSeconds(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kSecond);
}
// static
void Builtins::Generate_DatePrototypeGetTime(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kDateValue);
}
// static
void Builtins::Generate_DatePrototypeGetTimezoneOffset(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kTimezoneOffset);
}
// static
void Builtins::Generate_DatePrototypeGetUTCDate(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kDayUTC);
}
// static
void Builtins::Generate_DatePrototypeGetUTCDay(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kWeekdayUTC);
}
// static
void Builtins::Generate_DatePrototypeGetUTCFullYear(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kYearUTC);
}
// static
void Builtins::Generate_DatePrototypeGetUTCHours(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kHourUTC);
}
// static
void Builtins::Generate_DatePrototypeGetUTCMilliseconds(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kMillisecondUTC);
}
// static
void Builtins::Generate_DatePrototypeGetUTCMinutes(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kMinuteUTC);
}
// static
void Builtins::Generate_DatePrototypeGetUTCMonth(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kMonthUTC);
}
// static
void Builtins::Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm) {
Generate_DatePrototype_GetField(masm, JSDate::kSecondUTC);
}
namespace {
// ES6 section 19.2.1.1.1 CreateDynamicFunction
......
......@@ -197,8 +197,28 @@ inline bool operator&(BuiltinExtraArguments lhs, BuiltinExtraArguments rhs) {
V(KeyedStoreIC_Megamorphic_Strict, KEYED_STORE_IC, MEGAMORPHIC, \
StoreICState::kStrictModeState) \
\
V(DatePrototypeGetDate, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetDay, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetFullYear, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetHours, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetMilliseconds, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetMinutes, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetMonth, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetSeconds, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetTime, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetTimezoneOffset, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCDate, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCDay, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCFullYear, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCHours, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCMilliseconds, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCMinutes, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCMonth, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(DatePrototypeGetUTCSeconds, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\
V(FunctionPrototypeApply, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(FunctionPrototypeCall, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\
V(ReflectApply, BUILTIN, UNINITIALIZED, kNoExtraICState) \
V(ReflectConstruct, BUILTIN, UNINITIALIZED, kNoExtraICState) \
\
......@@ -390,8 +410,48 @@ class Builtins {
static void Generate_HandleFastApiCall(MacroAssembler* masm);
static void Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index);
// ES6 section 20.3.4.2 Date.prototype.getDate ( )
static void Generate_DatePrototypeGetDate(MacroAssembler* masm);
// ES6 section 20.3.4.3 Date.prototype.getDay ( )
static void Generate_DatePrototypeGetDay(MacroAssembler* masm);
// ES6 section 20.3.4.4 Date.prototype.getFullYear ( )
static void Generate_DatePrototypeGetFullYear(MacroAssembler* masm);
// ES6 section 20.3.4.5 Date.prototype.getHours ( )
static void Generate_DatePrototypeGetHours(MacroAssembler* masm);
// ES6 section 20.3.4.6 Date.prototype.getMilliseconds ( )
static void Generate_DatePrototypeGetMilliseconds(MacroAssembler* masm);
// ES6 section 20.3.4.7 Date.prototype.getMinutes ( )
static void Generate_DatePrototypeGetMinutes(MacroAssembler* masm);
// ES6 section 20.3.4.8 Date.prototype.getMonth ( )
static void Generate_DatePrototypeGetMonth(MacroAssembler* masm);
// ES6 section 20.3.4.9 Date.prototype.getSeconds ( )
static void Generate_DatePrototypeGetSeconds(MacroAssembler* masm);
// ES6 section 20.3.4.10 Date.prototype.getTime ( )
static void Generate_DatePrototypeGetTime(MacroAssembler* masm);
// ES6 section 20.3.4.11 Date.prototype.getTimezoneOffset ( )
static void Generate_DatePrototypeGetTimezoneOffset(MacroAssembler* masm);
// ES6 section 20.3.4.12 Date.prototype.getUTCDate ( )
static void Generate_DatePrototypeGetUTCDate(MacroAssembler* masm);
// ES6 section 20.3.4.13 Date.prototype.getUTCDay ( )
static void Generate_DatePrototypeGetUTCDay(MacroAssembler* masm);
// ES6 section 20.3.4.14 Date.prototype.getUTCFullYear ( )
static void Generate_DatePrototypeGetUTCFullYear(MacroAssembler* masm);
// ES6 section 20.3.4.15 Date.prototype.getUTCHours ( )
static void Generate_DatePrototypeGetUTCHours(MacroAssembler* masm);
// ES6 section 20.3.4.16 Date.prototype.getUTCMilliseconds ( )
static void Generate_DatePrototypeGetUTCMilliseconds(MacroAssembler* masm);
// ES6 section 20.3.4.17 Date.prototype.getUTCMinutes ( )
static void Generate_DatePrototypeGetUTCMinutes(MacroAssembler* masm);
// ES6 section 20.3.4.18 Date.prototype.getUTCMonth ( )
static void Generate_DatePrototypeGetUTCMonth(MacroAssembler* masm);
// ES6 section 20.3.4.19 Date.prototype.getUTCSeconds ( )
static void Generate_DatePrototypeGetUTCSeconds(MacroAssembler* masm);
static void Generate_FunctionPrototypeApply(MacroAssembler* masm);
static void Generate_FunctionPrototypeCall(MacroAssembler* masm);
static void Generate_ReflectApply(MacroAssembler* masm);
static void Generate_ReflectConstruct(MacroAssembler* masm);
......
......@@ -3321,9 +3321,7 @@ void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
} else {
Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
Operand stamp_operand = __ ExternalOperand(stamp);
__ movp(scratch, stamp_operand);
__ 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 +
......
......@@ -1000,6 +1000,58 @@ void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
}
// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
// -- esp[0] : return address
// -- esp[4] : receiver
// -----------------------------------
// 1. Load receiver into eax and check that it's actually a JSDate object.
Label receiver_not_date;
{
__ mov(eax, Operand(esp, kPointerSize));
__ JumpIfSmi(eax, &receiver_not_date);
__ CmpObjectType(eax, JS_DATE_TYPE, ebx);
__ j(not_equal, &receiver_not_date);
}
// 2. Load the specified date field, falling back to the runtime as necessary.
if (field_index == JSDate::kDateValue) {
__ mov(eax, FieldOperand(eax, JSDate::kValueOffset));
} else {
if (field_index < JSDate::kFirstUncachedField) {
Label stamp_mismatch;
__ mov(edx, Operand::StaticVariable(
ExternalReference::date_cache_stamp(masm->isolate())));
__ cmp(edx, FieldOperand(eax, JSDate::kCacheStampOffset));
__ j(not_equal, &stamp_mismatch, Label::kNear);
__ mov(eax, FieldOperand(
eax, JSDate::kValueOffset + field_index * kPointerSize));
__ ret(1 * kPointerSize);
__ bind(&stamp_mismatch);
}
FrameScope scope(masm, StackFrame::INTERNAL);
__ PrepareCallCFunction(2, ebx);
__ mov(Operand(esp, 0), eax);
__ mov(Operand(esp, 1 * kPointerSize),
Immediate(Smi::FromInt(field_index)));
__ CallCFunction(
ExternalReference::get_date_field_function(masm->isolate()), 2);
}
__ ret(1 * kPointerSize);
// 3. Raise a TypeError if the receiver is not a date.
__ bind(&receiver_not_date);
{
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterFrame(StackFrame::INTERNAL);
__ CallRuntime(Runtime::kThrowNotDateError);
}
}
// static
void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
// ----------- S t a t e -------------
......
......@@ -232,132 +232,6 @@ function DateToLocaleTimeString() {
}
// ECMA 262 - 15.9.5.9
function DateGetTime() {
CHECK_DATE(this);
return UTC_DATE_VALUE(this);
}
// ECMA 262 - 15.9.5.10
function DateGetFullYear() {
CHECK_DATE(this);
return LOCAL_YEAR(this);
}
// ECMA 262 - 15.9.5.11
function DateGetUTCFullYear() {
CHECK_DATE(this);
return UTC_YEAR(this);
}
// ECMA 262 - 15.9.5.12
function DateGetMonth() {
CHECK_DATE(this);
return LOCAL_MONTH(this);
}
// ECMA 262 - 15.9.5.13
function DateGetUTCMonth() {
CHECK_DATE(this);
return UTC_MONTH(this);
}
// ECMA 262 - 15.9.5.14
function DateGetDate() {
CHECK_DATE(this);
return LOCAL_DAY(this);
}
// ECMA 262 - 15.9.5.15
function DateGetUTCDate() {
CHECK_DATE(this);
return UTC_DAY(this);
}
// ECMA 262 - 15.9.5.16
function DateGetDay() {
CHECK_DATE(this);
return LOCAL_WEEKDAY(this);
}
// ECMA 262 - 15.9.5.17
function DateGetUTCDay() {
CHECK_DATE(this);
return UTC_WEEKDAY(this);
}
// ECMA 262 - 15.9.5.18
function DateGetHours() {
CHECK_DATE(this);
return LOCAL_HOUR(this);
}
// ECMA 262 - 15.9.5.19
function DateGetUTCHours() {
CHECK_DATE(this);
return UTC_HOUR(this);
}
// ECMA 262 - 15.9.5.20
function DateGetMinutes() {
CHECK_DATE(this);
return LOCAL_MIN(this);
}
// ECMA 262 - 15.9.5.21
function DateGetUTCMinutes() {
CHECK_DATE(this);
return UTC_MIN(this);
}
// ECMA 262 - 15.9.5.22
function DateGetSeconds() {
CHECK_DATE(this);
return LOCAL_SEC(this);
}
// ECMA 262 - 15.9.5.23
function DateGetUTCSeconds() {
CHECK_DATE(this);
return UTC_SEC(this)
}
// ECMA 262 - 15.9.5.24
function DateGetMilliseconds() {
CHECK_DATE(this);
return LOCAL_MS(this);
}
// ECMA 262 - 15.9.5.25
function DateGetUTCMilliseconds() {
CHECK_DATE(this);
return UTC_MS(this);
}
// ECMA 262 - 15.9.5.26
function DateGetTimezoneOffset() {
CHECK_DATE(this);
return TIMEZONE_OFFSET(this);
}
// ECMA 262 - 15.9.5.27
function DateSetTime(ms) {
CHECK_DATE(this);
......@@ -648,24 +522,6 @@ utils.InstallFunctions(GlobalDate.prototype, DONT_ENUM, [
"toLocaleString", DateToLocaleString,
"toLocaleDateString", DateToLocaleDateString,
"toLocaleTimeString", DateToLocaleTimeString,
"getTime", DateGetTime,
"getFullYear", DateGetFullYear,
"getUTCFullYear", DateGetUTCFullYear,
"getMonth", DateGetMonth,
"getUTCMonth", DateGetUTCMonth,
"getDate", DateGetDate,
"getUTCDate", DateGetUTCDate,
"getDay", DateGetDay,
"getUTCDay", DateGetUTCDay,
"getHours", DateGetHours,
"getUTCHours", DateGetUTCHours,
"getMinutes", DateGetMinutes,
"getUTCMinutes", DateGetUTCMinutes,
"getSeconds", DateGetSeconds,
"getUTCSeconds", DateGetUTCSeconds,
"getMilliseconds", DateGetMilliseconds,
"getUTCMilliseconds", DateGetUTCMilliseconds,
"getTimezoneOffset", DateGetTimezoneOffset,
"setTime", DateSetTime,
"setMilliseconds", DateSetMilliseconds,
"setUTCMilliseconds", DateSetUTCMilliseconds,
......
......@@ -1385,6 +1385,53 @@ void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
}
// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
// -- sp[0] : receiver
// -----------------------------------
// 1. Pop receiver into a0 and check that it's actually a JSDate object.
Label receiver_not_date;
{
__ Pop(a0);
__ JumpIfSmi(a0, &receiver_not_date);
__ GetObjectType(a0, t0, t0);
__ Branch(&receiver_not_date, ne, t0, Operand(JS_DATE_TYPE));
}
// 2. Load the specified date field, falling back to the runtime as necessary.
if (field_index == JSDate::kDateValue) {
__ Ret(USE_DELAY_SLOT);
__ lw(v0, FieldMemOperand(a0, JSDate::kValueOffset)); // In delay slot.
} else {
if (field_index < JSDate::kFirstUncachedField) {
Label stamp_mismatch;
__ li(a1, Operand(ExternalReference::date_cache_stamp(masm->isolate())));
__ lw(a1, MemOperand(a1));
__ lw(t0, FieldMemOperand(a0, JSDate::kCacheStampOffset));
__ Branch(&stamp_mismatch, ne, t0, Operand(a1));
__ Ret(USE_DELAY_SLOT);
__ lw(v0, FieldMemOperand(
a0, JSDate::kValueOffset +
field_index * kPointerSize)); // In delay slot.
__ bind(&stamp_mismatch);
}
FrameScope scope(masm, StackFrame::INTERNAL);
__ PrepareCallCFunction(2, t0);
__ li(a1, Operand(Smi::FromInt(field_index)));
__ CallCFunction(
ExternalReference::get_date_field_function(masm->isolate()), 2);
__ Ret();
}
// 3. Raise a TypeError if the receiver is not a date.
__ bind(&receiver_not_date);
__ TailCallRuntime(Runtime::kThrowNotDateError);
}
// static
void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
// ----------- S t a t e -------------
......
......@@ -1376,6 +1376,53 @@ void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
}
// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
// -- sp[0] : receiver
// -----------------------------------
// 1. Pop receiver into a0 and check that it's actually a JSDate object.
Label receiver_not_date;
{
__ Pop(a0);
__ JumpIfSmi(a0, &receiver_not_date);
__ GetObjectType(a0, t0, t0);
__ Branch(&receiver_not_date, ne, t0, Operand(JS_DATE_TYPE));
}
// 2. Load the specified date field, falling back to the runtime as necessary.
if (field_index == JSDate::kDateValue) {
__ Ret(USE_DELAY_SLOT);
__ ld(v0, FieldMemOperand(a0, JSDate::kValueOffset)); // In delay slot.
} else {
if (field_index < JSDate::kFirstUncachedField) {
Label stamp_mismatch;
__ li(a1, Operand(ExternalReference::date_cache_stamp(masm->isolate())));
__ ld(a1, MemOperand(a1));
__ ld(t0, FieldMemOperand(a0, JSDate::kCacheStampOffset));
__ Branch(&stamp_mismatch, ne, t0, Operand(a1));
__ Ret(USE_DELAY_SLOT);
__ ld(v0, FieldMemOperand(
a0, JSDate::kValueOffset +
field_index * kPointerSize)); // In delay slot.
__ bind(&stamp_mismatch);
}
FrameScope scope(masm, StackFrame::INTERNAL);
__ PrepareCallCFunction(2, t0);
__ li(a1, Operand(Smi::FromInt(field_index)));
__ CallCFunction(
ExternalReference::get_date_field_function(masm->isolate()), 2);
__ Ret();
}
// 3. Raise a TypeError if the receiver is not a date.
__ bind(&receiver_not_date);
__ TailCallRuntime(Runtime::kThrowNotDateError);
}
// static
void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
// ----------- S t a t e -------------
......
......@@ -1052,6 +1052,58 @@ void Builtins::Generate_NotifyLazyDeoptimized(MacroAssembler* masm) {
}
// static
void Builtins::Generate_DatePrototype_GetField(MacroAssembler* masm,
int field_index) {
// ----------- S t a t e -------------
// -- rsp[0] : return address
// -- rsp[8] : receiver
// -----------------------------------
// 1. Load receiver into rax and check that it's actually a JSDate object.
Label receiver_not_date;
{
StackArgumentsAccessor args(rsp, 0);
__ movp(rax, args.GetReceiverOperand());
__ JumpIfSmi(rax, &receiver_not_date);
__ CmpObjectType(rax, JS_DATE_TYPE, rbx);
__ j(not_equal, &receiver_not_date);
}
// 2. Load the specified date field, falling back to the runtime as necessary.
if (field_index == JSDate::kDateValue) {
__ movp(rax, FieldOperand(rax, JSDate::kValueOffset));
} else {
if (field_index < JSDate::kFirstUncachedField) {
Label stamp_mismatch;
__ Load(rdx, ExternalReference::date_cache_stamp(masm->isolate()));
__ cmpp(rdx, FieldOperand(rax, JSDate::kCacheStampOffset));
__ j(not_equal, &stamp_mismatch, Label::kNear);
__ movp(rax, FieldOperand(
rax, JSDate::kValueOffset + field_index * kPointerSize));
__ ret(1 * kPointerSize);
__ bind(&stamp_mismatch);
}
FrameScope scope(masm, StackFrame::INTERNAL);
__ PrepareCallCFunction(2);
__ Move(arg_reg_1, rax);
__ Move(arg_reg_2, Smi::FromInt(field_index));
__ CallCFunction(
ExternalReference::get_date_field_function(masm->isolate()), 2);
}
__ ret(1 * kPointerSize);
// 3. Raise a TypeError if the receiver is not a date.
__ bind(&receiver_not_date);
{
FrameScope scope(masm, StackFrame::MANUAL);
__ EnterFrame(StackFrame::INTERNAL);
__ CallRuntime(Runtime::kThrowNotDateError);
}
}
// static
void Builtins::Generate_FunctionPrototypeApply(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- rax : argc
......
......@@ -328,18 +328,11 @@ assertThrows('Date.prototype.setHours.call("", 1, 2, 3, 4);', TypeError);
assertThrows('Date.prototype.getDate.call("");', TypeError);
assertThrows('Date.prototype.getUTCDate.call("");', TypeError);
var date = new Date();
date.getTime();
date.getTime();
%OptimizeFunctionOnNextCall(Date.prototype.getTime);
assertThrows(function() { Date.prototype.getTime.call(""); }, TypeError);
assertUnoptimized(Date.prototype.getTime);
date.getYear();
date.getYear();
%OptimizeFunctionOnNextCall(Date.prototype.getYear);
assertThrows(function() { Date.prototype.getYear.call(""); }, TypeError);
assertUnoptimized(Date.prototype.getYear);
assertThrows(function() { Date.prototype.getTime.call(0) }, TypeError);
assertThrows(function() { Date.prototype.getTime.call("") }, TypeError);
assertThrows(function() { Date.prototype.getYear.call(0) }, TypeError);
assertThrows(function() { Date.prototype.getYear.call("") }, TypeError);
(function TestDatePrototypeOrdinaryObject() {
assertEquals(Object.prototype, Date.prototype.__proto__);
......@@ -353,7 +346,7 @@ delete Date.prototype.getUTCHours;
delete Date.prototype.getUTCMinutes;
delete Date.prototype.getUTCSeconds;
delete Date.prototype.getUTCMilliseconds;
date.toISOString();
(new Date()).toISOString();
(function TestDeleteToString() {
assertTrue(delete Date.prototype.toString);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment