__ ldr(r0, MemOperand(sp));
__ push(r0);
VisitForStackValue(key);
- __ mov(r1, Operand(property->kind() == ObjectLiteral::Property::SETTER ?
- Smi::FromInt(1) :
- Smi::FromInt(0)));
- __ push(r1);
- VisitForStackValue(value);
+ if (property->kind() == ObjectLiteral::Property::GETTER) {
+ VisitForStackValue(value);
+ __ LoadRoot(r1, Heap::kNullValueRootIndex);
+ __ push(r1);
+ } else {
+ __ LoadRoot(r1, Heap::kNullValueRootIndex);
+ __ push(r1);
+ VisitForStackValue(value);
+ }
__ mov(r0, Operand(Smi::FromInt(NONE)));
__ push(r0);
__ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5);
case ObjectLiteral::Property::GETTER:
__ push(Operand(esp, 0)); // Duplicate receiver.
VisitForStackValue(key);
- __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ?
- Smi::FromInt(1) :
- Smi::FromInt(0)));
- VisitForStackValue(value);
+ if (property->kind() == ObjectLiteral::Property::GETTER) {
+ VisitForStackValue(value);
+ __ push(Immediate(isolate()->factory()->null_value()));
+ } else {
+ __ push(Immediate(isolate()->factory()->null_value()));
+ VisitForStackValue(value);
+ }
__ push(Immediate(Smi::FromInt(NONE)));
__ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5);
break;
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
hasBeenSet = true;
value = v;
};
- %DefineOrRedefineAccessorProperty(obj, name, GETTER, getter, DONT_ENUM);
- %DefineOrRedefineAccessorProperty(obj, name, SETTER, setter, DONT_ENUM);
+ %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
}
function CallSite(receiver, fun, pos) {
__ lw(a0, MemOperand(sp));
__ push(a0);
VisitForStackValue(key);
- __ li(a1, Operand(property->kind() == ObjectLiteral::Property::SETTER ?
- Smi::FromInt(1) :
- Smi::FromInt(0)));
- __ push(a1);
- VisitForStackValue(value);
+ if (property->kind() == ObjectLiteral::Property::GETTER) {
+ VisitForStackValue(value);
+ __ LoadRoot(a1, Heap::kNullValueRootIndex);
+ __ push(a1);
+ } else {
+ __ LoadRoot(a1, Heap::kNullValueRootIndex);
+ __ push(a1);
+ VisitForStackValue(value);
+ }
__ li(a0, Operand(Smi::FromInt(NONE)));
__ push(a0);
__ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5);
class Object : public MaybeObject {
public:
// Type testing.
+ bool IsObject() { return true; }
+
#define IS_TYPE_FUNCTION_DECL(type_) inline bool Is##type_();
OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
HEAP_OBJECT_TYPE_LIST(IS_TYPE_FUNCTION_DECL)
-// Copyright 2006-2009 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
LAST_INPUT(lastMatchInfo) = ToString(string);
};
- %DefineOrRedefineAccessorProperty($RegExp, 'input', GETTER, RegExpGetInput,
- DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'input', SETTER, RegExpSetInput,
- DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$_', GETTER, RegExpGetInput,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$_', SETTER, RegExpSetInput,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$input', GETTER, RegExpGetInput,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$input', SETTER, RegExpSetInput,
- DONT_ENUM | DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, 'input', RegExpGetInput,
+ RegExpSetInput, DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, '$_', RegExpGetInput,
+ RegExpSetInput, DONT_ENUM | DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, '$input', RegExpGetInput,
+ RegExpSetInput, DONT_ENUM | DONT_DELETE);
// The properties multiline and $* are aliases for each other. When this
// value is set in SpiderMonkey, the value it is set to is coerced to a
var RegExpGetMultiline = function() { return multiline; };
var RegExpSetMultiline = function(flag) { multiline = flag ? true : false; };
- %DefineOrRedefineAccessorProperty($RegExp, 'multiline', GETTER,
- RegExpGetMultiline, DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'multiline', SETTER,
+ %DefineOrRedefineAccessorProperty($RegExp, 'multiline', RegExpGetMultiline,
RegExpSetMultiline, DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$*', GETTER, RegExpGetMultiline,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$*', SETTER, RegExpSetMultiline,
+ %DefineOrRedefineAccessorProperty($RegExp, '$*', RegExpGetMultiline,
+ RegExpSetMultiline,
DONT_ENUM | DONT_DELETE);
// Static properties set by a successful match.
- %DefineOrRedefineAccessorProperty($RegExp, 'lastMatch', GETTER,
- RegExpGetLastMatch, DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'lastMatch', SETTER, NoOpSetter,
+ %DefineOrRedefineAccessorProperty($RegExp, 'lastMatch', RegExpGetLastMatch,
+ NoOpSetter, DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, '$&', RegExpGetLastMatch,
+ NoOpSetter, DONT_ENUM | DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, 'lastParen', RegExpGetLastParen,
+ NoOpSetter, DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, '$+', RegExpGetLastParen,
+ NoOpSetter, DONT_ENUM | DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, 'leftContext',
+ RegExpGetLeftContext, NoOpSetter,
DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$&', GETTER, RegExpGetLastMatch,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$&', SETTER, NoOpSetter,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'lastParen', GETTER,
- RegExpGetLastParen, DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'lastParen', SETTER, NoOpSetter,
+ %DefineOrRedefineAccessorProperty($RegExp, '$`', RegExpGetLeftContext,
+ NoOpSetter, DONT_ENUM | DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, 'rightContext',
+ RegExpGetRightContext, NoOpSetter,
DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$+', GETTER, RegExpGetLastParen,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$+', SETTER, NoOpSetter,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'leftContext', GETTER,
- RegExpGetLeftContext, DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'leftContext', SETTER, NoOpSetter,
- DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$`', GETTER, RegExpGetLeftContext,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$`', SETTER, NoOpSetter,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'rightContext', GETTER,
- RegExpGetRightContext, DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, 'rightContext', SETTER, NoOpSetter,
- DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, "$'", GETTER,
- RegExpGetRightContext,
- DONT_ENUM | DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, "$'", SETTER, NoOpSetter,
- DONT_ENUM | DONT_DELETE);
+ %DefineOrRedefineAccessorProperty($RegExp, "$'", RegExpGetRightContext,
+ NoOpSetter, DONT_ENUM | DONT_DELETE);
for (var i = 1; i < 10; ++i) {
- %DefineOrRedefineAccessorProperty($RegExp, '$' + i, GETTER,
- RegExpMakeCaptureGetter(i), DONT_DELETE);
- %DefineOrRedefineAccessorProperty($RegExp, '$' + i, SETTER, NoOpSetter,
+ %DefineOrRedefineAccessorProperty($RegExp, '$' + i,
+ RegExpMakeCaptureGetter(i), NoOpSetter,
DONT_DELETE);
}
}
DESCRIPTOR_SIZE
};
-// Returns an array with the property description:
-// if args[1] is not a property on args[0]
-// returns undefined
-// if args[1] is a data property on args[0]
-// [false, value, Writeable, Enumerable, Configurable]
-// if args[1] is an accessor on args[0]
-// [true, GetFunction, SetFunction, Enumerable, Configurable]
-RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
- ASSERT(args.length() == 2);
+
+static MaybeObject* GetOwnProperty(Isolate* isolate,
+ Handle<JSObject> obj,
+ Handle<String> name) {
Heap* heap = isolate->heap();
- HandleScope scope(isolate);
Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms);
LookupResult result(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
-
// This could be an element.
uint32_t index;
if (name->AsArrayIndex(&index)) {
}
+// Returns an array with the property description:
+// if args[1] is not a property on args[0]
+// returns undefined
+// if args[1] is a data property on args[0]
+// [false, value, Writeable, Enumerable, Configurable]
+// if args[1] is an accessor on args[0]
+// [true, GetFunction, SetFunction, Enumerable, Configurable]
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
+ ASSERT(args.length() == 2);
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+ return GetOwnProperty(isolate, obj, name);
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
ASSERT(args.length() == 1);
CONVERT_ARG_CHECKED(JSObject, obj, 0);
args.at<Object>(1));
}
+
+static bool IsValidAccessor(Handle<Object> obj) {
+ return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
+}
+
+
// Implements part of 8.12.9 DefineOwnProperty.
// There are 3 cases that lead here:
// Step 4b - define a new accessor property.
ASSERT(args.length() == 5);
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_CHECKED(String, name, 1);
- CONVERT_SMI_ARG_CHECKED(flag, 2);
- Object* fun = args[3];
+ RUNTIME_ASSERT(!obj->IsNull());
+ CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
+ RUNTIME_ASSERT(IsValidAccessor(getter));
+ CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
+ RUNTIME_ASSERT(IsValidAccessor(setter));
CONVERT_SMI_ARG_CHECKED(unchecked, 4);
-
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
- RUNTIME_ASSERT(!obj->IsNull());
- RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined());
- AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER;
- return obj->DefineAccessor(name, component, fun, attr);
+ // TODO(svenpanne) Define getter/setter/attributes in a single step.
+ if (getter->IsNull() && setter->IsNull()) {
+ JSArray* array;
+ { MaybeObject* maybe_array = GetOwnProperty(isolate, obj, name);
+ if (!maybe_array->To(&array)) return maybe_array;
+ }
+ Object* current = FixedArray::cast(array->elements())->get(GETTER_INDEX);
+ getter = Handle<Object>(current, isolate);
+ }
+ if (!getter->IsNull()) {
+ MaybeObject* ok =
+ obj->DefineAccessor(*name, ACCESSOR_GETTER, *getter, attr);
+ if (ok->IsFailure()) return ok;
+ }
+ if (!setter->IsNull()) {
+ MaybeObject* ok =
+ obj->DefineAccessor(*name, ACCESSOR_SETTER, *setter, attr);
+ if (ok->IsFailure()) return ok;
+ }
+
+ return isolate->heap()->undefined_value();
}
// Implements part of 8.12.9 DefineOwnProperty.
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
- Handle<Object> obj_value = args.at<Object>(2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
CONVERT_SMI_ARG_CHECKED(unchecked, 3);
-
RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
}
%DefineOrRedefineDataProperty(obj, p, value, flag);
- } else if (IsGenericDescriptor(desc)) {
- // Step 12 - updating an existing accessor property with generic
- // descriptor. Changing flags only.
- %DefineOrRedefineAccessorProperty(obj, p, GETTER, current.getGet(), flag);
} else {
// There are 3 cases that lead here:
// Step 4b - defining a new accessor property.
// property.
// Step 12 - updating an existing accessor property with an accessor
// descriptor.
- if (desc.hasGetter()) {
- %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag);
- }
- if (desc.hasSetter()) {
- %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag);
- }
+ var getter = desc.hasGetter() ? desc.getGet() : null;
+ var setter = desc.hasSetter() ? desc.getSet() : null;
+ %DefineOrRedefineAccessorProperty(obj, p, getter, setter, flag);
}
return true;
}
case ObjectLiteral::Property::GETTER:
__ push(Operand(rsp, 0)); // Duplicate receiver.
VisitForStackValue(key);
- __ Push(property->kind() == ObjectLiteral::Property::SETTER ?
- Smi::FromInt(1) :
- Smi::FromInt(0));
- VisitForStackValue(value);
+ if (property->kind() == ObjectLiteral::Property::GETTER) {
+ VisitForStackValue(value);
+ __ PushRoot(Heap::kNullValueRootIndex);
+ } else {
+ __ PushRoot(Heap::kNullValueRootIndex);
+ VisitForStackValue(value);
+ }
__ Push(Smi::FromInt(NONE));
__ CallRuntime(Runtime::kDefineOrRedefineAccessorProperty, 5);
break;
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2012 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:
// Defining properties null should fail even when we have
// other allowed values
try {
- %DefineOrRedefineAccessorProperty(null, 'foo', 0, func, 0);
+ %DefineOrRedefineAccessorProperty(null, 'foo', func, null, 0);
} catch (e) {
assertTrue(/illegal access/.test(e));
}