| Index: src/v8natives.js | 
| =================================================================== | 
| --- src/v8natives.js	(revision 3785) | 
| +++ src/v8natives.js	(working copy) | 
| @@ -307,7 +307,7 @@ | 
|  | 
| // ES5 8.10.4 | 
| function FromPropertyDescriptor(desc) { | 
| -  if(IS_UNDEFINED(desc)) return desc; | 
| +  if (IS_UNDEFINED(desc)) return desc; | 
| var obj = new $Object(); | 
| if (IsDataDescriptor(desc)) { | 
| obj.value = desc.getValue(); | 
| @@ -333,7 +333,6 @@ | 
| desc.setEnumerable(ToBoolean(obj.enumerable)); | 
| } | 
|  | 
| - | 
| if ("configurable" in obj) { | 
| desc.setConfigurable(ToBoolean(obj.configurable)); | 
| } | 
| @@ -377,7 +376,9 @@ | 
| this.writable_ = false; | 
| this.hasWritable_ = false; | 
| this.enumerable_ = false; | 
| +  this.hasEnumerable_ = false; | 
| this.configurable_ = false; | 
| +  this.hasConfigurable_ = false; | 
| this.get_ = void 0; | 
| this.hasGetter_ = false; | 
| this.set_ = void 0; | 
| @@ -396,8 +397,14 @@ | 
| } | 
|  | 
|  | 
| +PropertyDescriptor.prototype.hasValue = function() { | 
| +  return this.hasValue_; | 
| +} | 
| + | 
| + | 
| PropertyDescriptor.prototype.setEnumerable = function(enumerable) { | 
| this.enumerable_ = enumerable; | 
| +  this.hasEnumerable_ = true; | 
| } | 
|  | 
|  | 
| @@ -406,6 +413,11 @@ | 
| } | 
|  | 
|  | 
| +PropertyDescriptor.prototype.hasEnumerable = function() { | 
| +  return this.hasEnumerable_; | 
| +} | 
| + | 
| + | 
| PropertyDescriptor.prototype.setWritable = function(writable) { | 
| this.writable_ = writable; | 
| this.hasWritable_ = true; | 
| @@ -419,9 +431,15 @@ | 
|  | 
| PropertyDescriptor.prototype.setConfigurable = function(configurable) { | 
| this.configurable_ = configurable; | 
| +  this.hasConfigurable_ = true; | 
| } | 
|  | 
|  | 
| +PropertyDescriptor.prototype.hasConfigurable = function() { | 
| +  return this.hasConfigurable_; | 
| +} | 
| + | 
| + | 
| PropertyDescriptor.prototype.isConfigurable = function() { | 
| return this.configurable_; | 
| } | 
| @@ -438,6 +456,11 @@ | 
| } | 
|  | 
|  | 
| +PropertyDescriptor.prototype.hasGetter = function() { | 
| +  return this.hasGetter_; | 
| +} | 
| + | 
| + | 
| PropertyDescriptor.prototype.setSet = function(set) { | 
| this.set_ = set; | 
| this.hasSetter_ = true; | 
| @@ -449,6 +472,12 @@ | 
| } | 
|  | 
|  | 
| +PropertyDescriptor.prototype.hasSetter = function() { | 
| +  return this.hasSetter_; | 
| +} | 
| + | 
| + | 
| + | 
| // ES5 section 8.12.1. | 
| function GetOwnProperty(obj, p) { | 
| var desc = new PropertyDescriptor(); | 
| @@ -458,8 +487,7 @@ | 
| //  obj is an accessor [true, Get, Set, Enumerable, Configurable] | 
| var props = %GetOwnProperty(ToObject(obj), ToString(p)); | 
|  | 
| -  if (IS_UNDEFINED(props)) | 
| -    return void 0; | 
| +  if (IS_UNDEFINED(props)) return void 0; | 
|  | 
| // This is an accessor | 
| if (props[0]) { | 
| @@ -476,17 +504,90 @@ | 
| } | 
|  | 
|  | 
| -// ES5 8.12.9.  This version cannot cope with the property p already | 
| -// being present on obj. | 
| +// ES5 section 8.12.2. | 
| +function GetProperty(obj, p) { | 
| +  var prop = GetOwnProperty(obj); | 
| +  if (!IS_UNDEFINED(prop)) return prop; | 
| +  var proto = obj.__proto__; | 
| +  if (IS_NULL(proto)) return void 0; | 
| +  return GetProperty(proto, p); | 
| +} | 
| + | 
| + | 
| +// ES5 section 8.12.6 | 
| +function HasProperty(obj, p) { | 
| +  var desc = GetProperty(obj, p); | 
| +  return IS_UNDEFINED(desc) ? false : true; | 
| +} | 
| + | 
| + | 
| +// ES5 8.12.9. | 
| function DefineOwnProperty(obj, p, desc, should_throw) { | 
| -  var flag = desc.isEnumerable() ? 0 : DONT_ENUM; | 
| -  if (IsDataDescriptor(desc)) { | 
| -    flag |= desc.isWritable() ? 0 : (DONT_DELETE | READ_ONLY); | 
| -    %SetProperty(obj, p, desc.getValue(), flag); | 
| +  var current = GetOwnProperty(obj, p); | 
| +  var extensible = %IsExtensible(ToObject(obj)); | 
| + | 
| +  // Error handling according to spec. | 
| +  // Step 3 | 
| +  if (IS_UNDEFINED(current) && !extensible) | 
| +    throw MakeTypeError("define_disallowed", ["defineProperty"]); | 
| + | 
| +  if (!IS_UNDEFINED(current) && !current.isConfigurable()) { | 
| +    // Step 7 | 
| +    if (desc.isConfigurable() ||  desc.isEnumerable() != current.isEnumerable()) | 
| +      throw MakeTypeError("redefine_disallowed", ["defineProperty"]); | 
| +    // Step 9 | 
| +    if (IsDataDescriptor(current) != IsDataDescriptor(desc)) | 
| +      throw MakeTypeError("redefine_disallowed", ["defineProperty"]); | 
| +    // Step 10 | 
| +    if (IsDataDescriptor(current) && IsDataDescriptor(desc)) { | 
| +      if (!current.isWritable() && desc.isWritable()) | 
| +        throw MakeTypeError("redefine_disallowed", ["defineProperty"]); | 
| +      if (!current.isWritable() && desc.hasValue() && | 
| +          !SameValue(desc.getValue(), current.getValue())) { | 
| +        throw MakeTypeError("redefine_disallowed", ["defineProperty"]); | 
| +      } | 
| +    } | 
| +    // Step 11 | 
| +    if (IsAccessorDescriptor(desc) && IsAccessorDescriptor(current)) { | 
| +      if (desc.hasSetter() && !SameValue(desc.getSet(), current.getSet())){ | 
| +        throw MakeTypeError("redefine_disallowed", ["defineProperty"]); | 
| +      } | 
| +      if (desc.hasGetter() && !SameValue(desc.getGet(),current.getGet())) | 
| +        throw MakeTypeError("redefine_disallowed", ["defineProperty"]); | 
| +    } | 
| +  } | 
| + | 
| +  // Send flags - enumerable and configurable are common - writable is | 
| +  // only send to the data descriptor. | 
| +  // Take special care if enumerable and configurable is not defined on | 
| +  // desc (we need to preserve the existing values from current). | 
| +  var flag = NONE; | 
| +  if (desc.hasEnumerable()) { | 
| +    flag |= desc.isEnumerable() ? 0 : DONT_ENUM; | 
| +  } else if (!IS_UNDEFINED(current)) { | 
| +    flag |= current.isEnumerable() ? 0 : DONT_ENUM; | 
| } else { | 
| -    if (IS_FUNCTION(desc.getGet())) %DefineAccessor(obj, p, GETTER, desc.getGet(), flag); | 
| -    if (IS_FUNCTION(desc.getSet())) %DefineAccessor(obj, p, SETTER, desc.getSet(), flag); | 
| +    flag |= DONT_ENUM; | 
| } | 
| + | 
| +  if (desc.hasConfigurable()) { | 
| +    flag |= desc.isConfigurable() ? 0 : DONT_DELETE; | 
| +  } else if (!IS_UNDEFINED(current)) { | 
| +    flag |= current.isConfigurable() ? 0 : DONT_DELETE; | 
| +  } else | 
| +    flag |= DONT_DELETE; | 
| + | 
| +  if (IsDataDescriptor(desc) || IsGenericDescriptor(desc)) { | 
| +    flag |= desc.isWritable() ? 0 : READ_ONLY; | 
| +    %DefineOrRedefineDataProperty(obj, p, desc.getValue(), flag); | 
| +  } else { | 
| +    if (desc.hasGetter() && IS_FUNCTION(desc.getGet())) { | 
| +       %DefineOrRedefineAccessorProperty(obj, p, GETTER, desc.getGet(), flag); | 
| +    } | 
| +    if (desc.hasSetter() && IS_FUNCTION(desc.getSet())) { | 
| +      %DefineOrRedefineAccessorProperty(obj, p, SETTER, desc.getSet(), flag); | 
| +    } | 
| +  } | 
| return true; | 
| } | 
|  | 
| @@ -558,10 +659,21 @@ | 
| } | 
|  | 
|  | 
| -// ES5 section 15.2.3.7.  This version cannot cope with the properies already | 
| -// being present on obj.  Therefore it is not exposed as | 
| -// Object.defineProperties yet. | 
| +// ES5 section 15.2.3.6. | 
| +function ObjectDefineProperty(obj, p, attributes) { | 
| +  if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj)) | 
| +    throw MakeTypeError("obj_ctor_property_non_object", ["defineProperty"]); | 
| +  var name = ToString(p); | 
| +  var desc = ToPropertyDescriptor(attributes); | 
| +  DefineOwnProperty(obj, name, desc, true); | 
| +  return obj; | 
| +} | 
| + | 
| + | 
| +// ES5 section 15.2.3.7. | 
| function ObjectDefineProperties(obj, properties) { | 
| + if ((!IS_OBJECT(obj) || IS_NULL_OR_UNDEFINED(obj)) && !IS_FUNCTION(obj)) | 
| +    throw MakeTypeError("obj_ctor_property_non_object", ["defineProperties"]); | 
| var props = ToObject(properties); | 
| var key_values = []; | 
| for (var key in props) { | 
| @@ -611,6 +723,8 @@ | 
| InstallFunctions($Object, DONT_ENUM, $Array( | 
| "keys", ObjectKeys, | 
| "create", ObjectCreate, | 
| +    "defineProperty", ObjectDefineProperty, | 
| +    "defineProperties", ObjectDefineProperties, | 
| "getPrototypeOf", ObjectGetPrototypeOf, | 
| "getOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptor, | 
| "getOwnPropertyNames", ObjectGetOwnPropertyNames | 
|  |