Commit 3ac8bf41 authored by palfia@homejinni.com's avatar palfia@homejinni.com

MIPS: ES6 symbols: turn symbols into a proper primitive type

Port r14051 (e9140a92)

Original commit message:
(qua last week's TC39)

Specifically:
- Install Symbol constructor function on the global object.
- Adjust code generation for typeof.
- Remove IsSymbol built-in, IS_SYMBOL macro now defined using typeof.
- Remove hack that allowed symbols as constructor results, and some other special cases.
- Remove symbol_delegate and GetDelegate function.
- Extend ToBoolean stub to handle symbols.
- Extend ToNumber to return NaN on symbols.
- Poison symbol's toString function, and thereby ToString on symbols.

BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14058 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9bebd23d
......@@ -1130,10 +1130,6 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
__ GetObjectType(v0, a1, a3);
__ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
// Symbols are "objects".
__ lbu(a3, FieldMemOperand(a1, Map::kInstanceTypeOffset));
__ Branch(&exit, eq, a3, Operand(SYMBOL_TYPE));
// Throw away the result of the constructor invocation and use the
// on-stack receiver as the result.
__ bind(&use_receiver);
......
......@@ -2780,28 +2780,6 @@ void FullCodeGenerator::EmitIsStringWrapperSafeForDefaultValueOf(
}
void FullCodeGenerator::EmitIsSymbol(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 1);
VisitForAccumulatorValue(args->at(0));
Label materialize_true, materialize_false;
Label* if_true = NULL;
Label* if_false = NULL;
Label* fall_through = NULL;
context()->PrepareTest(&materialize_true, &materialize_false,
&if_true, &if_false, &fall_through);
__ JumpIfSmi(v0, if_false);
__ GetObjectType(v0, a1, a2);
PrepareForBailoutBeforeSplit(expr, true, if_true, if_false);
Split(eq, a2, Operand(SYMBOL_TYPE), if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
}
void FullCodeGenerator::EmitIsFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() == 1);
......@@ -4320,6 +4298,10 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ And(a1, a1, Operand(1 << Map::kIsUndetectable));
Split(eq, a1, Operand(zero_reg),
if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->symbol_string())) {
__ JumpIfSmi(v0, if_false);
__ GetObjectType(v0, v0, a1);
Split(eq, a1, Operand(SYMBOL_TYPE), if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->boolean_string())) {
__ LoadRoot(at, Heap::kTrueValueRootIndex);
__ Branch(if_true, eq, v0, Operand(at));
......@@ -4351,10 +4333,6 @@ void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr,
__ LoadRoot(at, Heap::kNullValueRootIndex);
__ Branch(if_true, eq, v0, Operand(at));
}
if (FLAG_harmony_symbols) {
__ GetObjectType(v0, v0, a1);
__ Branch(if_true, eq, a1, Operand(SYMBOL_TYPE));
}
// Check for JS objects => true.
__ GetObjectType(v0, v0, a1);
__ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
......
......@@ -1901,6 +1901,13 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ bind(&not_string);
}
if (expected.Contains(ToBooleanStub::SYMBOL)) {
// Symbol value -> true.
const Register scratch = scratch1();
__ lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
__ Branch(true_label, eq, scratch, Operand(SYMBOL_TYPE));
}
if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
CpuFeatureScope scope(masm(), FPU);
// heap number -> false iff +0, -0, or NaN.
......@@ -5771,6 +5778,13 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
cmp2 = Operand(zero_reg);
final_branch_condition = eq;
} else if (type_name->Equals(heap()->symbol_string())) {
__ JumpIfSmi(input, false_label);
__ GetObjectType(input, input, scratch);
cmp1 = scratch;
cmp2 = Operand(SYMBOL_TYPE);
final_branch_condition = eq;
} else if (type_name->Equals(heap()->boolean_string())) {
__ LoadRoot(at, Heap::kTrueValueRootIndex);
__ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
......@@ -5814,20 +5828,10 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
__ LoadRoot(at, Heap::kNullValueRootIndex);
__ Branch(USE_DELAY_SLOT, true_label, eq, at, Operand(input));
}
if (FLAG_harmony_symbols) {
// input is an object, it is safe to use GetObjectType in the delay slot.
__ GetObjectType(input, input, scratch);
__ Branch(USE_DELAY_SLOT, true_label, eq, scratch, Operand(SYMBOL_TYPE));
// Still an object, so the InstanceType can be loaded.
__ lbu(scratch, FieldMemOperand(input, Map::kInstanceTypeOffset));
__ Branch(USE_DELAY_SLOT, false_label,
lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
} else {
// input is an object, it is safe to use GetObjectType in the delay slot.
__ GetObjectType(input, input, scratch);
__ Branch(USE_DELAY_SLOT, false_label,
lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
}
// input is an object, it is safe to use GetObjectType in the delay slot.
__ GetObjectType(input, input, scratch);
__ Branch(USE_DELAY_SLOT, false_label,
lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
// Still an object, so the InstanceType can be loaded.
__ lbu(scratch, FieldMemOperand(input, Map::kInstanceTypeOffset));
__ Branch(USE_DELAY_SLOT, false_label,
......
......@@ -2424,6 +2424,12 @@ void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
// Check that the object is a symbol.
__ GetObjectType(a1, a1, a3);
__ Branch(&miss, ne, a3, Operand(SYMBOL_TYPE));
// Check that the maps starting from the prototype haven't changed.
GenerateDirectLoadGlobalFunctionPrototype(
masm(), Context::SYMBOL_FUNCTION_INDEX, a0, &miss);
CheckPrototypes(
Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
a0, holder, a3, a1, t0, name, &miss);
break;
case NUMBER_CHECK: {
......
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