Reviewers: Søren Gjesse,
Description:
MIPS: port Implement set trap for proxies, and revamp class hierarchy in
preparation
Ported commits: r8126 (6461bae)
Original commit message:
- Introduce a class JSReceiver, that is a common superclass of JSObject and
JSProxy. Use JSReceiver where appropriate (probably lots of places that we
still have to migrate, but we will find those later with proxy test suite).
- Move appropriate methods to JSReceiver class (SetProperty,
GetPropertyAttribute, Get/SetPrototype, Lookup, and so on).
- Introduce new JSFunctionProxy subclass of JSProxy. Currently only a stub.
- Overhaul enum InstanceType:
* Introduce FIRST/LAST_SPEC_OBJECT_TYPE that ranges over all types that
represent JS objects, and use that consistently to check language types.
* Rename FIRST/LAST_JS_OBJECT_TYPE and FIRST/LAST_FUNCTION_CLASS_TYPE
to FIRST/LAST_[NON]CALLABLE_SPEC_OBJECT_TYPE for clarity.
* Eliminate the overlap over JS_REGEXP_TYPE.
* Also replace FIRST_JS_OBJECT with FIRST_JS_RECEIVER, but only use it where
we exclusively talk about the internal representation type.
* Insert JS_PROXY and JS_FUNCTION_PROXY in the appropriate places.
- Fix all checks concerning classification, especially for functions, to
use the CALLABLE_SPEC_OBJECT range (that includes funciton proxies).
- Handle proxies in SetProperty (that was the easiest part :) ).
- A few simple test cases.
BUG=
TEST=
Please review this at http://codereview.chromium.org/7024041/
Affected files:
M src/mips/builtins-mips.cc
M src/mips/code-stubs-mips.cc
M src/mips/full-codegen-mips.cc
M src/mips/ic-mips.cc
M src/mips/macro-assembler-mips.cc
M src/mips/stub-cache-mips.cc
Index: src/mips/builtins-mips.cc
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index
420e2ca3b4345eef9edd7179361826ecd986fe8a..036847e1b3683fdf8682cd84c5b20ae5e41962ec
100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -974,9 +974,9 @@ static void
Generate_JSConstructStubHelper(MacroAssembler* masm,
__ Branch(&use_receiver, eq, t0, Operand(zero_reg));
// If the type of the result (stored in its map) is less than
- // FIRST_JS_OBJECT_TYPE, it is not an object in the ECMA sense.
+ // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
__ GetObjectType(v0, a3, a3);
- __ Branch(&exit, greater_equal, a3, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(&exit, greater_equal, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
// Throw away the result of the constructor invocation and use the
// on-stack receiver as the result.
@@ -1234,10 +1234,9 @@ void Builtins::Generate_FunctionCall(MacroAssembler*
masm) {
__ LoadRoot(a3, Heap::kNullValueRootIndex);
__ Branch(&use_global_receiver, eq, a2, Operand(a3));
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ GetObjectType(a2, a3, a3);
- __ Branch(&shift_arguments, ge, a3, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(&shift_arguments, ge, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
__ bind(&convert_to_object);
__ EnterInternalFrame(); // In order to preserve argument count.
@@ -1416,10 +1415,9 @@ void
Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// Check if the receiver is already a JavaScript object.
// a0: receiver
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
__ GetObjectType(a0, a1, a1);
- __ Branch(&push_receiver, ge, a1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(&push_receiver, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
// Convert the receiver to a regular object.
// a0: receiver
Index: src/mips/code-stubs-mips.cc
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index
e14b2bae899ebbe24e70b670f8c734de8d03a635..585af93e8fc2bda8c9336b4004be70b4f89d8f8b
100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -985,13 +985,13 @@ static void
EmitIdenticalObjectComparison(MacroAssembler* masm,
// Smis. If it's not a heap number, then return equal.
if (cc == less || cc == greater) {
__ GetObjectType(a0, t4, t4);
- __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
} else {
__ GetObjectType(a0, t4, t4);
__ Branch(&heap_number, eq, t4, Operand(HEAP_NUMBER_TYPE));
// Comparing JS objects with <=, >= is complicated.
if (cc != eq) {
- __ Branch(slow, greater, t4, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(slow, greater, t4, Operand(FIRST_SPEC_OBJECT_TYPE));
// Normally here we fall through to return_equal, but undefined is
// special: (undefined == undefined) == true, but
// (undefined <= undefined) == false! See ECMAScript 11.8.5.
@@ -1309,15 +1309,15 @@ static void
EmitTwoNonNanDoubleComparison(MacroAssembler* masm, Condition cc) {
static void EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
Register lhs,
Register rhs) {
- // If either operand is a JSObject or an oddball value, then they are
+ // If either operand is a JS object or an oddball value, then they are
// not equal since their pointers are different.
// There is no test for undetectability in strict equality.
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
Label first_non_object;
// Get the type of the first operand into a2 and compare it with
- // FIRST_JS_OBJECT_TYPE.
+ // FIRST_SPEC_OBJECT_TYPE.
__ GetObjectType(lhs, a2, a2);
- __ Branch(&first_non_object, less, a2, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(&first_non_object, less, a2,
Operand(FIRST_SPEC_OBJECT_TYPE));
// Return non-zero.
Label return_not_equal;
@@ -1330,7 +1330,7 @@ static void
EmitStrictTwoHeapObjectCompare(MacroAssembler* masm,
__ Branch(&return_not_equal, eq, a2, Operand(ODDBALL_TYPE));
__ GetObjectType(rhs, a3, a3);
- __ Branch(&return_not_equal, greater, a3,
Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(&return_not_equal, greater, a3,
Operand(FIRST_SPEC_OBJECT_TYPE));
// Check for oddballs: true, false, null, undefined.
__ Branch(&return_not_equal, eq, a3, Operand(ODDBALL_TYPE));
@@ -1406,9 +1406,9 @@ static void
EmitCheckForSymbolsOrObjects(MacroAssembler* masm,
__ Ret();
__ bind(&object_test);
- __ Branch(not_both_strings, lt, a2, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(not_both_strings, lt, a2, Operand(FIRST_SPEC_OBJECT_TYPE));
__ GetObjectType(rhs, a2, a3);
- __ Branch(not_both_strings, lt, a3, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(not_both_strings, lt, a3, Operand(FIRST_SPEC_OBJECT_TYPE));
// If both objects are undetectable, they are equal. Otherwise, they
// are not equal, since they are different objects and an object is not
@@ -1784,7 +1784,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) {
// "tos_" is a register and contains a non-zero value.
// Hence we implicitly return true if the greater than
// condition is satisfied.
- __ Ret(gt, scratch0, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Ret(gt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
// Check for string.
__ lw(scratch0, FieldMemOperand(tos_, HeapObject::kMapOffset));
Index: src/mips/full-codegen-mips.cc
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index
b085859d00bd2a6194d210ad7d749ff69cdd10ad..c1472bb4eb0c0f78a376d67b94efd37e0d2c99f3
100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -918,7 +918,7 @@ void
FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
Label convert, done_convert;
__ JumpIfSmi(a0, &convert);
__ GetObjectType(a0, a1, a1);
- __ Branch(&done_convert, hs, a1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(&done_convert, ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
__ bind(&convert);
__ push(a0);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
@@ -2477,9 +2477,9 @@ void
FullCodeGenerator::EmitIsObject(ZoneList<Expression*>* args) {
__ And(at, a1, Operand(1 << Map::kIsUndetectable));
__ Branch(if_false, ne, at, Operand(zero_reg));
__ lbu(a1, FieldMemOperand(a2, Map::kInstanceTypeOffset));
- __ Branch(if_false, lt, a1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(if_false, lt, a1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
- Split(le, a1, Operand(LAST_JS_OBJECT_TYPE), if_true, if_false,
fall_through);
+ Split(le, a1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE), if_true,
if_false, fall_through);
context()->Plug(if_true, if_false);
}
@@ -2500,7 +2500,7 @@ void
FullCodeGenerator::EmitIsSpecObject(ZoneList<Expression*>* args) {
__ JumpIfSmi(v0, if_false);
__ GetObjectType(v0, a1, a1);
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
- Split(ge, a1, Operand(FIRST_JS_OBJECT_TYPE),
+ Split(ge, a1, Operand(FIRST_SPEC_OBJECT_TYPE),
if_true, if_false, fall_through);
context()->Plug(if_true, if_false);
@@ -2779,14 +2779,15 @@ void
FullCodeGenerator::EmitClassOf(ZoneList<Expression*>* args) {
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
__ GetObjectType(v0, v0, a1); // Map is now in v0.
- __ Branch(&null, lt, a1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(&null, lt, a1, Operand(FIRST_SPEC_OBJECT_TYPE));
- // As long as JS_FUNCTION_TYPE is the last instance type and it is
- // right after LAST_JS_OBJECT_TYPE, we can avoid checking for
- // LAST_JS_OBJECT_TYPE.
- ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- ASSERT(JS_FUNCTION_TYPE == LAST_JS_OBJECT_TYPE + 1);
- __ Branch(&function, eq, a1, Operand(JS_FUNCTION_TYPE));
+ // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last instance type,
and
+ // FIRST_CALLABLE_SPEC_OBJECT_TYPE comes right after
+ // LAST_NONCALLABLE_SPEC_OBJECT_TYPE, we can avoid checking for the
latter.
+ STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+ STATIC_ASSERT(FIRST_CALLABLE_SPEC_OBJECT_TYPE ==
+ LAST_NONCALLABLE_SPEC_OBJECT_TYPE + 1);
+ __ Branch(&function, ge, a1, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE));
// Check if the constructor in the map is a function.
__ lw(v0, FieldMemOperand(v0, Map::kConstructorOffset));
@@ -4098,7 +4099,7 @@ bool
FullCodeGenerator::TryLiteralCompare(Token::Value op,
} else if (check->Equals(isolate()->heap()->function_symbol())) {
__ JumpIfSmi(v0, if_false);
__ GetObjectType(v0, a1, v0); // Leave map in a1.
- Split(ge, v0, Operand(FIRST_FUNCTION_CLASS_TYPE),
+ Split(ge, v0, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE),
if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->object_symbol())) {
@@ -4107,9 +4108,9 @@ bool
FullCodeGenerator::TryLiteralCompare(Token::Value op,
__ Branch(if_true, eq, v0, Operand(at));
// Check for JS objects => true.
__ GetObjectType(v0, v0, a1);
- __ Branch(if_false, lo, a1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(if_false, lt, a1,
Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
__ lbu(a1, FieldMemOperand(v0, Map::kInstanceTypeOffset));
- __ Branch(if_false, hs, a1, Operand(FIRST_FUNCTION_CLASS_TYPE));
+ __ Branch(if_false, gt, a1,
Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
// Check for undetectable objects => false.
__ lbu(a1, FieldMemOperand(v0, Map::kBitFieldOffset));
__ And(a1, a1, Operand(1 << Map::kIsUndetectable));
Index: src/mips/ic-mips.cc
diff --git a/src/mips/ic-mips.cc b/src/mips/ic-mips.cc
index
85b1ca22d2db5951ae94a7c62f49f5c78ab9b991..2a13901562eae221ce7a44abdce8461ce0e3da90
100644
--- a/src/mips/ic-mips.cc
+++ b/src/mips/ic-mips.cc
@@ -80,10 +80,10 @@ static void
GenerateStringDictionaryReceiverCheck(MacroAssembler* masm,
// Check that the receiver is a valid JS object.
__ GetObjectType(receiver, scratch0, scratch1);
- __ Branch(miss, lt, scratch1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(miss, lt, scratch1, Operand(FIRST_SPEC_OBJECT_TYPE));
// If this assert fails, we have to check upper bound too.
- ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
GenerateGlobalInstanceTypeCheck(masm, scratch1, miss);
@@ -1174,8 +1174,10 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler*
masm,
__ lbu(t3, FieldMemOperand(t3, Map::kInstanceTypeOffset));
__ Branch(&array, eq, t3, Operand(JS_ARRAY_TYPE));
- // Check that the object is some kind of JS object.
- __ Branch(&slow, lt, t3, Operand(FIRST_JS_OBJECT_TYPE));
+ // Check that the object is some kind of JSObject.
+ __ Branch(&slow, lt, t3, Operand(FIRST_JS_RECEIVER_TYPE));
+ __ Branch(&slow, eq, t3, Operand(JS_PROXY_TYPE));
+ __ Branch(&slow, eq, t3, Operand(JS_FUNCTION_PROXY_TYPE));
// Object case: Check key against length in the elements array.
__ lw(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
Index: src/mips/macro-assembler-mips.cc
diff --git a/src/mips/macro-assembler-mips.cc
b/src/mips/macro-assembler-mips.cc
index
bd585946f11d546bed602bd8d338b4ca1f0f1c5c..244056ff28fdeca4cd5184726555a76e04fc048b
100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -2930,8 +2930,8 @@ void MacroAssembler::IsInstanceJSObjectType(Register
map,
Register scratch,
Label* fail) {
lbu(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
- Branch(fail, lt, scratch, Operand(FIRST_JS_OBJECT_TYPE));
- Branch(fail, gt, scratch, Operand(LAST_JS_OBJECT_TYPE));
+ Branch(fail, lt, scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+ Branch(fail, gt, scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
}
Index: src/mips/stub-cache-mips.cc
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index
fa2dd47b03d669e97580f7561357cae4f25bcef2..dfae057abdb5555d95cfa7376f221621f8d1eb56
100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -126,7 +126,7 @@ MUST_USE_RESULT static MaybeObject*
GenerateDictionaryNegativeLookup(
// Check that receiver is a JSObject.
__ lbu(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
- __ Branch(miss_label, lt, scratch0, Operand(FIRST_JS_OBJECT_TYPE));
+ __ Branch(miss_label, lt, scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
// Load properties array.
Register properties = scratch0;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev