Revision: 8175
Author:   [email protected]
Date:     Mon Jun  6 01:47:27 2011
Log: 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=

Review URL: http://codereview.chromium.org/7024041
Patch from Paul Lind <[email protected]>.
http://code.google.com/p/v8/source/detail?r=8175

Modified:
 /branches/bleeding_edge/src/mips/builtins-mips.cc
 /branches/bleeding_edge/src/mips/code-stubs-mips.cc
 /branches/bleeding_edge/src/mips/full-codegen-mips.cc
 /branches/bleeding_edge/src/mips/ic-mips.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.cc
 /branches/bleeding_edge/src/mips/stub-cache-mips.cc

=======================================
--- /branches/bleeding_edge/src/mips/builtins-mips.cc Wed Jun 1 02:05:44 2011 +++ /branches/bleeding_edge/src/mips/builtins-mips.cc Mon Jun 6 01:47:27 2011
@@ -974,9 +974,9 @@
   __ 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 @@
     __ 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 @@

   // 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
=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.cc Mon Jun 6 01:43:15 2011 +++ /branches/bleeding_edge/src/mips/code-stubs-mips.cc Mon Jun 6 01:47:27 2011
@@ -983,13 +983,13 @@
     // 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.
@@ -1307,15 +1307,15 @@
 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;
@@ -1328,7 +1328,7 @@
     __ 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));
@@ -1404,9 +1404,9 @@
   __ 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
@@ -1782,7 +1782,7 @@
   // "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));
=======================================
--- /branches/bleeding_edge/src/mips/full-codegen-mips.cc Wed Jun 1 02:06:46 2011 +++ /branches/bleeding_edge/src/mips/full-codegen-mips.cc Mon Jun 6 01:47:27 2011
@@ -918,7 +918,7 @@
   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,10 @@
   __ 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 +2501,7 @@
   __ 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 +2780,15 @@
   // 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));
-
-  // 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));
+  __ Branch(&null, lt, a1, Operand(FIRST_SPEC_OBJECT_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 +4100,7 @@
   } 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 +4109,9 @@
     __ 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));
=======================================
--- /branches/bleeding_edge/src/mips/ic-mips.cc Wed Jun  1 02:01:57 2011
+++ /branches/bleeding_edge/src/mips/ic-mips.cc Mon Jun  6 01:47:27 2011
@@ -80,10 +80,10 @@

   // 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 @@
   __ 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));
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Mon Jun 6 01:43:15 2011 +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Mon Jun 6 01:47:27 2011
@@ -2935,8 +2935,8 @@
                                             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));
 }


=======================================
--- /branches/bleeding_edge/src/mips/stub-cache-mips.cc Mon Jun 6 01:43:15 2011 +++ /branches/bleeding_edge/src/mips/stub-cache-mips.cc Mon Jun 6 01:47:27 2011
@@ -126,7 +126,7 @@

   // 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

Reply via email to