libraries/v8/runtime.cc
// Implements part of 8.12.9 DefineOwnProperty.
// There are 3 cases that lead here:
// Step 4a - define a new data property.
// Steps 9b & 12 - replace an existing accessor property with a data property.
// Step 12 - update an existing data property with a data or generic
//           descriptor.
Implements part of 8.12.9 DefineOwnProperty.
There are 3 cases that lead here:
Step 4a - define a new data property.
Steps 9b & 12 - replace an existing accessor property with a data property.
Step 12 - update an existing data property with a data or generic
descriptor.
Implements part of 8 . 12 . 9 DefineOwnProperty . There are 3 cases that lead here : Step 4a - define a new data property . Steps 9b & 12 - replace an existing accessor property with a data property . Step 12 - update an existing data property with a data or generic descriptor .
RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
  HandleScope scope(isolate);
  ASSERT(args.length() == 4);
  CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
  CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
  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);
  LookupResult result(isolate);
  js_object->LocalLookupRealNamedProperty(*name, &result);
  if (result.IsPropertyCallbacks()) {
    Object* callback = result.GetCallbackObject();
    if (callback->IsAccessorInfo()) {
      return isolate->heap()->undefined_value();
    }
    if (callback->IsForeign() && result.GetAttributes() == attr) {
      Handle<Object> result_object =
          JSObject::SetPropertyWithCallback(js_object,
                                            handle(callback, isolate),
                                            name,
                                            obj_value,
                                            handle(result.holder()),
                                            kStrictMode);
      RETURN_IF_EMPTY_HANDLE(isolate, result_object);
      return *result_object;
    }
  }
  if (result.IsFound() &&
      (attr != result.GetAttributes() || result.IsPropertyCallbacks())) {
    if (js_object->IsJSGlobalProxy()) {
      js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
    }
    JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
    Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
        js_object, name, obj_value, attr);
    RETURN_IF_EMPTY_HANDLE(isolate, result);
    return *result;
  }
  return Runtime::ForceSetObjectProperty(isolate,
                                         js_object,
                                         name,
                                         obj_value,
                                         attr);
}
RUNTIME_FUNCTION ( MaybeObject * , Runtime_DefineOrRedefineDataProperty ) { HandleScope scope ( isolate ) ; ASSERT ( args . length ( ) == 4 ) ; CONVERT_ARG_HANDLE_CHECKED ( JSObject , js_object , 0 ) ; CONVERT_ARG_HANDLE_CHECKED ( Name , name , 1 ) ; 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 ) ; LookupResult result ( isolate ) ; js_object -> LocalLookupRealNamedProperty ( * name , & result ) ; if ( result . IsPropertyCallbacks ( ) ) { Object * callback = result . GetCallbackObject ( ) ; if ( callback -> IsAccessorInfo ( ) ) { return isolate -> heap ( ) -> undefined_value ( ) ; } if ( callback -> IsForeign ( ) && result . GetAttributes ( ) == attr ) { Handle < Object > result_object = JSObject :: SetPropertyWithCallback ( js_object , handle ( callback , isolate ) , name , obj_value , handle ( result . holder ( ) ) , kStrictMode ) ; RETURN_IF_EMPTY_HANDLE ( isolate , result_object ) ; return * result_object ; } } if ( result . IsFound ( ) && ( attr != result . GetAttributes ( ) || result . IsPropertyCallbacks ( ) ) ) { if ( js_object -> IsJSGlobalProxy ( ) ) { js_object = Handle < JSObject > ( JSObject :: cast ( js_object -> GetPrototype ( ) ) ) ; } JSObject :: NormalizeProperties ( js_object , CLEAR_INOBJECT_PROPERTIES , 0 ) ; Handle < Object > result = JSObject :: SetLocalPropertyIgnoreAttributes ( js_object , name , obj_value , attr ) ; RETURN_IF_EMPTY_HANDLE ( isolate , result ) ; return * result ; } return Runtime :: ForceSetObjectProperty ( isolate , js_object , name , obj_value , attr ) ; }
Implements part of 8.12.9 DefineOwnProperty.
Implements part of 8 . 12 . 9 DefineOwnProperty .
// Special case for callback properties. // To be compatible with Safari we do not change the value on API objects // in Object.defineProperty(). Firefox disagrees here, and actually changes // the value. // Avoid redefining foreign callback as data property, just use the stored // setter to update the value instead. // TODO(mstarzinger): So far this only works if property attributes don't // change, this should be fixed once we cleanup the underlying code. // Take special care when attributes are different and there is already // a property. For simplicity we normalize the property which enables us // to not worry about changing the instance_descriptor and creating a new // map. The current version of SetObjectProperty does not handle attributes // correctly in the case where a property is a field and is reset with // new attributes. // New attributes - normalize to avoid writing to instance descriptor // Since the result is a property, the prototype will exist so // we don't have to check for null. // Use IgnoreAttributes version since a readonly property may be // overridden and SetProperty does not allow this.