}
+void FullCodeGenerator::EmitThrowIfNotADate(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ VisitForAccumulatorValue(args->at(0)); // Load the object.
+
+ Label done, not_date_object;
+ Register object = r0;
+ Register result = r0;
+ Register scratch0 = r9;
+
+ __ JumpIfSmi(object, ¬_date_object);
+ __ CompareObjectType(object, scratch0, scratch0, JS_DATE_TYPE);
+ __ b(eq, &done);
+ __ bind(¬_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+
+ __ bind(&done);
+ context()->Plug(result);
+}
+
+
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2);
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done, not_date_object;
Register object = r0;
Register result = r0;
Register scratch0 = r9;
Register scratch1 = r1;
- __ JumpIfSmi(object, ¬_date_object);
- __ CompareObjectType(object, scratch1, scratch1, JS_DATE_TYPE);
- __ b(ne, ¬_date_object);
-
if (index->value() == 0) {
__ ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
- __ jmp(&done);
} else {
+ Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
__ mov(scratch1, Operand(stamp));
__ PrepareCallCFunction(2, scratch1);
__ mov(r1, Operand(index));
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
- __ jmp(&done);
+ __ bind(&done);
}
- __ bind(¬_date_object);
- __ CallRuntime(Runtime::kThrowNotDateError, 0);
- __ bind(&done);
- context()->Plug(r0);
+ context()->Plug(result);
}
LOperand* object = UseFixed(instr->value(), r0);
LDateField* result =
new(zone()) LDateField(object, FixedTemp(r1), instr->index());
- return MarkAsCall(DefineFixed(result, r0), instr, CAN_DEOPTIMIZE_EAGERLY);
+ return MarkAsCall(DefineFixed(result, r0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}
Register result = ToRegister(instr->result());
Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
- Label runtime, done;
DCHECK(object.is(result));
DCHECK(object.is(r0));
DCHECK(!scratch.is(scratch0()));
DCHECK(!scratch.is(object));
- __ SmiTst(object);
- DeoptimizeIf(eq, instr, Deoptimizer::kSmi);
- __ CompareObjectType(object, scratch, scratch, JS_DATE_TYPE);
- DeoptimizeIf(ne, instr, Deoptimizer::kNotADateObject);
-
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));
}
+void FullCodeGenerator::EmitThrowIfNotADate(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ VisitForAccumulatorValue(args->at(0)); // Load the object.
+
+ Label done, not_date_object;
+ Register object = x0;
+ Register result = x0;
+
+ __ JumpIfSmi(object, ¬_date_object);
+ __ JumpIfObjectType(object, x10, x10, JS_DATE_TYPE, &done);
+ __ Bind(¬_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+
+ __ Bind(&done);
+ context()->Plug(result);
+}
+
+
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2);
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done, not_date_object;
Register object = x0;
Register result = x0;
Register stamp_addr = x10;
Register stamp_cache = x11;
- __ JumpIfSmi(object, ¬_date_object);
- __ JumpIfNotObjectType(object, x10, x10, JS_DATE_TYPE, ¬_date_object);
-
if (index->value() == 0) {
__ Ldr(result, FieldMemOperand(object, JSDate::kValueOffset));
- __ B(&done);
} else {
+ Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
- __ Mov(x10, stamp);
- __ Ldr(stamp_addr, MemOperand(x10));
+ __ 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);
__ Bind(&runtime);
__ Mov(x1, index);
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
- __ B(&done);
+ __ Bind(&done);
}
- __ Bind(¬_date_object);
- __ CallRuntime(Runtime::kThrowNotDateError, 0);
- __ Bind(&done);
- context()->Plug(x0);
+ context()->Plug(result);
}
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, CAN_DEOPTIMIZE_EAGERLY);
+ return MarkAsCall(DefineFixed(result, x0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}
Register temp1 = x10;
Register temp2 = x11;
Smi* index = instr->index();
- Label runtime, done;
DCHECK(object.is(result) && object.Is(x0));
DCHECK(instr->IsMarkedAsCall());
- DeoptimizeIfSmi(object, instr, Deoptimizer::kSmi);
- __ CompareObjectType(object, temp1, temp1, JS_DATE_TYPE);
- DeoptimizeIf(ne, instr, Deoptimizer::kNotADateObject);
-
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));
__ Bind(&runtime);
__ Mov(x1, Operand(index));
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
+ __ Bind(&done);
}
-
- __ Bind(&done);
}
V(kOperandIsASmiAndNotAName, "Operand is a smi and not a name") \
V(kOperandIsASmiAndNotAString, "Operand is a smi and not a string") \
V(kOperandIsASmi, "Operand is a smi") \
+ V(kOperandIsNotADate, "Operand is not a date") \
V(kOperandIsNotAName, "Operand is not a name") \
V(kOperandIsNotANumber, "Operand is not a number") \
V(kOperandIsNotASmi, "Operand is not a smi") \
return false;
case Runtime::kInlineArguments:
case Runtime::kInlineCallFunction:
- case Runtime::kInlineDateField:
+ case Runtime::kInlineDateField: // TODO(bmeurer): Remove this.
case Runtime::kInlineDeoptimizeNow:
case Runtime::kInlineGetPrototype:
case Runtime::kInlineRegExpExec:
+ case Runtime::kInlineThrowIfNotADate:
return true;
default:
break;
function DateString(date) {
+ CHECK_DATE(date);
return WeekDays[LOCAL_WEEKDAY(date)] + ' '
+ Months[LOCAL_MONTH(date)] + ' '
+ TwoDigitString(LOCAL_DAY(date)) + ' '
function LongDateString(date) {
+ CHECK_DATE(date);
return LongWeekDays[LOCAL_WEEKDAY(date)] + ', '
+ LongMonths[LOCAL_MONTH(date)] + ' '
+ TwoDigitString(LOCAL_DAY(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);
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)
// 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);
// ECMA 262 - 15.9.5.5
function DateToLocaleString() {
+ CHECK_DATE(this);
return %_CallFunction(this, DateToString);
}
// 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.8
function DateValueOf() {
+ CHECK_DATE(this);
return UTC_DATE_VALUE(this);
}
// 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.28
function DateSetMilliseconds(ms) {
+ CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
ms = $toNumber(ms);
var time = MakeTime(LOCAL_HOUR(this), LOCAL_MIN(this), LOCAL_SEC(this), ms);
// ECMA 262 - 15.9.5.29
function DateSetUTCMilliseconds(ms) {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
ms = $toNumber(ms);
var time = MakeTime(UTC_HOUR(this),
// ECMA 262 - 15.9.5.30
function DateSetSeconds(sec, ms) {
+ CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
sec = $toNumber(sec);
ms = %_ArgumentsLength() < 2 ? LOCAL_MS(this) : $toNumber(ms);
// ECMA 262 - 15.9.5.31
function DateSetUTCSeconds(sec, ms) {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
sec = $toNumber(sec);
ms = %_ArgumentsLength() < 2 ? UTC_MS(this) : $toNumber(ms);
// ECMA 262 - 15.9.5.33
function DateSetMinutes(min, sec, ms) {
+ CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
min = $toNumber(min);
var argc = %_ArgumentsLength();
// ECMA 262 - 15.9.5.34
function DateSetUTCMinutes(min, sec, ms) {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
min = $toNumber(min);
var argc = %_ArgumentsLength();
// ECMA 262 - 15.9.5.35
function DateSetHours(hour, min, sec, ms) {
+ CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
hour = $toNumber(hour);
var argc = %_ArgumentsLength();
// ECMA 262 - 15.9.5.34
function DateSetUTCHours(hour, min, sec, ms) {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
hour = $toNumber(hour);
var argc = %_ArgumentsLength();
// ECMA 262 - 15.9.5.36
function DateSetDate(date) {
+ CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
date = $toNumber(date);
var day = MakeDay(LOCAL_YEAR(this), LOCAL_MONTH(this), date);
// ECMA 262 - 15.9.5.37
function DateSetUTCDate(date) {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
date = $toNumber(date);
var day = MakeDay(UTC_YEAR(this), UTC_MONTH(this), date);
// ECMA 262 - 15.9.5.38
function DateSetMonth(month, date) {
+ CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
month = $toNumber(month);
date = %_ArgumentsLength() < 2 ? LOCAL_DAY(this) : $toNumber(date);
// ECMA 262 - 15.9.5.39
function DateSetUTCMonth(month, date) {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
month = $toNumber(month);
date = %_ArgumentsLength() < 2 ? UTC_DAY(this) : $toNumber(date);
// ECMA 262 - 15.9.5.40
function DateSetFullYear(year, month, date) {
+ CHECK_DATE(this);
var t = LOCAL_DATE_VALUE(this);
year = $toNumber(year);
var argc = %_ArgumentsLength();
// ECMA 262 - 15.9.5.41
function DateSetUTCFullYear(year, month, date) {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
year = $toNumber(year);
var argc = %_ArgumentsLength();
// 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
// ECMA 262 - B.2.4
function DateGetYear() {
+ CHECK_DATE(this);
return LOCAL_YEAR(this) - 1900;
}
// ECMA 262 - 15.9.5.43
function DateToISOString() {
+ CHECK_DATE(this);
var t = UTC_DATE_VALUE(this);
if (NUMBER_IS_NAN(t)) throw MakeRangeError(kInvalidTimeValue);
var year = this.getUTCFullYear();
V(kNoCache, "no cache") \
V(kNonStrictElementsInKeyedLoadGenericStub, \
"non-strict elements in KeyedLoadGenericStub") \
- V(kNotADateObject, "not a date object") \
V(kNotAHeapNumber, "not a heap number") \
V(kNotAHeapNumberUndefinedBoolean, "not a heap number/undefined/true/false") \
V(kNotAHeapNumberUndefined, "not a heap number/undefined") \
F(Arguments) \
F(ValueOf) \
F(SetValueOf) \
+ F(ThrowIfNotADate) \
F(DateField) \
F(StringCharFromCode) \
F(StringCharAt) \
case IS_JS_ARRAY:
*first = *last = JS_ARRAY_TYPE;
return;
+ case IS_JS_DATE:
+ *first = *last = JS_DATE_TYPE;
+ return;
default:
UNREACHABLE();
}
switch (check_) {
case IS_SPEC_OBJECT: return "object";
case IS_JS_ARRAY: return "array";
+ case IS_JS_DATE:
+ return "date";
case IS_STRING: return "string";
case IS_INTERNALIZED_STRING: return "internalized_string";
}
enum Check {
IS_SPEC_OBJECT,
IS_JS_ARRAY,
+ IS_JS_DATE,
IS_STRING,
IS_INTERNALIZED_STRING,
- LAST_INTERVAL_CHECK = IS_JS_ARRAY
+ LAST_INTERVAL_CHECK = IS_JS_DATE
};
DECLARE_INSTRUCTION_FACTORY_P2(HCheckInstanceType, HValue*, Check);
switch (check_) {
case IS_SPEC_OBJECT: return HType::JSObject();
case IS_JS_ARRAY: return HType::JSArray();
+ case IS_JS_DATE:
+ return HType::JSObject();
case IS_STRING: return HType::String();
case IS_INTERNALIZED_STRING: return HType::String();
}
}
+void HOptimizedGraphBuilder::GenerateThrowIfNotADate(CallRuntime* call) {
+ DCHECK_EQ(1, call->arguments()->length());
+ CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
+ HValue* obj = Pop();
+ BuildCheckHeapObject(obj);
+ HCheckInstanceType* check =
+ New<HCheckInstanceType>(obj, HCheckInstanceType::IS_JS_DATE);
+ return ast_context()->ReturnInstruction(check, call->id());
+}
+
+
void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) {
DCHECK(call->arguments()->length() == 2);
DCHECK_NOT_NULL(call->arguments()->at(1)->AsLiteral());
F(Arguments) \
F(ValueOf) \
F(SetValueOf) \
+ F(ThrowIfNotADate) \
F(DateField) \
F(StringCharFromCode) \
F(StringCharAt) \
}
+void FullCodeGenerator::EmitThrowIfNotADate(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ VisitForAccumulatorValue(args->at(0)); // Load the object.
+
+ Label done, not_date_object;
+ Register object = eax;
+ Register result = eax;
+ Register scratch = ecx;
+
+ __ JumpIfSmi(object, ¬_date_object, Label::kNear);
+ __ CmpObjectType(object, JS_DATE_TYPE, scratch);
+ __ j(equal, &done, Label::kNear);
+ __ bind(¬_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+
+ __ bind(&done);
+ context()->Plug(result);
+}
+
+
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2);
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done, not_date_object;
Register object = eax;
Register result = eax;
Register scratch = ecx;
- __ JumpIfSmi(object, ¬_date_object);
- __ CmpObjectType(object, JS_DATE_TYPE, scratch);
- __ j(not_equal, ¬_date_object);
-
if (index->value() == 0) {
__ mov(result, FieldOperand(object, JSDate::kValueOffset));
- __ jmp(&done);
} else {
+ Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
__ mov(scratch, Operand::StaticVariable(stamp));
__ j(not_equal, &runtime, Label::kNear);
__ mov(result, FieldOperand(object, JSDate::kValueOffset +
kPointerSize * index->value()));
- __ jmp(&done);
+ __ 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);
- __ jmp(&done);
+ __ bind(&done);
}
- __ bind(¬_date_object);
- __ CallRuntime(Runtime::kThrowNotDateError, 0);
- __ bind(&done);
context()->Plug(result);
}
Register result = ToRegister(instr->result());
Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
- Label runtime, done;
DCHECK(object.is(result));
DCHECK(object.is(eax));
- __ test(object, Immediate(kSmiTagMask));
- DeoptimizeIf(zero, instr, Deoptimizer::kSmi);
- __ CmpObjectType(object, JS_DATE_TYPE, scratch);
- DeoptimizeIf(not_equal, instr, Deoptimizer::kNotADateObject);
-
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));
LOperand* date = UseFixed(instr->value(), eax);
LDateField* result =
new(zone()) LDateField(date, FixedTemp(ecx), instr->index());
- return MarkAsCall(DefineFixed(result, eax), instr, CAN_DEOPTIMIZE_EAGERLY);
+ return MarkAsCall(DefineFixed(result, eax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}
# Gets the value of a Date object. If arg is not a Date object
# a type error is thrown.
-macro CHECK_DATE(arg) = if (%_ClassOf(arg) !== 'Date') throw MakeTypeError(kDateType);
+macro CHECK_DATE(arg) = %_ThrowIfNotADate(arg);
macro LOCAL_DATE_VALUE(arg) = (%_DateField(arg, 0) + %_DateField(arg, 21));
macro UTC_DATE_VALUE(arg) = (%_DateField(arg, 0));
}
+void FullCodeGenerator::EmitThrowIfNotADate(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ VisitForAccumulatorValue(args->at(0)); // Load the object.
+
+ Label done, not_date_object;
+ Register object = v0;
+ Register result = v0;
+ Register scratch1 = a1;
+
+ __ JumpIfSmi(object, ¬_date_object);
+ __ GetObjectType(object, scratch1, scratch1);
+ __ Branch(&done, eq, scratch1, Operand(JS_DATE_TYPE));
+ __ bind(¬_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+
+ __ bind(&done);
+ context()->Plug(result);
+}
+
+
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2);
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done, not_date_object;
Register object = v0;
Register result = v0;
Register scratch0 = t5;
Register scratch1 = a1;
- __ JumpIfSmi(object, ¬_date_object);
- __ GetObjectType(object, scratch1, scratch1);
- __ Branch(¬_date_object, ne, scratch1, Operand(JS_DATE_TYPE));
-
if (index->value() == 0) {
__ lw(result, FieldMemOperand(object, JSDate::kValueOffset));
- __ jmp(&done);
} else {
+ Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
__ li(scratch1, Operand(stamp));
__ li(a1, Operand(index));
__ Move(a0, object);
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
- __ jmp(&done);
+ __ bind(&done);
}
- __ bind(¬_date_object);
- __ CallRuntime(Runtime::kThrowNotDateError, 0);
- __ bind(&done);
- context()->Plug(v0);
+ context()->Plug(result);
}
Register result = ToRegister(instr->result());
Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
- Label runtime, done;
DCHECK(object.is(a0));
DCHECK(result.is(v0));
DCHECK(!scratch.is(scratch0()));
DCHECK(!scratch.is(object));
- __ SmiTst(object, at);
- DeoptimizeIf(eq, instr, Deoptimizer::kSmi, at, Operand(zero_reg));
- __ GetObjectType(object, scratch, scratch);
- DeoptimizeIf(ne, instr, Deoptimizer::kNotADateObject, scratch,
- Operand(JS_DATE_TYPE));
-
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));
LOperand* object = UseFixed(instr->value(), a0);
LDateField* result =
new(zone()) LDateField(object, FixedTemp(a1), instr->index());
- return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY);
+ return MarkAsCall(DefineFixed(result, v0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}
}
+void FullCodeGenerator::EmitThrowIfNotADate(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ VisitForAccumulatorValue(args->at(0)); // Load the object.
+
+ Label done, not_date_object;
+ Register object = v0;
+ Register result = v0;
+ Register scratch1 = a1;
+
+ __ JumpIfSmi(object, ¬_date_object);
+ __ GetObjectType(object, scratch1, scratch1);
+ __ Branch(&done, eq, scratch1, Operand(JS_DATE_TYPE));
+ __ bind(¬_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+
+ __ bind(&done);
+ context()->Plug(result);
+}
+
+
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2);
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done, not_date_object;
Register object = v0;
Register result = v0;
Register scratch0 = t1;
Register scratch1 = a1;
- __ JumpIfSmi(object, ¬_date_object);
- __ GetObjectType(object, scratch1, scratch1);
- __ Branch(¬_date_object, ne, scratch1, Operand(JS_DATE_TYPE));
-
if (index->value() == 0) {
__ ld(result, FieldMemOperand(object, JSDate::kValueOffset));
- __ jmp(&done);
} else {
+ Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
__ li(scratch1, Operand(stamp));
__ li(a1, Operand(index));
__ Move(a0, object);
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
- __ jmp(&done);
+ __ bind(&done);
}
- __ bind(¬_date_object);
- __ CallRuntime(Runtime::kThrowNotDateError, 0);
- __ bind(&done);
- context()->Plug(v0);
+ context()->Plug(result);
}
Register result = ToRegister(instr->result());
Register scratch = ToRegister(instr->temp());
Smi* index = instr->index();
- Label runtime, done;
DCHECK(object.is(a0));
DCHECK(result.is(v0));
DCHECK(!scratch.is(scratch0()));
DCHECK(!scratch.is(object));
- __ SmiTst(object, at);
- DeoptimizeIf(eq, instr, Deoptimizer::kSmi, at, Operand(zero_reg));
- __ GetObjectType(object, scratch, scratch);
- DeoptimizeIf(ne, instr, Deoptimizer::kNotADateObject, scratch,
- Operand(JS_DATE_TYPE));
-
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));
LOperand* object = UseFixed(instr->value(), a0);
LDateField* result =
new(zone()) LDateField(object, FixedTemp(a1), instr->index());
- return MarkAsCall(DefineFixed(result, v0), instr, CAN_DEOPTIMIZE_EAGERLY);
+ return MarkAsCall(DefineFixed(result, v0), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}
}
+RUNTIME_FUNCTION(Runtime_ThrowIfNotADate) {
+ SealHandleScope shs(isolate);
+ DCHECK_EQ(1, args.length());
+ CONVERT_ARG_CHECKED(Object, obj, 0);
+ if (!obj->IsJSDate()) {
+ HandleScope scope(isolate);
+ THROW_NEW_ERROR_RETURN_FAILURE(
+ isolate, NewTypeError(MessageTemplate::kNotDateObject));
+ }
+ return obj;
+}
+
+
RUNTIME_FUNCTION(Runtime_ThrowNotDateError) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
RUNTIME_FUNCTION(Runtime_DateField) {
SealHandleScope shs(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_CHECKED(Object, obj, 0);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_CHECKED(JSDate, date, 0);
CONVERT_SMI_ARG_CHECKED(index, 1);
- if (!obj->IsJSDate()) {
- HandleScope scope(isolate);
- THROW_NEW_ERROR_RETURN_FAILURE(
- isolate, NewTypeError(MessageTemplate::kNotDateObject));
- }
- JSDate* date = JSDate::cast(obj);
+ DCHECK_LE(0, index);
if (index == 0) return date->value();
return JSDate::GetField(date, Smi::FromInt(index));
}
+
} // namespace internal
} // namespace v8
#define FOR_EACH_INTRINSIC_DATE(F) \
F(DateMakeDay, 2, 1) \
F(DateSetValue, 3, 1) \
+ F(ThrowIfNotADate, 1, 1) \
F(ThrowNotDateError, 0, 1) \
F(DateCurrentTime, 0, 1) \
F(DateParseString, 2, 1) \
}
+void FullCodeGenerator::EmitThrowIfNotADate(CallRuntime* expr) {
+ ZoneList<Expression*>* args = expr->arguments();
+ DCHECK_EQ(1, args->length());
+
+ VisitForAccumulatorValue(args->at(0)); // Load the object.
+
+ Register object = rax;
+ Register result = rax;
+ Register scratch = rcx;
+
+ Label done, not_date_object;
+ __ JumpIfSmi(object, ¬_date_object, Label::kNear);
+ __ CmpObjectType(object, JS_DATE_TYPE, scratch);
+ __ j(equal, &done, Label::kNear);
+ __ bind(¬_date_object);
+ __ CallRuntime(Runtime::kThrowNotDateError, 0);
+
+ __ bind(&done);
+ context()->Plug(result);
+}
+
+
void FullCodeGenerator::EmitDateField(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 2);
VisitForAccumulatorValue(args->at(0)); // Load the object.
- Label runtime, done, not_date_object;
Register object = rax;
Register result = rax;
Register scratch = rcx;
- __ JumpIfSmi(object, ¬_date_object);
- __ CmpObjectType(object, JS_DATE_TYPE, scratch);
- __ j(not_equal, ¬_date_object);
+ 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));
- __ jmp(&done);
} else {
+ Label runtime, done;
if (index->value() < JSDate::kFirstUncachedField) {
ExternalReference stamp = ExternalReference::date_cache_stamp(isolate());
Operand stamp_operand = __ ExternalOperand(stamp);
__ j(not_equal, &runtime, Label::kNear);
__ movp(result, FieldOperand(object, JSDate::kValueOffset +
kPointerSize * index->value()));
- __ jmp(&done);
+ __ jmp(&done, Label::kNear);
}
__ bind(&runtime);
__ PrepareCallCFunction(2);
__ Move(arg_reg_2, index, Assembler::RelocInfoNone());
__ CallCFunction(ExternalReference::get_date_field_function(isolate()), 2);
__ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
- __ jmp(&done);
+ __ bind(&done);
}
- __ bind(¬_date_object);
- __ CallRuntime(Runtime::kThrowNotDateError, 0);
- __ bind(&done);
context()->Plug(rax);
}
Register object = ToRegister(instr->date());
Register result = ToRegister(instr->result());
Smi* index = instr->index();
- Label runtime, done, not_date_object;
DCHECK(object.is(result));
DCHECK(object.is(rax));
- Condition cc = masm()->CheckSmi(object);
- DeoptimizeIf(cc, instr, Deoptimizer::kSmi);
- __ CmpObjectType(object, JS_DATE_TYPE, kScratchRegister);
- DeoptimizeIf(not_equal, instr, Deoptimizer::kNotADateObject);
+ 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);
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, CAN_DEOPTIMIZE_EAGERLY);
+ return MarkAsCall(DefineFixed(result, rax), instr, CANNOT_DEOPTIMIZE_EAGERLY);
}