static const int kFullStringRepresentationMask = 0x07;
static const int kExternalTwoByteRepresentationTag = 0x02;
- static const int kJSObjectType = 0xa2;
+ static const int kJSObjectType = 0xa1;
static const int kFirstNonstringType = 0x80;
static const int kForeignType = 0x85;
__ b(eq, &use_receiver);
// 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.
- __ CompareObjectType(r0, r3, r3, FIRST_JS_OBJECT_TYPE);
+ // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
+ __ CompareObjectType(r0, r3, r3, FIRST_SPEC_OBJECT_TYPE);
__ b(ge, &exit);
// Throw away the result of the constructor invocation and use the
__ cmp(r2, r3);
__ b(eq, &use_global_receiver);
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- __ CompareObjectType(r2, r3, r3, FIRST_JS_OBJECT_TYPE);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+ __ CompareObjectType(r2, r3, r3, FIRST_SPEC_OBJECT_TYPE);
__ b(ge, &shift_arguments);
__ bind(&convert_to_object);
// Check if the receiver is already a JavaScript object.
// r0: receiver
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+ __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
__ b(ge, &push_receiver);
// Convert the receiver to a regular object.
// They are both equal and they are not both Smis so both of them are not
// Smis. If it's not a heap number, then return equal.
if (cond == lt || cond == gt) {
- __ CompareObjectType(r0, r4, r4, FIRST_JS_OBJECT_TYPE);
+ __ CompareObjectType(r0, r4, r4, FIRST_SPEC_OBJECT_TYPE);
__ b(ge, slow);
} else {
__ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
__ b(eq, &heap_number);
// Comparing JS objects with <=, >= is complicated.
if (cond != eq) {
- __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
+ __ cmp(r4, Operand(FIRST_SPEC_OBJECT_TYPE));
__ b(ge, slow);
// Normally here we fall through to return_equal, but undefined is
// special: (undefined == undefined) == true, but
ASSERT((lhs.is(r0) && rhs.is(r1)) ||
(lhs.is(r1) && rhs.is(r0)));
- // 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 r2 and compare it with
- // FIRST_JS_OBJECT_TYPE.
- __ CompareObjectType(rhs, r2, r2, FIRST_JS_OBJECT_TYPE);
+ // FIRST_SPEC_OBJECT_TYPE.
+ __ CompareObjectType(rhs, r2, r2, FIRST_SPEC_OBJECT_TYPE);
__ b(lt, &first_non_object);
// Return non-zero (r0 is not zero)
__ cmp(r2, Operand(ODDBALL_TYPE));
__ b(eq, &return_not_equal);
- __ CompareObjectType(lhs, r3, r3, FIRST_JS_OBJECT_TYPE);
+ __ CompareObjectType(lhs, r3, r3, FIRST_SPEC_OBJECT_TYPE);
__ b(ge, &return_not_equal);
// Check for oddballs: true, false, null, undefined.
__ Ret();
__ bind(&object_test);
- __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE));
+ __ cmp(r2, Operand(FIRST_SPEC_OBJECT_TYPE));
__ b(lt, not_both_strings);
- __ CompareObjectType(lhs, r2, r3, FIRST_JS_OBJECT_TYPE);
+ __ CompareObjectType(lhs, r2, r3, FIRST_SPEC_OBJECT_TYPE);
__ b(lt, not_both_strings);
// If both objects are undetectable, they are equal. Otherwise, they
// are not equal, since they are different objects and an object is not
// JavaScript object => true.
__ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
__ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
- __ cmp(scratch, Operand(FIRST_JS_OBJECT_TYPE));
+ __ cmp(scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
// "tos_" is a register and contains a non-zero value.
// Hence we implicitly return true if the greater than
// condition is satisfied.
// Convert the object to a JS object.
Label convert, done_convert;
__ JumpIfSmi(r0, &convert);
- __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
- __ b(hs, &done_convert);
+ __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
+ __ b(ge, &done_convert);
__ bind(&convert);
__ push(r0);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
__ tst(r1, Operand(1 << Map::kIsUndetectable));
__ b(ne, if_false);
__ ldrb(r1, FieldMemOperand(r2, Map::kInstanceTypeOffset));
- __ cmp(r1, Operand(FIRST_JS_OBJECT_TYPE));
+ __ cmp(r1, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
__ b(lt, if_false);
- __ cmp(r1, Operand(LAST_JS_OBJECT_TYPE));
+ __ cmp(r1, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(le, if_true, if_false, fall_through);
&if_true, &if_false, &fall_through);
__ JumpIfSmi(r0, if_false);
- __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
+ __ CompareObjectType(r0, r1, r1, FIRST_SPEC_OBJECT_TYPE);
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(ge, if_true, if_false, fall_through);
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
- __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE); // Map is now in r0.
+ __ CompareObjectType(r0, r0, r1, FIRST_SPEC_OBJECT_TYPE);
+ // Map is now in r0.
__ b(lt, &null);
- // 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);
- __ cmp(r1, Operand(JS_FUNCTION_TYPE));
- __ b(eq, &function);
+ // 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);
+ __ cmp(r1, Operand(FIRST_CALLABLE_SPEC_OBJECT_TYPE));
+ __ b(ge, &function);
// Check if the constructor in the map is a function.
__ ldr(r0, FieldMemOperand(r0, Map::kConstructorOffset));
} else if (check->Equals(isolate()->heap()->function_symbol())) {
__ JumpIfSmi(r0, if_false);
- __ CompareObjectType(r0, r1, r0, FIRST_FUNCTION_CLASS_TYPE);
+ __ CompareObjectType(r0, r1, r0, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
Split(ge, if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->object_symbol())) {
__ CompareRoot(r0, Heap::kNullValueRootIndex);
__ b(eq, if_true);
// Check for JS objects => true.
- __ CompareObjectType(r0, r0, r1, FIRST_JS_OBJECT_TYPE);
- __ b(lo, if_false);
- __ CompareInstanceType(r0, r1, FIRST_FUNCTION_CLASS_TYPE);
- __ b(hs, if_false);
+ __ CompareObjectType(r0, r0, r1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ b(lt, if_false);
+ __ CompareInstanceType(r0, r1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ b(gt, if_false);
// Check for undetectable objects => false.
__ ldrb(r1, FieldMemOperand(r0, Map::kBitFieldOffset));
__ tst(r1, Operand(1 << Map::kIsUndetectable));
__ b(eq, miss);
// Check that the receiver is a valid JS object.
- __ CompareObjectType(receiver, t0, t1, FIRST_JS_OBJECT_TYPE);
+ __ CompareObjectType(receiver, t0, t1, FIRST_SPEC_OBJECT_TYPE);
__ b(lt, miss);
// 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, t1, miss);
__ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset));
__ cmp(r4, Operand(JS_ARRAY_TYPE));
__ b(eq, &array);
- // Check that the object is some kind of JS object.
- __ cmp(r4, Operand(FIRST_JS_OBJECT_TYPE));
+ // Check that the object is some kind of JSObject.
+ __ cmp(r4, Operand(FIRST_JS_RECEIVER_TYPE));
__ b(lt, &slow);
+ __ cmp(r4, Operand(JS_PROXY_TYPE));
+ __ b(eq, &slow);
+ __ cmp(r4, Operand(JS_FUNCTION_PROXY_TYPE));
+ __ b(eq, &slow);
// Object case: Check key against length in the elements array.
__ ldr(elements, FieldMemOperand(receiver, JSObject::kElementsOffset));
// Load instance type and check that it is in object type range.
__ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset));
- __ cmp(temp2, Operand(FIRST_JS_OBJECT_TYPE));
+ __ cmp(temp2, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
__ b(lt, is_not_object);
- __ cmp(temp2, Operand(LAST_JS_OBJECT_TYPE));
+ __ cmp(temp2, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
return le;
}
ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
__ tst(input, Operand(kSmiTagMask));
__ b(eq, is_false);
- __ CompareObjectType(input, temp, temp2, FIRST_JS_OBJECT_TYPE);
+ __ CompareObjectType(input, temp, temp2, FIRST_SPEC_OBJECT_TYPE);
__ b(lt, is_false);
// Map is now in temp.
// Functions have class 'Function'.
- __ CompareInstanceType(temp, temp2, JS_FUNCTION_TYPE);
+ __ CompareInstanceType(temp, temp2, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
if (class_name->IsEqualTo(CStrVector("Function"))) {
- __ b(eq, is_true);
+ __ b(ge, is_true);
} else {
- __ b(eq, is_false);
+ __ b(ge, is_false);
}
// Check if the constructor in the map is a function.
__ ldr(temp, FieldMemOperand(temp, Map::kConstructorOffset));
- // 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);
+ // 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);
// Objects with a non-function constructor have class 'Object'.
__ CompareObjectType(temp, temp2, temp2, JS_FUNCTION_TYPE);
// Deoptimize if the receiver is not a JS object.
__ tst(receiver, Operand(kSmiTagMask));
DeoptimizeIf(eq, instr->environment());
- __ CompareObjectType(receiver, scratch, scratch, FIRST_JS_OBJECT_TYPE);
- DeoptimizeIf(lo, instr->environment());
+ __ CompareObjectType(receiver, scratch, scratch, FIRST_SPEC_OBJECT_TYPE);
+ DeoptimizeIf(lt, instr->environment());
__ jmp(&receiver_ok);
__ bind(&global_object);
} else if (type_name->Equals(heap()->function_symbol())) {
__ JumpIfSmi(input, false_label);
- __ CompareObjectType(input, input, scratch, FIRST_FUNCTION_CLASS_TYPE);
+ __ CompareObjectType(input, input, scratch,
+ FIRST_CALLABLE_SPEC_OBJECT_TYPE);
final_branch_condition = ge;
} else if (type_name->Equals(heap()->object_symbol())) {
__ JumpIfSmi(input, false_label);
__ CompareRoot(input, Heap::kNullValueRootIndex);
__ b(eq, true_label);
- __ CompareObjectType(input, input, scratch, FIRST_JS_OBJECT_TYPE);
- __ b(lo, false_label);
- __ CompareInstanceType(input, scratch, FIRST_FUNCTION_CLASS_TYPE);
- __ b(hs, false_label);
+ __ CompareObjectType(input, input, scratch,
+ FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ b(lt, false_label);
+ __ CompareInstanceType(input, scratch, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ b(gt, false_label);
// Check for undetectable objects => false.
__ ldrb(ip, FieldMemOperand(input, Map::kBitFieldOffset));
__ tst(ip, Operand(1 << Map::kIsUndetectable));
Register scratch,
Label* fail) {
ldrb(scratch, FieldMemOperand(map, Map::kInstanceTypeOffset));
- cmp(scratch, Operand(FIRST_JS_OBJECT_TYPE));
+ cmp(scratch, Operand(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
b(lt, fail);
- cmp(scratch, Operand(LAST_JS_OBJECT_TYPE));
+ cmp(scratch, Operand(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
b(gt, fail);
}
// Check that receiver is a JSObject.
__ ldrb(scratch0, FieldMemOperand(map, Map::kInstanceTypeOffset));
- __ cmp(scratch0, Operand(FIRST_JS_OBJECT_TYPE));
+ __ cmp(scratch0, Operand(FIRST_SPEC_OBJECT_TYPE));
__ b(lt, miss_label);
// Load properties array.
void Genesis::InstallExperimentalNativeFunctions() {
if (FLAG_harmony_proxies) {
INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
+ INSTALL_NATIVE(JSFunction, "DerivedSetTrap", derived_set_trap);
}
}
V(MAP_CACHE_INDEX, Object, map_cache) \
V(CONTEXT_DATA_INDEX, Object, data) \
V(ALLOW_CODE_GEN_FROM_STRINGS_INDEX, Object, allow_code_gen_from_strings) \
- V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap)
+ V(DERIVED_GET_TRAP_INDEX, JSFunction, derived_get_trap) \
+ V(DERIVED_SET_TRAP_INDEX, JSFunction, derived_set_trap)
// JSFunctions are pairs (context, function code), sometimes also called
// closures. A Context object is used to represent function contexts and
CONTEXT_DATA_INDEX,
ALLOW_CODE_GEN_FROM_STRINGS_INDEX,
DERIVED_GET_TRAP_INDEX,
+ DERIVED_SET_TRAP_INDEX,
// Properties from here are treated as weak references by the full GC.
// Scavenge treats them as strong references.
}
-Handle<Object> SetProperty(Handle<JSObject> object,
+Handle<Object> SetProperty(Handle<JSReceiver> object,
Handle<String> key,
Handle<Object> value,
PropertyAttributes attributes,
}
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
const char* name) {
Isolate* isolate = obj->GetIsolate();
Handle<String> str = isolate->factory()->LookupAsciiSymbol(name);
}
-Handle<Object> GetProperty(Handle<Object> obj,
- const char* name,
- LookupResult* result) {
- Isolate* isolate = Isolate::Current();
- Handle<String> str = isolate->factory()->LookupAsciiSymbol(name);
- PropertyAttributes attributes;
- CALL_HEAP_FUNCTION(
- isolate, obj->GetProperty(*obj, result, *str, &attributes), Object);
-}
-
-
Handle<Object> GetProperty(Handle<Object> obj,
Handle<Object> key) {
Isolate* isolate = Isolate::Current();
}
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
Handle<String> name,
LookupResult* result) {
PropertyAttributes attributes;
// string.
Handle<String> FlattenGetString(Handle<String> str);
-Handle<Object> SetProperty(Handle<JSObject> object,
+Handle<Object> SetProperty(Handle<JSReceiver> object,
Handle<String> key,
Handle<Object> value,
PropertyAttributes attributes,
Handle<Object> value,
StrictModeFlag strict_mode);
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
const char* name);
-Handle<Object> GetProperty(Handle<Object> obj,
- const char* name,
- LookupResult* result);
-
Handle<Object> GetProperty(Handle<Object> obj,
Handle<Object> key);
-Handle<Object> GetProperty(Handle<JSObject> obj,
+Handle<Object> GetProperty(Handle<JSReceiver> obj,
Handle<String> name,
LookupResult* result);
void HHasInstanceType::PrintDataTo(StringStream* stream) {
value()->PrintNameTo(stream);
switch (from_) {
- case FIRST_JS_OBJECT_TYPE:
+ case FIRST_JS_RECEIVER_TYPE:
if (to_ == LAST_TYPE) stream->Add(" spec_object");
break;
case JS_REGEXP_TYPE:
InstanceType* last) {
ASSERT(is_interval_check());
switch (check_) {
- case IS_JS_OBJECT_OR_JS_FUNCTION:
- STATIC_ASSERT((LAST_JS_OBJECT_TYPE + 1) == JS_FUNCTION_TYPE);
- *first = FIRST_JS_OBJECT_TYPE;
- *last = JS_FUNCTION_TYPE;
+ case IS_SPEC_OBJECT:
+ *first = FIRST_SPEC_OBJECT_TYPE;
+ *last = LAST_SPEC_OBJECT_TYPE;
return;
case IS_JS_ARRAY:
*first = *last = JS_ARRAY_TYPE;
class HCheckInstanceType: public HUnaryOperation {
public:
- static HCheckInstanceType* NewIsJSObjectOrJSFunction(HValue* value) {
- return new HCheckInstanceType(value, IS_JS_OBJECT_OR_JS_FUNCTION);
+ static HCheckInstanceType* NewIsSpecObject(HValue* value) {
+ return new HCheckInstanceType(value, IS_SPEC_OBJECT);
}
static HCheckInstanceType* NewIsJSArray(HValue* value) {
return new HCheckInstanceType(value, IS_JS_ARRAY);
private:
enum Check {
- IS_JS_OBJECT_OR_JS_FUNCTION,
+ IS_SPEC_OBJECT,
IS_JS_ARRAY,
IS_STRING,
IS_SYMBOL,
case Token::EQ:
case Token::EQ_STRICT: {
AddInstruction(new(zone()) HCheckNonSmi(left));
- AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(left));
+ AddInstruction(HCheckInstanceType::NewIsSpecObject(left));
AddInstruction(new(zone()) HCheckNonSmi(right));
- AddInstruction(HCheckInstanceType::NewIsJSObjectOrJSFunction(right));
+ AddInstruction(HCheckInstanceType::NewIsSpecObject(right));
instr = new(zone()) HCompareJSObjectEq(left, right);
break;
}
CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* value = Pop();
HHasInstanceType* result =
- new(zone()) HHasInstanceType(value, FIRST_JS_OBJECT_TYPE, LAST_TYPE);
+ new(zone()) HHasInstanceType(value,
+ FIRST_SPEC_OBJECT_TYPE,
+ LAST_SPEC_OBJECT_TYPE);
ast_context()->ReturnInstruction(result, call->id());
}
__ j(zero, &use_receiver);
// 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.
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+ // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, &exit);
// Throw away the result of the constructor invocation and use the
__ j(equal, &use_global_receiver);
__ cmp(ebx, factory->undefined_value());
__ j(equal, &use_global_receiver);
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- __ CmpObjectType(ebx, FIRST_JS_OBJECT_TYPE, ecx);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+ __ CmpObjectType(ebx, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, &shift_arguments);
__ bind(&convert_to_object);
__ j(equal, &use_global_receiver);
__ cmp(ebx, factory->undefined_value());
__ j(equal, &use_global_receiver);
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- __ CmpObjectType(ebx, FIRST_JS_OBJECT_TYPE, ecx);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+ __ CmpObjectType(ebx, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, &push_receiver);
__ bind(&call_to_object);
__ j(not_zero, &false_result, Label::kNear);
// JavaScript object => true.
- __ CmpInstanceType(edx, FIRST_JS_OBJECT_TYPE);
+ __ CmpInstanceType(edx, FIRST_SPEC_OBJECT_TYPE);
__ j(above_equal, &true_result, Label::kNear);
// String value => false iff empty.
__ j(equal, &heap_number, Label::kNear);
if (cc_ != equal) {
// Call runtime on identical JSObjects. Otherwise return equal.
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, ¬_identical);
}
__ Set(eax, Immediate(Smi::FromInt(EQUAL)));
// Get the type of the first operand.
// If the first object is a JS object, we have done pointer comparison.
Label first_non_object;
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+ STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(below, &first_non_object, Label::kNear);
// Return non-zero (eax is not zero)
__ CmpInstanceType(ecx, ODDBALL_TYPE);
__ j(equal, &return_not_equal);
- __ CmpObjectType(edx, FIRST_JS_OBJECT_TYPE, ecx);
+ __ CmpObjectType(edx, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, &return_not_equal);
// Check for oddballs: true, false, null, undefined.
__ lea(ecx, Operand(eax, edx, times_1, 0));
__ test(ecx, Immediate(kSmiTagMask));
__ j(not_zero, ¬_both_objects, Label::kNear);
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(below, ¬_both_objects, Label::kNear);
- __ CmpObjectType(edx, FIRST_JS_OBJECT_TYPE, ebx);
+ __ CmpObjectType(edx, FIRST_SPEC_OBJECT_TYPE, ebx);
__ j(below, ¬_both_objects, Label::kNear);
// We do not bail out after this point. Both are JSObjects, and
// they are equal if and only if both are undetectable.
Label convert, done_convert;
__ test(eax, Immediate(kSmiTagMask));
__ j(zero, &convert, Label::kNear);
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ecx);
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
__ j(above_equal, &done_convert, Label::kNear);
__ bind(&convert);
__ push(eax);
__ test(ecx, Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, if_false);
__ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset));
- __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
+ __ cmp(ecx, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
__ j(below, if_false);
- __ cmp(ecx, LAST_JS_OBJECT_TYPE);
+ __ cmp(ecx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(below_equal, if_true, if_false, fall_through);
__ test(eax, Immediate(kSmiTagMask));
__ j(equal, if_false);
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, ebx);
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ebx);
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(above_equal, if_true, if_false, fall_through);
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, eax); // Map is now in eax.
+ __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, eax);
+ // Map is now in eax.
__ j(below, &null);
- // 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);
- __ CmpInstanceType(eax, JS_FUNCTION_TYPE);
- __ j(equal, &function);
+ // 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);
+ __ CmpInstanceType(eax, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
+ __ j(above_equal, &function);
// Check if the constructor in the map is a function.
__ mov(eax, FieldOperand(eax, Map::kConstructorOffset));
Split(not_zero, if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->function_symbol())) {
__ JumpIfSmi(eax, if_false);
- __ CmpObjectType(eax, FIRST_FUNCTION_CLASS_TYPE, edx);
+ __ CmpObjectType(eax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, edx);
Split(above_equal, if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->object_symbol())) {
__ JumpIfSmi(eax, if_false);
__ cmp(eax, isolate()->factory()->null_value());
__ j(equal, if_true);
- __ CmpObjectType(eax, FIRST_JS_OBJECT_TYPE, edx);
+ __ CmpObjectType(eax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, edx);
__ j(below, if_false);
- __ CmpInstanceType(edx, FIRST_FUNCTION_CLASS_TYPE);
- __ j(above_equal, if_false);
+ __ CmpInstanceType(edx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ j(above, if_false);
// Check for undetectable objects => false.
__ test_b(FieldOperand(edx, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
// Check that the receiver is a valid JS object.
__ mov(r1, FieldOperand(receiver, HeapObject::kMapOffset));
__ movzx_b(r0, FieldOperand(r1, Map::kInstanceTypeOffset));
- __ cmp(r0, FIRST_JS_OBJECT_TYPE);
+ __ cmp(r0, FIRST_SPEC_OBJECT_TYPE);
__ j(below, miss);
// 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, r0, miss);
__ j(not_zero, &slow);
__ CmpInstanceType(edi, JS_ARRAY_TYPE);
__ j(equal, &array);
- // Check that the object is some kind of JS object.
- __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
+ // Check that the object is some kind of JSObject.
+ __ CmpInstanceType(edi, FIRST_JS_RECEIVER_TYPE);
__ j(below, &slow);
+ __ CmpInstanceType(edi, JS_PROXY_TYPE);
+ __ j(equal, &slow);
+ __ CmpInstanceType(edi, JS_FUNCTION_PROXY_TYPE);
+ __ j(equal, &slow);
// Object case: Check key against length in the elements array.
// eax: value
__ j(not_zero, is_not_object);
__ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset));
- __ cmp(temp2, FIRST_JS_OBJECT_TYPE);
+ __ cmp(temp2, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
__ j(below, is_not_object);
- __ cmp(temp2, LAST_JS_OBJECT_TYPE);
+ __ cmp(temp2, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
return below_equal;
}
ASSERT(!temp.is(temp2)); // But input and temp2 may be the same register.
__ test(input, Immediate(kSmiTagMask));
__ j(zero, is_false);
- __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, temp);
+ __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp);
__ j(below, is_false);
// Map is now in temp.
// Functions have class 'Function'.
- __ CmpInstanceType(temp, JS_FUNCTION_TYPE);
+ __ CmpInstanceType(temp, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
if (class_name->IsEqualTo(CStrVector("Function"))) {
- __ j(equal, is_true);
+ __ j(above_equal, is_true);
} else {
- __ j(equal, is_false);
+ __ j(above_equal, is_false);
}
// Check if the constructor in the map is a function.
__ mov(temp, FieldOperand(temp, Map::kConstructorOffset));
- // 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);
+ // 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);
// Objects with a non-function constructor have class 'Object'.
__ CmpObjectType(temp, JS_FUNCTION_TYPE, temp2);
// The receiver should be a JS object.
__ test(receiver, Immediate(kSmiTagMask));
DeoptimizeIf(equal, instr->environment());
- __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, scratch);
+ __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, scratch);
DeoptimizeIf(below, instr->environment());
__ jmp(&receiver_ok, Label::kNear);
final_branch_condition = not_zero;
} else if (type_name->Equals(heap()->function_symbol())) {
+ STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
__ JumpIfSmi(input, false_label);
- __ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input);
+ __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input);
final_branch_condition = above_equal;
} else if (type_name->Equals(heap()->object_symbol())) {
__ JumpIfSmi(input, false_label);
__ cmp(input, factory()->null_value());
__ j(equal, true_label);
- __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
+ __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
__ j(below, false_label);
- __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
- __ j(above_equal, false_label);
+ __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ j(above, false_label);
// Check for undetectable objects => false.
__ test_b(FieldOperand(input, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
Register scratch,
Label* fail) {
movzx_b(scratch, FieldOperand(map, Map::kInstanceTypeOffset));
- sub(Operand(scratch), Immediate(FIRST_JS_OBJECT_TYPE));
- cmp(scratch, LAST_JS_OBJECT_TYPE - FIRST_JS_OBJECT_TYPE);
+ sub(Operand(scratch), Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
+ cmp(scratch,
+ LAST_NONCALLABLE_SPEC_OBJECT_TYPE - FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
j(above, fail);
}
__ j(not_zero, miss_label);
// Check that receiver is a JSObject.
- __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE);
+ __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
__ j(below, miss_label);
// Load properties array.
}
-static bool LookupForWrite(JSObject* object,
+static bool LookupForWrite(JSReceiver* receiver,
String* name,
LookupResult* lookup) {
- object->LocalLookup(name, lookup);
+ receiver->LocalLookup(name, lookup);
if (!StoreICableLookup(lookup)) {
return false;
}
if (lookup->type() == INTERCEPTOR) {
+ JSObject* object = JSObject::cast(receiver);
if (object->GetNamedInterceptor()->setter()->IsUndefined()) {
object->LocalLookupRealNamedProperty(name, lookup);
return StoreICableLookup(lookup);
return TypeError("non_object_property_store", object, name);
}
- if (!object->IsJSObject()) {
+ if (!object->IsJSReceiver()) {
// The length property of string values is read-only. Throw in strict mode.
if (strict_mode == kStrictMode && object->IsString() &&
name->Equals(isolate()->heap()->length_symbol())) {
return *value;
}
+ // Handle proxies.
+ if (object->IsJSProxy()) {
+ return JSReceiver::cast(*object)->
+ SetProperty(*name, *value, NONE, strict_mode);
+ }
+
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
// Check if the given name is an array index.
// Use specialized code for setting the length of arrays.
if (receiver->IsJSArray()
&& name->Equals(isolate()->heap()->length_symbol())
- && receiver->AllowsSetElementsLength()) {
+ && JSArray::cast(*receiver)->AllowsSetElementsLength()) {
#ifdef DEBUG
if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
#endif
// When map collection is enabled we have to mark through map's transitions
// in a special way to make transition links weak.
- // Only maps with instance types between FIRST_JS_OBJECT_TYPE and
- // JS_FUNCTION_TYPE can have transitions.
- if (FLAG_collect_maps &&
- map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
- map->instance_type() <= JS_FUNCTION_TYPE) {
+ // Only maps for subclasses of JSReceiver can have transitions.
+ STATIC_ASSERT(LAST_TYPE == LAST_JS_RECEIVER_TYPE);
+ if (FLAG_collect_maps && map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
MarkMapContents(map);
} else {
marking_stack_.Push(map);
next_object != NULL; next_object = iterator.next()) {
if (next_object->IsMap()) { // Could also be ByteArray on free list.
Map* map = Map::cast(next_object);
- if (map->instance_type() >= FIRST_JS_OBJECT_TYPE &&
- map->instance_type() <= JS_FUNCTION_TYPE) {
+ STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+ if (map->instance_type() >= FIRST_JS_RECEIVER_TYPE) {
map->CreateBackPointers();
} else {
ASSERT(map->instance_descriptors() == heap()->empty_descriptor_array());
ASSERT(SafeIsMap(map));
// Only JSObject and subtypes have map transitions and back pointers.
- if (map->instance_type() < FIRST_JS_OBJECT_TYPE) continue;
- if (map->instance_type() > JS_FUNCTION_TYPE) continue;
+ STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
+ if (map->instance_type() < FIRST_JS_RECEIVER_TYPE) continue;
if (map->IsMarked() && map->attached_to_shared_function_info()) {
// This map is used for inobject slack tracking and has been detached
}
+bool Object::IsJSReceiver() {
+ return IsHeapObject() &&
+ HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
+}
+
+
bool Object::IsJSObject() {
- return IsHeapObject()
- && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
+ return IsJSReceiver() && !IsJSProxy();
+}
+
+
+bool Object::IsJSProxy() {
+ return Object::IsHeapObject() &&
+ (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
+ HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
+}
+
+
+bool Object::IsJSFunctionProxy() {
+ return Object::IsHeapObject() &&
+ HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
}
}
-bool Object::IsJSProxy() {
- return Object::IsHeapObject()
- && HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE;
-}
-
-
bool Object::IsForeign() {
return Object::IsHeapObject()
&& HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
CAST_ACCESSOR(ExternalString)
CAST_ACCESSOR(ExternalAsciiString)
CAST_ACCESSOR(ExternalTwoByteString)
+CAST_ACCESSOR(JSReceiver)
CAST_ACCESSOR(JSObject)
CAST_ACCESSOR(Smi)
CAST_ACCESSOR(HeapObject)
CAST_ACCESSOR(JSArray)
CAST_ACCESSOR(JSRegExp)
CAST_ACCESSOR(JSProxy)
+CAST_ACCESSOR(JSFunctionProxy)
CAST_ACCESSOR(Foreign)
CAST_ACCESSOR(ByteArray)
CAST_ACCESSOR(ExternalArray)
}
-Object* JSObject::GetPrototype() {
- return JSObject::cast(this)->map()->prototype();
+Object* JSReceiver::GetPrototype() {
+ return HeapObject::cast(this)->map()->prototype();
}
-PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
+PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
return GetPropertyAttributeWithReceiver(this, key);
}
HeapObject* heap_object = HeapObject::cast(this);
if (heap_object->IsJSObject()) {
return JSObject::cast(this)->Lookup(name, result);
+ } else if (heap_object->IsJSProxy()) {
+ return result->HandlerResult();
}
Context* global_context = Isolate::Current()->context()->global_context();
if (heap_object->IsString()) {
holder = global_context->number_function()->instance_prototype();
} else if (heap_object->IsBoolean()) {
holder = global_context->boolean_function()->instance_prototype();
- } else if (heap_object->IsJSProxy()) {
- return result->HandlerResult();
}
}
ASSERT(holder != NULL); // Cannot handle null or undefined.
Handle<Object> handler(handler_raw);
// Extract trap function.
- LookupResult lookup;
- Handle<Object> trap(v8::internal::GetProperty(handler, "get", &lookup));
- if (!lookup.IsFound()) {
+ Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("get");
+ Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+ if (trap->IsUndefined()) {
// Get the derived `get' property.
trap = isolate->derived_get_trap();
}
}
-String* JSObject::class_name() {
- if (IsJSFunction()) {
+String* JSReceiver::class_name() {
+ if (IsJSFunction() && IsJSFunctionProxy()) {
return GetHeap()->function_class_symbol();
}
if (map()->constructor()->IsJSFunction()) {
}
-String* JSObject::constructor_name() {
+String* JSReceiver::constructor_name() {
if (map()->constructor()->IsJSFunction()) {
JSFunction* constructor = JSFunction::cast(map()->constructor());
String* name = String::cast(constructor->shared()->name());
Object* proto = GetPrototype();
if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
}
+ // TODO(rossberg): what about proxies?
// If the constructor is not present, return "Object".
return GetHeap()->Object_symbol();
}
}
-MaybeObject* JSObject::SetProperty(String* name,
- Object* value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode) {
+MaybeObject* JSReceiver::SetProperty(String* name,
+ Object* value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
LookupResult result;
LocalLookup(name, &result);
return SetProperty(&result, name, value, attributes, strict_mode);
}
-MaybeObject* JSObject::SetProperty(LookupResult* result,
+MaybeObject* JSReceiver::SetProperty(LookupResult* result,
+ String* key,
+ Object* value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
+ if (result->IsFound() && result->type() == HANDLER) {
+ return JSProxy::cast(this)->SetPropertyWithHandler(
+ key, value, attributes, strict_mode);
+ } else {
+ return JSObject::cast(this)->SetPropertyForResult(
+ result, key, value, attributes, strict_mode);
+ }
+}
+
+
+MUST_USE_RESULT MaybeObject* JSProxy::SetPropertyWithHandler(
+ String* name_raw,
+ Object* value_raw,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode) {
+ Isolate* isolate = GetIsolate();
+ HandleScope scope;
+ Handle<Object> receiver(this);
+ Handle<Object> name(name_raw);
+ Handle<Object> value(value_raw);
+ Handle<Object> handler(this->handler());
+
+ // Extract trap function.
+ Handle<String> trap_name = isolate->factory()->LookupAsciiSymbol("set");
+ Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+ if (trap->IsUndefined()) {
+ trap = isolate->derived_set_trap();
+ }
+
+ // Call trap function.
+ Object** args[] = {
+ receiver.location(), name.location(), value.location()
+ };
+ bool has_exception;
+ Handle<Object> result =
+ Execution::Call(trap, handler, ARRAY_SIZE(args), args, &has_exception);
+ if (has_exception) return Failure::Exception();
+
+ return value_raw;
+}
+
+
+MUST_USE_RESULT PropertyAttributes JSProxy::GetPropertyAttributeWithHandler(
+ JSReceiver* receiver_raw,
+ String* name_raw,
+ bool* has_exception) {
+ Isolate* isolate = GetIsolate();
+ HandleScope scope;
+ Handle<JSReceiver> receiver(receiver_raw);
+ Handle<Object> name(name_raw);
+ Handle<Object> handler(this->handler());
+
+ // Extract trap function.
+ Handle<String> trap_name =
+ isolate->factory()->LookupAsciiSymbol("getPropertyDescriptor");
+ Handle<Object> trap(v8::internal::GetProperty(handler, trap_name));
+ if (trap->IsUndefined()) {
+ Handle<Object> args[] = { handler, trap_name };
+ Handle<Object> error = isolate->factory()->NewTypeError(
+ "handler_trap_missing", HandleVector(args, ARRAY_SIZE(args)));
+ isolate->Throw(*error);
+ *has_exception = true;
+ return NONE;
+ }
+
+ // Call trap function.
+ Object** args[] = { name.location() };
+ Handle<Object> result =
+ Execution::Call(trap, handler, ARRAY_SIZE(args), args, has_exception);
+ if (has_exception) return NONE;
+
+ // TODO(rossberg): convert result to PropertyAttributes
+ USE(result);
+ return NONE;
+}
+
+
+MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
String* name,
Object* value,
PropertyAttributes attributes,
}
-PropertyAttributes JSObject::GetPropertyAttributeWithReceiver(
- JSObject* receiver,
+PropertyAttributes JSReceiver::GetPropertyAttributeWithReceiver(
+ JSReceiver* receiver,
String* key) {
uint32_t index = 0;
- if (key->AsArrayIndex(&index)) {
- if (HasElementWithReceiver(receiver, index)) return NONE;
+ if (IsJSObject() && key->AsArrayIndex(&index)) {
+ if (JSObject::cast(this)->HasElementWithReceiver(receiver, index))
+ return NONE;
return ABSENT;
}
// Named property.
}
-PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver,
- LookupResult* result,
- String* name,
- bool continue_search) {
+PropertyAttributes JSReceiver::GetPropertyAttribute(JSReceiver* receiver,
+ LookupResult* result,
+ String* name,
+ bool continue_search) {
// Check access rights if needed.
if (IsAccessCheckNeeded()) {
+ JSObject* this_obj = JSObject::cast(this);
Heap* heap = GetHeap();
- if (!heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) {
- return GetPropertyAttributeWithFailedAccessCheck(receiver,
- result,
- name,
- continue_search);
+ if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) {
+ return this_obj->GetPropertyAttributeWithFailedAccessCheck(
+ receiver, result, name, continue_search);
}
}
if (result->IsProperty()) {
case CONSTANT_FUNCTION:
case CALLBACKS:
return result->GetAttributes();
+ case HANDLER: {
+ // TODO(rossberg): propagate exceptions properly.
+ bool has_exception = false;
+ return JSProxy::cast(this)->GetPropertyAttributeWithHandler(
+ receiver, name, &has_exception);
+ }
case INTERCEPTOR:
- return result->holder()->
- GetPropertyAttributeWithInterceptor(receiver, name, continue_search);
+ return result->holder()->GetPropertyAttributeWithInterceptor(
+ JSObject::cast(receiver), name, continue_search);
default:
UNREACHABLE();
}
}
-PropertyAttributes JSObject::GetLocalPropertyAttribute(String* name) {
+PropertyAttributes JSReceiver::GetLocalPropertyAttribute(String* name) {
// Check whether the name is an array index.
uint32_t index = 0;
- if (name->AsArrayIndex(&index)) {
- if (HasLocalElement(index)) return NONE;
+ if (IsJSObject() && name->AsArrayIndex(&index)) {
+ if (JSObject::cast(this)->HasLocalElement(index)) return NONE;
return ABSENT;
}
// Named property.
}
+void JSReceiver::LocalLookup(String* name, LookupResult* result) {
+ if (IsJSProxy()) {
+ result->HandlerResult();
+ } else {
+ JSObject::cast(this)->LocalLookup(name, result);
+ }
+}
+
+
void JSObject::LocalLookup(String* name, LookupResult* result) {
ASSERT(name->IsString());
}
-void JSObject::Lookup(String* name, LookupResult* result) {
+void JSReceiver::Lookup(String* name, LookupResult* result) {
// Ecma-262 3rd 8.6.2.4
Heap* heap = GetHeap();
for (Object* current = this;
}
-MaybeObject* JSObject::SetPrototype(Object* value,
- bool skip_hidden_prototypes) {
+MaybeObject* JSReceiver::SetPrototype(Object* value,
+ bool skip_hidden_prototypes) {
Heap* heap = GetHeap();
// Silently ignore the change if value is not a JSObject or null.
// SpiderMonkey behaves this way.
- if (!value->IsJSObject() && !value->IsNull()) return value;
+ if (!value->IsJSReceiver() && !value->IsNull()) return value;
// From 8.6.2 Object Internal Methods
// ...
}
}
- JSObject* real_receiver = this;
+ JSReceiver* real_receiver = this;
if (skip_hidden_prototypes) {
// Find the first object in the chain whose prototype object is not
}
-bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementPostInterceptor(JSReceiver* receiver, uint32_t index) {
switch (GetElementsKind()) {
case FAST_ELEMENTS: {
uint32_t length = IsJSArray() ?
}
-bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementWithInterceptor(JSReceiver* receiver, uint32_t index) {
Isolate* isolate = GetIsolate();
// Make sure that the top context does not change when doing
// callbacks or interceptor calls.
AssertNoContextChange ncc;
HandleScope scope(isolate);
Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
- Handle<JSObject> receiver_handle(receiver);
+ Handle<JSReceiver> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
CustomArguments args(isolate, interceptor->data(), receiver, this);
v8::AccessorInfo info(args.end());
}
-bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) {
+bool JSObject::HasElementWithReceiver(JSReceiver* receiver, uint32_t index) {
// Check access rights if needed.
if (IsAccessCheckNeeded()) {
Heap* heap = GetHeap();
MaybeObject* JSObject::GetPropertyPostInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
MaybeObject* JSObject::GetLocalPropertyPostInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
// Check local property in holder, ignore interceptor.
MaybeObject* JSObject::GetPropertyWithInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes) {
Isolate* isolate = GetIsolate();
InterceptorInfo* interceptor = GetNamedInterceptor();
HandleScope scope(isolate);
- Handle<JSObject> receiver_handle(receiver);
+ Handle<JSReceiver> receiver_handle(receiver);
Handle<JSObject> holder_handle(this);
Handle<String> name_handle(name);
// - Object
// - Smi (immediate small integer)
// - HeapObject (superclass for everything allocated in the heap)
-// - JSObject
-// - JSArray
-// - JSRegExp
-// - JSFunction
-// - GlobalObject
-// - JSGlobalObject
-// - JSBuiltinsObject
-// - JSGlobalProxy
-// - JSValue
-// - JSMessageObject
+// - JSReceiver (suitable for property access)
+// - JSObject
+// - JSArray
+// - JSRegExp
+// - JSFunction
+// - GlobalObject
+// - JSGlobalObject
+// - JSBuiltinsObject
+// - JSGlobalProxy
+// - JSValue
+// - JSMessageObject
+// - JSProxy
+// - JSFunctionProxy
// - ByteArray
// - ExternalArray
// - ExternalPixelArray
// - Code
// - Map
// - Oddball
-// - JSProxy
// - Foreign
// - SharedFunctionInfo
// - Struct
V(JS_GLOBAL_PROPERTY_CELL_TYPE) \
\
V(HEAP_NUMBER_TYPE) \
- V(JS_PROXY_TYPE) \
V(FOREIGN_TYPE) \
V(BYTE_ARRAY_TYPE) \
/* Note: the order of these external array */ \
V(JS_BUILTINS_OBJECT_TYPE) \
V(JS_GLOBAL_PROXY_TYPE) \
V(JS_ARRAY_TYPE) \
+ V(JS_PROXY_TYPE) \
V(JS_REGEXP_TYPE) \
\
V(JS_FUNCTION_TYPE) \
+ V(JS_FUNCTION_PROXY_TYPE) \
#ifdef ENABLE_DEBUGGER_SUPPORT
#define INSTANCE_TYPE_LIST_DEBUGGER(V) \
// objects.
HEAP_NUMBER_TYPE,
FOREIGN_TYPE,
- JS_PROXY_TYPE,
BYTE_ARRAY_TYPE,
EXTERNAL_BYTE_ARRAY_TYPE, // FIRST_EXTERNAL_ARRAY_TYPE
EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE,
JS_MESSAGE_OBJECT_TYPE,
- JS_VALUE_TYPE, // FIRST_JS_OBJECT_TYPE
+ JS_VALUE_TYPE, // FIRST_NON_CALLABLE_OBJECT_TYPE, FIRST_JS_RECEIVER_TYPE
JS_OBJECT_TYPE,
JS_CONTEXT_EXTENSION_OBJECT_TYPE,
JS_GLOBAL_OBJECT_TYPE,
JS_BUILTINS_OBJECT_TYPE,
JS_GLOBAL_PROXY_TYPE,
JS_ARRAY_TYPE,
+ JS_PROXY_TYPE,
- JS_REGEXP_TYPE, // LAST_JS_OBJECT_TYPE
+ JS_REGEXP_TYPE, // LAST_NONCALLABLE_SPEC_OBJECT_TYPE
- JS_FUNCTION_TYPE, // FIRST_FUNCTION_CLASS_TYPE
+ JS_FUNCTION_TYPE, // FIRST_CALLABLE_SPEC_OBJECT_TYPE
+ JS_FUNCTION_PROXY_TYPE, // LAST_CALLABLE_SPEC_OBJECT_TYPE
// Pseudo-types
FIRST_TYPE = 0x0,
- LAST_TYPE = JS_FUNCTION_TYPE,
+ LAST_TYPE = JS_FUNCTION_PROXY_TYPE,
INVALID_TYPE = FIRST_TYPE - 1,
FIRST_NONSTRING_TYPE = MAP_TYPE,
// Boundaries for testing for an external array.
LAST_EXTERNAL_ARRAY_TYPE = EXTERNAL_PIXEL_ARRAY_TYPE,
// Boundary for promotion to old data space/old pointer space.
LAST_DATA_TYPE = FILLER_TYPE,
- // Boundaries for testing the type is a JavaScript "object". Note that
- // function objects are not counted as objects, even though they are
- // implemented as such; only values whose typeof is "object" are included.
- FIRST_JS_OBJECT_TYPE = JS_VALUE_TYPE,
- LAST_JS_OBJECT_TYPE = JS_REGEXP_TYPE,
- // RegExp objects have [[Class]] "function" because they are callable.
- // All types from this type and above are objects with [[Class]] "function".
- FIRST_FUNCTION_CLASS_TYPE = JS_FUNCTION_TYPE
+ // Boundary for objects represented as JSReceiver (i.e. JSObject or JSProxy).
+ // Note that there is no range for JSObject or JSProxy, since their subtypes
+ // are not continuous in this enum! The enum ranges instead reflect the
+ // external class names, where proxies are treated as either ordinary objects,
+ // or functions.
+ FIRST_JS_RECEIVER_TYPE = JS_VALUE_TYPE,
+ LAST_JS_RECEIVER_TYPE = LAST_TYPE,
+ // Boundaries for testing the types for which typeof is "object".
+ FIRST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_VALUE_TYPE,
+ LAST_NONCALLABLE_SPEC_OBJECT_TYPE = JS_REGEXP_TYPE,
+ // Boundaries for testing the types for which typeof is "function".
+ FIRST_CALLABLE_SPEC_OBJECT_TYPE = JS_FUNCTION_TYPE,
+ LAST_CALLABLE_SPEC_OBJECT_TYPE = JS_FUNCTION_PROXY_TYPE,
+ // Boundaries for testing whether the type is a JavaScript object.
+ FIRST_SPEC_OBJECT_TYPE = FIRST_NONCALLABLE_SPEC_OBJECT_TYPE,
+ LAST_SPEC_OBJECT_TYPE = LAST_CALLABLE_SPEC_OBJECT_TYPE
};
static const int kExternalArrayTypeCount = LAST_EXTERNAL_ARRAY_TYPE -
V(ExternalDoubleArray) \
V(ExternalPixelArray) \
V(ByteArray) \
+ V(JSReceiver) \
V(JSObject) \
V(JSContextExtensionObject) \
V(Map) \
V(Boolean) \
V(JSArray) \
V(JSProxy) \
+ V(JSFunctionProxy) \
V(JSRegExp) \
V(HashTable) \
V(Dictionary) \
};
+// JSReceiver includes types on which properties can be defined, i.e.,
+// JSObject and JSProxy.
+class JSReceiver: public HeapObject {
+ public:
+ // Casting.
+ static inline JSReceiver* cast(Object* obj);
+
+ // Can cause GC.
+ MUST_USE_RESULT MaybeObject* SetProperty(String* key,
+ Object* value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode);
+ MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
+ String* key,
+ Object* value,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode);
+
+ // Returns the class name ([[Class]] property in the specification).
+ String* class_name();
+
+ // Returns the constructor name (the name (possibly, inferred name) of the
+ // function that was used to instantiate the object).
+ String* constructor_name();
+
+ inline PropertyAttributes GetPropertyAttribute(String* name);
+ PropertyAttributes GetPropertyAttributeWithReceiver(JSReceiver* receiver,
+ String* name);
+ PropertyAttributes GetLocalPropertyAttribute(String* name);
+
+ // Can cause a GC.
+ bool HasProperty(String* name) {
+ return GetPropertyAttribute(name) != ABSENT;
+ }
+
+ // Can cause a GC.
+ bool HasLocalProperty(String* name) {
+ return GetLocalPropertyAttribute(name) != ABSENT;
+ }
+
+ // Return the object's prototype (might be Heap::null_value()).
+ inline Object* GetPrototype();
+
+ // Set the object's prototype (only JSReceiver and null are allowed).
+ MUST_USE_RESULT MaybeObject* SetPrototype(Object* value,
+ bool skip_hidden_prototypes);
+
+ // Lookup a property. If found, the result is valid and has
+ // detailed information.
+ void LocalLookup(String* name, LookupResult* result);
+ void Lookup(String* name, LookupResult* result);
+
+ private:
+ PropertyAttributes GetPropertyAttribute(JSReceiver* receiver,
+ LookupResult* result,
+ String* name,
+ bool continue_search);
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(JSReceiver);
+};
+
// The JSObject describes real heap allocated JavaScript objects with
// properties.
// Note that the map of JSObject changes during execution to enable inline
// caching.
-class JSObject: public HeapObject {
+class JSObject: public JSReceiver {
public:
enum DeleteMode {
NORMAL_DELETION,
// a dictionary, and it will stay a dictionary.
MUST_USE_RESULT MaybeObject* PrepareSlowElementsForSort(uint32_t limit);
- MUST_USE_RESULT MaybeObject* SetProperty(String* key,
- Object* value,
- PropertyAttributes attributes,
- StrictModeFlag strict_mode);
- MUST_USE_RESULT MaybeObject* SetProperty(LookupResult* result,
+ MUST_USE_RESULT MaybeObject* SetPropertyForResult(LookupResult* result,
String* key,
Object* value,
PropertyAttributes attributes,
MUST_USE_RESULT MaybeObject* DeleteNormalizedProperty(String* name,
DeleteMode mode);
- // Returns the class name ([[Class]] property in the specification).
- String* class_name();
-
- // Returns the constructor name (the name (possibly, inferred name) of the
- // function that was used to instantiate the object).
- String* constructor_name();
-
// Retrieve interceptors.
InterceptorInfo* GetNamedInterceptor();
InterceptorInfo* GetIndexedInterceptor();
- inline PropertyAttributes GetPropertyAttribute(String* name);
- PropertyAttributes GetPropertyAttributeWithReceiver(JSObject* receiver,
- String* name);
- PropertyAttributes GetLocalPropertyAttribute(String* name);
+ // Used from JSReceiver.
+ PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
+ String* name,
+ bool continue_search);
+ PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
+ String* name,
+ bool continue_search);
+ PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
+ Object* receiver,
+ LookupResult* result,
+ String* name,
+ bool continue_search);
MUST_USE_RESULT MaybeObject* DefineAccessor(String* name,
bool is_getter,
String* name,
PropertyAttributes* attributes);
MaybeObject* GetPropertyWithInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes);
MaybeObject* GetPropertyPostInterceptor(
- JSObject* receiver,
+ JSReceiver* receiver,
String* name,
PropertyAttributes* attributes);
- MaybeObject* GetLocalPropertyPostInterceptor(JSObject* receiver,
+ MaybeObject* GetLocalPropertyPostInterceptor(JSReceiver* receiver,
String* name,
PropertyAttributes* attributes);
// been modified since it was created. May give false positives.
bool IsDirty();
- bool HasProperty(String* name) {
- return GetPropertyAttribute(name) != ABSENT;
- }
-
- // Can cause a GC if it hits an interceptor.
- bool HasLocalProperty(String* name) {
- return GetLocalPropertyAttribute(name) != ABSENT;
- }
-
// If the receiver is a JSGlobalProxy this method will return its prototype,
// otherwise the result is the receiver itself.
inline Object* BypassGlobalProxy();
// elements.
bool ShouldConvertToFastElements();
- // Return the object's prototype (might be Heap::null_value()).
- inline Object* GetPrototype();
-
- // Set the object's prototype (only JSObject and null are allowed).
- MUST_USE_RESULT MaybeObject* SetPrototype(Object* value,
- bool skip_hidden_prototypes);
-
// Tells whether the index'th element is present.
inline bool HasElement(uint32_t index);
- bool HasElementWithReceiver(JSObject* receiver, uint32_t index);
+ bool HasElementWithReceiver(JSReceiver* receiver, uint32_t index);
// Computes the new capacity when expanding the elements of a JSObject.
static int NewElementsCapacity(int old_capacity) {
LocalElementType HasLocalElement(uint32_t index);
- bool HasElementWithInterceptor(JSObject* receiver, uint32_t index);
- bool HasElementPostInterceptor(JSObject* receiver, uint32_t index);
+ bool HasElementWithInterceptor(JSReceiver* receiver, uint32_t index);
+ bool HasElementPostInterceptor(JSReceiver* receiver, uint32_t index);
MUST_USE_RESULT MaybeObject* SetFastElement(uint32_t index,
Object* value,
// Lookup a property. If found, the result is valid and has
// detailed information.
void LocalLookup(String* name, LookupResult* result);
- void Lookup(String* name, LookupResult* result);
// The following lookup functions skip interceptors.
void LocalLookupRealNamedProperty(String* name, LookupResult* result);
DeleteMode mode);
MUST_USE_RESULT MaybeObject* DeleteElementWithInterceptor(uint32_t index);
- PropertyAttributes GetPropertyAttributePostInterceptor(JSObject* receiver,
- String* name,
- bool continue_search);
- PropertyAttributes GetPropertyAttributeWithInterceptor(JSObject* receiver,
- String* name,
- bool continue_search);
- PropertyAttributes GetPropertyAttributeWithFailedAccessCheck(
- Object* receiver,
- LookupResult* result,
- String* name,
- bool continue_search);
- PropertyAttributes GetPropertyAttribute(JSObject* receiver,
- LookupResult* result,
- String* name,
- bool continue_search);
-
// Returns true if most of the elements backing storage is used.
bool HasDenseElements();
// The JSProxy describes EcmaScript Harmony proxies
-class JSProxy: public HeapObject {
+class JSProxy: public JSReceiver {
public:
// [handler]: The handler property.
DECL_ACCESSORS(handler, Object)
// Casting.
static inline JSProxy* cast(Object* obj);
+ MUST_USE_RESULT MaybeObject* SetPropertyWithHandler(
+ String* name_raw,
+ Object* value_raw,
+ PropertyAttributes attributes,
+ StrictModeFlag strict_mode);
+
+ MUST_USE_RESULT PropertyAttributes GetPropertyAttributeWithHandler(
+ JSReceiver* receiver,
+ String* name_raw,
+ bool* has_exception);
+
// Dispatched behavior.
#ifdef OBJECT_PRINT
inline void JSProxyPrint() {
};
+// TODO(rossberg): Only a stub for now.
+class JSFunctionProxy: public JSProxy {
+ public:
+ // Casting.
+ static inline JSFunctionProxy* cast(Object* obj);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy);
+};
+
// Foreign describes objects pointing from JavaScript to C structures.
// Since they cannot contain references to JS HeapObjects they can be
}
$Proxy.create = function(handler, proto) {
+ if (!IS_SPEC_OBJECT(handler)) throw TypeError
if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
return %CreateJSProxy(handler, proto)
}
function DerivedGetTrap(receiver, name) {
var desc = this.getPropertyDescriptor(name)
- if (IS_UNDEFINED(desc)) { return desc; }
+ if (IS_UNDEFINED(desc)) { return desc }
if ('value' in desc) {
return desc.value
} else {
- if (IS_UNDEFINED(desc.get)) { return desc.get; }
- return desc.get.call(receiver) // The proposal says so...
+ if (IS_UNDEFINED(desc.get)) { return desc.get }
+ // The proposal says: desc.get.call(receiver)
+ return %_CallFunction(receiver, desc.get)
}
}
+
+function DerivedSetTrap(receiver, name, val) {
+ var desc = this.getOwnPropertyDescriptor(name)
+ if (desc) {
+ if ('writable' in desc) {
+ if (desc.writable) {
+ desc.value = val
+ this.defineProperty(name, desc)
+ return true
+ } else {
+ return false
+ }
+ } else { // accessor
+ if (desc.set) {
+ // The proposal says: desc.set.call(receiver, val)
+ %_CallFunction(receiver, val, desc.set)
+ return true
+ } else {
+ return false
+ }
+ }
+ }
+ desc = this.getPropertyDescriptor(name)
+ if (desc) {
+ if ('writable' in desc) {
+ if (desc.writable) {
+ // fall through
+ } else {
+ return false
+ }
+ } else { // accessor
+ if (desc.set) {
+ // The proposal says: desc.set.call(receiver, val)
+ %_CallFunction(receiver, val, desc.set)
+ return true
+ } else {
+ return false
+ }
+ }
+ }
+ this.defineProperty(name, {
+ value: val,
+ writable: true,
+ enumerable: true,
+ configurable: true});
+ return true;
+}
if (name->AsArrayIndex(&index)) {
return GetElementOrCharAt(isolate, object, index);
} else {
- PropertyAttributes attr;
- return object->GetProperty(*name, &attr);
+ return object->GetProperty(*name);
}
}
__ JumpIfSmi(rax, &use_receiver);
// 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.
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+ // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, &exit);
// Throw away the result of the constructor invocation and use the
__ CompareRoot(rbx, Heap::kUndefinedValueRootIndex);
__ j(equal, &use_global_receiver);
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, rcx);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+ __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, &shift_arguments);
__ bind(&convert_to_object);
// If given receiver is already a JavaScript object then there's no
// reason for converting it.
- STATIC_ASSERT(LAST_JS_OBJECT_TYPE + 1 == LAST_TYPE);
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
- __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, rcx);
+ STATIC_ASSERT(LAST_SPEC_OBJECT_TYPE == LAST_TYPE);
+ __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, &push_receiver);
// Convert the receiver to an object.
__ j(not_zero, &false_result, Label::kNear);
// JavaScript object => true.
- __ cmpq(rcx, Immediate(FIRST_JS_OBJECT_TYPE));
+ __ cmpq(rcx, Immediate(FIRST_SPEC_OBJECT_TYPE));
__ j(above_equal, &true_result, Label::kNear);
// String value => false iff empty.
factory->heap_number_map());
__ j(equal, &heap_number, Label::kNear);
if (cc_ != equal) {
- // Call runtime on identical JSObjects. Otherwise return equal.
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+ // Call runtime on identical objects. Otherwise return equal.
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, ¬_identical, Label::kNear);
}
__ Set(rax, EQUAL);
// There is no test for undetectability in strict equality.
// If the first object is a JS object, we have done pointer comparison.
- STATIC_ASSERT(LAST_TYPE == JS_FUNCTION_TYPE);
+ STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
Label first_non_object;
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(below, &first_non_object, Label::kNear);
// Return non-zero (eax (not rax) is not zero)
Label return_not_equal;
__ CmpInstanceType(rcx, ODDBALL_TYPE);
__ j(equal, &return_not_equal);
- __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
+ __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, &return_not_equal);
// Check for oddballs: true, false, null, undefined.
__ lea(rcx, Operand(rax, rdx, times_1, 0));
__ testb(rcx, Immediate(kSmiTagMask));
__ j(not_zero, ¬_both_objects, Label::kNear);
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rbx);
__ j(below, ¬_both_objects, Label::kNear);
- __ CmpObjectType(rdx, FIRST_JS_OBJECT_TYPE, rcx);
+ __ CmpObjectType(rdx, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(below, ¬_both_objects, Label::kNear);
__ testb(FieldOperand(rbx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
__ JumpIfSmi(rax, &slow);
// Check that the left hand is a JS object. Leave its map in rax.
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax);
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax);
__ j(below, &slow);
- __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE);
+ __ CmpInstanceType(rax, LAST_SPEC_OBJECT_TYPE);
__ j(above, &slow);
// Get the prototype of the function.
// Check that the function prototype is a JS object.
__ JumpIfSmi(rbx, &slow);
- __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister);
+ __ CmpObjectType(rbx, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
__ j(below, &slow);
- __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
+ __ CmpInstanceType(kScratchRegister, LAST_SPEC_OBJECT_TYPE);
__ j(above, &slow);
// Register mapping:
// Convert the object to a JS object.
Label convert, done_convert;
__ JumpIfSmi(rax, &convert);
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx);
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rcx);
__ j(above_equal, &done_convert);
__ bind(&convert);
__ push(rax);
Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, if_false);
__ movzxbq(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
- __ cmpq(rbx, Immediate(FIRST_JS_OBJECT_TYPE));
+ __ cmpq(rbx, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
__ j(below, if_false);
- __ cmpq(rbx, Immediate(LAST_JS_OBJECT_TYPE));
+ __ cmpq(rbx, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(below_equal, if_true, if_false, fall_through);
&if_true, &if_false, &fall_through);
__ JumpIfSmi(rax, if_false);
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rbx);
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rbx);
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(above_equal, if_true, if_false, fall_through);
// Check that the object is a JS object but take special care of JS
// functions to make sure they have 'Function' as their class.
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax); // Map is now in rax.
+ __ CmpObjectType(rax, FIRST_SPEC_OBJECT_TYPE, rax);
+ // Map is now in rax.
__ j(below, &null);
- // 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);
- __ CmpInstanceType(rax, JS_FUNCTION_TYPE);
- __ j(equal, &function);
+ // 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);
+ __ CmpInstanceType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
+ __ j(above_equal, &function);
// Check if the constructor in the map is a function.
__ movq(rax, FieldOperand(rax, Map::kConstructorOffset));
Split(not_zero, if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->function_symbol())) {
__ JumpIfSmi(rax, if_false);
- __ CmpObjectType(rax, FIRST_FUNCTION_CLASS_TYPE, rdx);
+ STATIC_ASSERT(LAST_CALLABLE_SPEC_OBJECT_TYPE == LAST_TYPE);
+ __ CmpObjectType(rax, FIRST_CALLABLE_SPEC_OBJECT_TYPE, rdx);
Split(above_equal, if_true, if_false, fall_through);
} else if (check->Equals(isolate()->heap()->object_symbol())) {
__ JumpIfSmi(rax, if_false);
__ CompareRoot(rax, Heap::kNullValueRootIndex);
__ j(equal, if_true);
- __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rdx);
+ __ CmpObjectType(rax, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, rdx);
__ j(below, if_false);
- __ CmpInstanceType(rdx, FIRST_FUNCTION_CLASS_TYPE);
- __ j(above_equal, if_false);
+ __ CmpInstanceType(rdx, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ j(above, if_false);
// Check for undetectable objects => false.
__ testb(FieldOperand(rdx, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
// Check that the receiver is a valid JS object.
__ movq(r1, FieldOperand(receiver, HeapObject::kMapOffset));
__ movb(r0, FieldOperand(r1, Map::kInstanceTypeOffset));
- __ cmpb(r0, Immediate(FIRST_JS_OBJECT_TYPE));
+ __ cmpb(r0, Immediate(FIRST_SPEC_OBJECT_TYPE));
__ j(below, miss);
// 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, r0, miss);
__ CmpInstanceType(rbx, JS_ARRAY_TYPE);
__ j(equal, &array);
- // Check that the object is some kind of JS object.
- __ CmpInstanceType(rbx, FIRST_JS_OBJECT_TYPE);
+ // Check that the object is some kind of JSObject.
+ __ CmpInstanceType(rbx, FIRST_JS_RECEIVER_TYPE);
__ j(below, &slow);
+ __ CmpInstanceType(rbx, JS_PROXY_TYPE);
+ __ j(equal, &slow);
+ __ CmpInstanceType(rbx, JS_FUNCTION_PROXY_TYPE);
+ __ j(equal, &slow);
// Object case: Check key against length in the elements array.
// rax: value
__ movzxbl(kScratchRegister,
FieldOperand(kScratchRegister, Map::kInstanceTypeOffset));
- __ cmpb(kScratchRegister, Immediate(FIRST_JS_OBJECT_TYPE));
+ __ cmpb(kScratchRegister, Immediate(FIRST_NONCALLABLE_SPEC_OBJECT_TYPE));
__ j(below, is_not_object);
- __ cmpb(kScratchRegister, Immediate(LAST_JS_OBJECT_TYPE));
+ __ cmpb(kScratchRegister, Immediate(LAST_NONCALLABLE_SPEC_OBJECT_TYPE));
return below_equal;
}
Register input,
Register temp) {
__ JumpIfSmi(input, is_false);
- __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, temp);
+ __ CmpObjectType(input, FIRST_SPEC_OBJECT_TYPE, temp);
__ j(below, is_false);
// Map is now in temp.
// Functions have class 'Function'.
- __ CmpInstanceType(temp, JS_FUNCTION_TYPE);
+ __ CmpInstanceType(temp, FIRST_CALLABLE_SPEC_OBJECT_TYPE);
if (class_name->IsEqualTo(CStrVector("Function"))) {
- __ j(equal, is_true);
+ __ j(above_equal, is_true);
} else {
- __ j(equal, is_false);
+ __ j(above_equal, is_false);
}
// Check if the constructor in the map is a function.
__ movq(temp, FieldOperand(temp, Map::kConstructorOffset));
- // 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);
+ // As long as LAST_CALLABLE_SPEC_OBJECT_TYPE is the last 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);
// Objects with a non-function constructor have class 'Object'.
__ CmpObjectType(temp, JS_FUNCTION_TYPE, kScratchRegister);
// The receiver should be a JS object.
Condition is_smi = __ CheckSmi(receiver);
DeoptimizeIf(is_smi, instr->environment());
- __ CmpObjectType(receiver, FIRST_JS_OBJECT_TYPE, kScratchRegister);
+ __ CmpObjectType(receiver, FIRST_SPEC_OBJECT_TYPE, kScratchRegister);
DeoptimizeIf(below, instr->environment());
__ jmp(&receiver_ok, Label::kNear);
} else if (type_name->Equals(heap()->function_symbol())) {
__ JumpIfSmi(input, false_label);
- __ CmpObjectType(input, FIRST_FUNCTION_CLASS_TYPE, input);
+ __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input);
final_branch_condition = above_equal;
} else if (type_name->Equals(heap()->object_symbol())) {
__ JumpIfSmi(input, false_label);
__ CompareRoot(input, Heap::kNullValueRootIndex);
__ j(equal, true_label);
- __ CmpObjectType(input, FIRST_JS_OBJECT_TYPE, input);
+ __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
__ j(below, false_label);
- __ CmpInstanceType(input, FIRST_FUNCTION_CLASS_TYPE);
- __ j(above_equal, false_label);
+ __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
+ __ j(above, false_label);
// Check for undetectable objects => false.
__ testb(FieldOperand(input, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, miss_label);
// Check that receiver is a JSObject.
- __ CmpInstanceType(r0, FIRST_JS_OBJECT_TYPE);
+ __ CmpInstanceType(r0, FIRST_SPEC_OBJECT_TYPE);
__ j(below, miss_label);
// Load properties array.
--- /dev/null
+// Flags: --harmony-proxies
+
+// Copyright 2008 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+
+// Getters.
+
+function TestGet(handler) {
+ var o = Proxy.create(handler)
+ assertEquals(42, o.a)
+ assertEquals(42, o["b"])
+// assertEquals(Object.getOwnPropertyDescriptor(o, "b").value, 42)
+}
+
+TestGet({get: function(r, k) { return 42 }})
+TestGet({getPropertyDescriptor: function(k) { return {value: 42} }})
+TestGet({getPropertyDescriptor: function(k) { return {get value() { return 42 }} }})
+TestGet({get: undefined, getPropertyDescriptor: function(k) { return {value: 42} }})
+
+TestGet(Proxy.create({get: function(pr, pk) { return function(r, k) { return 42 } }}))
+
+
+
+// Setters.
+
+var key
+var val
+function TestSet(handler) {
+ var o = Proxy.create(handler)
+ assertEquals(42, o.a = 42)
+ assertEquals("a", key)
+ assertEquals(42, val)
+ assertEquals(43, o["b"] = 43)
+ assertEquals("b", key)
+ assertEquals(43, val)
+// assertTrue(Object.defineProperty(o, "c", {value: 44}))
+// assertEquals("c", key)
+// assertEquals(44, val)
+}
+
+TestSet({set: function(r, k, v) { key = k; val = v; return true }})
+TestSet({getOwnPropertyDescriptor: function(k) { return {writable: true} },
+ defineProperty: function(k, desc) { key = k, val = desc.value }})
+TestSet({getOwnPropertyDescriptor: function(k) { return {get writable() { return true }} },
+ defineProperty: function(k, desc) { key = k, val = desc.value }})
+TestSet({getOwnPropertyDescriptor: function(k) { return {set: function(v) { key = k, val = v }} }})
+TestSet({getOwnPropertyDescriptor: function(k) { return null },
+ getPropertyDescriptor: function(k) { return {writable: true} },
+ defineProperty: function(k, desc) { key = k, val = desc.value }})
+TestSet({getOwnPropertyDescriptor: function(k) { return null },
+ getPropertyDescriptor: function(k) { return {get writable() { return true }} },
+ defineProperty: function(k, desc) { key = k, val = desc.value }})
+TestSet({getOwnPropertyDescriptor: function(k) { return null },
+ getPropertyDescriptor: function(k) { return {set: function(v) { key = k, val = v }} }})
+TestSet({getOwnPropertyDescriptor: function(k) { return null },
+ getPropertyDescriptor: function(k) { return null },
+ defineProperty: function(k, desc) { key = k, val = desc.value }})
+
+TestSet(Proxy.create({get: function(pr, pk) { return function(r, k, v) { key = k; val = v; return true } }}))
+
+
+
+// Comparison.
+
+var o1 = Proxy.create({})
+var o2 = Proxy.create({})
+
+assertTrue(o1 == o1)
+assertTrue(o2 == o2)
+assertTrue(!(o1 == o2))
+assertTrue(!(o1 == {}))
+assertTrue(!({} == o2))
+assertTrue(!({} == {}))
+
+assertTrue(o1 === o1)
+assertTrue(o2 === o2)
+assertTrue(!(o1 === o2))
+assertTrue(!(o1 === {}))
+assertTrue(!({} === o2))
+assertTrue(!({} === {}))
+
+
+
+// Type.
+
+assertEquals("object", typeof Proxy.create({}))
+assertTrue(typeof Proxy.create({}) == "object")
+assertTrue("object" == typeof Proxy.create({}))
+
+// No function proxies yet.
third_party = [current_path + ['third_party', t] for t in self.Ls(join(self.root, 'third_party'))]
tools = [current_path + ['tools', t] for t in self.Ls(join(self.root, 'tools'))]
compiler = [current_path + ['compiler', t] for t in self.Ls(join(self.root, 'compiler'))]
+ harmony = [current_path + ['harmony', t] for t in self.Ls(join(self.root, 'harmony'))]
mjsunit.sort()
regress.sort()
bugs.sort()
third_party.sort()
tools.sort()
compiler.sort()
- all_tests = mjsunit + regress + bugs + third_party + tools + compiler
+ harmony.sort()
+ all_tests = mjsunit + regress + bugs + third_party + tools + compiler + harmony
result = []
for test in all_tests:
if self.Contains(path, test):
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-// The type of a regular expression should be 'function', including in
+// The type of a regular expression should be 'object', including in
// the context of string equality comparisons.
var r = new RegExp;
function test(x, y) { return x == y; }
assertTrue(test('object', typeof r));
-
130: "ODDBALL_TYPE",
131: "JS_GLOBAL_PROPERTY_CELL_TYPE",
132: "HEAP_NUMBER_TYPE",
- 134: "JS_PROXY_TYPE",
133: "FOREIGN_TYPE",
- 135: "BYTE_ARRAY_TYPE",
- 136: "EXTERNAL_BYTE_ARRAY_TYPE",
- 137: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE",
- 138: "EXTERNAL_SHORT_ARRAY_TYPE",
- 139: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE",
- 140: "EXTERNAL_INT_ARRAY_TYPE",
- 141: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE",
- 142: "EXTERNAL_FLOAT_ARRAY_TYPE",
- 144: "EXTERNAL_PIXEL_ARRAY_TYPE",
- 145: "FILLER_TYPE",
- 146: "ACCESSOR_INFO_TYPE",
- 147: "ACCESS_CHECK_INFO_TYPE",
- 148: "INTERCEPTOR_INFO_TYPE",
- 149: "CALL_HANDLER_INFO_TYPE",
- 150: "FUNCTION_TEMPLATE_INFO_TYPE",
- 151: "OBJECT_TEMPLATE_INFO_TYPE",
- 152: "SIGNATURE_INFO_TYPE",
- 153: "TYPE_SWITCH_INFO_TYPE",
- 154: "SCRIPT_TYPE",
- 155: "CODE_CACHE_TYPE",
- 158: "FIXED_ARRAY_TYPE",
- 159: "SHARED_FUNCTION_INFO_TYPE",
- 160: "JS_MESSAGE_OBJECT_TYPE",
- 161: "JS_VALUE_TYPE",
- 162: "JS_OBJECT_TYPE",
- 163: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
- 164: "JS_GLOBAL_OBJECT_TYPE",
- 165: "JS_BUILTINS_OBJECT_TYPE",
- 166: "JS_GLOBAL_PROXY_TYPE",
- 167: "JS_ARRAY_TYPE",
+ 134: "BYTE_ARRAY_TYPE",
+ 135: "EXTERNAL_BYTE_ARRAY_TYPE",
+ 136: "EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE",
+ 137: "EXTERNAL_SHORT_ARRAY_TYPE",
+ 138: "EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE",
+ 139: "EXTERNAL_INT_ARRAY_TYPE",
+ 140: "EXTERNAL_UNSIGNED_INT_ARRAY_TYPE",
+ 141: "EXTERNAL_FLOAT_ARRAY_TYPE",
+ 142: "EXTERNAL_DOUBLE_ARRAY_TYPE",
+ 143: "EXTERNAL_PIXEL_ARRAY_TYPE",
+ 144: "FILLER_TYPE",
+ 145: "ACCESSOR_INFO_TYPE",
+ 146: "ACCESS_CHECK_INFO_TYPE",
+ 147: "INTERCEPTOR_INFO_TYPE",
+ 148: "CALL_HANDLER_INFO_TYPE",
+ 149: "FUNCTION_TEMPLATE_INFO_TYPE",
+ 150: "OBJECT_TEMPLATE_INFO_TYPE",
+ 151: "SIGNATURE_INFO_TYPE",
+ 152: "TYPE_SWITCH_INFO_TYPE",
+ 153: "SCRIPT_TYPE",
+ 154: "CODE_CACHE_TYPE",
+ 155: "DEBUG_INFO_TYPE",
+ 156: "BREAK_POINT_INFO_TYPE",
+ 157: "FIXED_ARRAY_TYPE",
+ 158: "SHARED_FUNCTION_INFO_TYPE",
+ 159: "JS_MESSAGE_OBJECT_TYPE",
+ 160: "JS_VALUE_TYPE",
+ 161: "JS_OBJECT_TYPE",
+ 162: "JS_CONTEXT_EXTENSION_OBJECT_TYPE",
+ 163: "JS_GLOBAL_OBJECT_TYPE",
+ 164: "JS_BUILTINS_OBJECT_TYPE",
+ 165: "JS_GLOBAL_PROXY_TYPE",
+ 166: "JS_ARRAY_TYPE",
+ 167: "JS_PROXY_TYPE",
168: "JS_REGEXP_TYPE",
169: "JS_FUNCTION_TYPE",
- 156: "DEBUG_INFO_TYPE",
- 157: "BREAK_POINT_INFO_TYPE",
+ 170: "JS_FUNCTION_PROXY_TYPE",
}