⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objects.cc.svn-base

📁 Google浏览器V8内核代码
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
      Map::cast(new_map)->        set_instance_descriptors(DescriptorArray::cast(new_descriptors));      Map::cast(new_map)->        set_unused_property_fields(map()->unused_property_fields()-1);      set_map(Map::cast(new_map));      properties()->set(index, value);    } else {      ASSERT(map()->unused_property_fields() == 0);      static const int kFastNofProperties = 20;      if (properties()->length() > kFastNofProperties) {        Object* obj = NormalizeProperties();        if (obj->IsFailure()) return obj;        return SetProperty(name, value, NONE);      }      static const int kExtraFields = 5;      // Make room for the more properties.      Object* values =          properties()->CopySize(properties()->length() + kExtraFields);      if (values->IsFailure()) return values;      FixedArray::cast(values)->set(index, value);      // Allocate a new map for the object.      Object* new_map = map()->Copy();      if (new_map->IsFailure()) return new_map;      Map::cast(new_map)->        set_instance_descriptors(DescriptorArray::cast(new_descriptors));      Map::cast(new_map)->        set_unused_property_fields(kExtraFields - 1);      set_map(Map::cast(new_map));      set_properties(FixedArray::cast(values));    }  }  return value;}// Add property in slow modeObject* JSObject::AddSlowProperty(String* name,                                  Object* value,                                  PropertyAttributes attributes) {  PropertyDetails details = PropertyDetails(attributes, NORMAL);  Object* result = property_dictionary()->AddStringEntry(name, value, details);  if (result->IsFailure()) return result;  if (property_dictionary() != result) {     set_properties(Dictionary::cast(result));  }  return value;}Object* JSObject::AddProperty(String* name,                              Object* value,                              PropertyAttributes attributes) {  if (HasFastProperties()) {    // Ensure the descriptor array does not get too big.    if (map()->instance_descriptors()->number_of_descriptors() <        DescriptorArray::kMaxNumberOfDescriptors) {      if (value->IsJSFunction()) {        return AddConstantFunctionProperty(name,                                           JSFunction::cast(value),                                           attributes);      } else {        return AddFastProperty(name, value, attributes);      }    } else {      // Normalize the object to prevent very large instance descriptors.      // This eliminates unwanted N^2 allocation and lookup behavior.      Object* obj = NormalizeProperties();      if (obj->IsFailure()) return obj;    }  }  return AddSlowProperty(name, value, attributes);}Object* JSObject::SetPropertyPostInterceptor(String* name,                                             Object* value,                                             PropertyAttributes attributes) {  // Check local property, ignore interceptor.  LookupResult result;  LocalLookupRealNamedProperty(name, &result);  if (result.IsValid()) return SetProperty(&result, name, value, attributes);  // Add real property.  return AddProperty(name, value, attributes);}Object* JSObject::SetPropertyWithInterceptor(String* name,                                             Object* value,                                             PropertyAttributes attributes) {  HandleScope scope;  Handle<JSObject> this_handle(this);  Handle<String> name_handle(name);  Handle<Object> value_handle(value);  Handle<InterceptorInfo> interceptor(GetNamedInterceptor());  if (!interceptor->setter()->IsUndefined()) {    Handle<Object> data_handle(interceptor->data());    LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name));    v8::AccessorInfo info(v8::Utils::ToLocal(this_handle),                          v8::Utils::ToLocal(data_handle),                          v8::Utils::ToLocal(this_handle));    v8::NamedPropertySetter setter =        v8::ToCData<v8::NamedPropertySetter>(interceptor->setter());    v8::Handle<v8::Value> result;    {      // Leaving JavaScript.      VMState state(OTHER);      Handle<Object> value_unhole(value->IsTheHole() ?                                  Heap::undefined_value() :                                  value);      result = setter(v8::Utils::ToLocal(name_handle),                      v8::Utils::ToLocal(value_unhole),                      info);    }    RETURN_IF_SCHEDULED_EXCEPTION();    if (!result.IsEmpty()) return *value_handle;  }  Object* raw_result = this_handle->SetPropertyPostInterceptor(*name_handle,                                                               *value_handle,                                                               attributes);  RETURN_IF_SCHEDULED_EXCEPTION();  return raw_result;}Object* JSObject::SetProperty(String* name,                              Object* value,                              PropertyAttributes attributes) {  LookupResult result;  LocalLookup(name, &result);  return SetProperty(&result, name, value, attributes);}Object* JSObject::SetPropertyWithCallback(Object* structure,                                          String* name,                                          Object* value,                                          JSObject* holder) {  HandleScope scope;  // We should never get here to initialize a const with the hole  // value since a const declaration would conflict with the setter.  ASSERT(!value->IsTheHole());  Handle<Object> value_handle(value);  // To accommodate both the old and the new api we switch on the  // data structure used to store the callbacks.  Eventually proxy  // callbacks should be phased out.  if (structure->IsProxy()) {    AccessorDescriptor* callback =        reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy());    Object* obj = (callback->setter)(this,  value, callback->data);    RETURN_IF_SCHEDULED_EXCEPTION();    if (obj->IsFailure()) return obj;    return *value_handle;  }  if (structure->IsAccessorInfo()) {    // api style callbacks    AccessorInfo* data = AccessorInfo::cast(structure);    Object* call_obj = data->setter();    v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj);    if (call_fun == NULL) return value;    Handle<JSObject> self(this);    Handle<JSObject> holder_handle(JSObject::cast(holder));    Handle<String> key(name);    Handle<Object> fun_data(data->data());    LOG(ApiNamedPropertyAccess("store", this, name));    v8::AccessorInfo info(v8::Utils::ToLocal(self),                          v8::Utils::ToLocal(fun_data),                          v8::Utils::ToLocal(holder_handle));    {      // Leaving JavaScript.      VMState state(OTHER);      call_fun(v8::Utils::ToLocal(key),               v8::Utils::ToLocal(value_handle),               info);    }    RETURN_IF_SCHEDULED_EXCEPTION();    return *value_handle;  }  if (structure->IsFixedArray()) {    Object* setter = FixedArray::cast(structure)->get(kSetterIndex);    if (setter->IsJSFunction()) {      Handle<JSFunction> fun(JSFunction::cast(setter));      Handle<JSObject> self(this);      bool has_pending_exception;      Object** argv[] = { value_handle.location() };      Execution::Call(fun, self, 1, argv, &has_pending_exception);      // Check for pending exception and return the result.      if (has_pending_exception) return Failure::Exception();    } else {      Handle<String> key(name);      Handle<Object> holder_handle(holder);      Handle<Object> args[2] = { key, holder_handle };      return Top::Throw(*Factory::NewTypeError("no_setter_in_callback",                                               HandleVector(args, 2)));    }    return *value_handle;  }  UNREACHABLE();  return 0;}void JSObject::LookupCallbackSetterInPrototypes(String* name,                                                LookupResult* result) {  for (Object* pt = GetPrototype();       pt != Heap::null_value();       pt = pt->GetPrototype()) {    JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);    if (result->IsValid()) {      if (!result->IsTransitionType() && result->IsReadOnly()) {        result->NotFound();        return;      }      if (result->type() == CALLBACKS) {        return;      }    }  }  result->NotFound();}void JSObject::LookupInDescriptor(String* name, LookupResult* result) {  DescriptorArray* descriptors = map()->instance_descriptors();  int number = descriptors->Search(name);  if (number != DescriptorArray::kNotFound) {    result->DescriptorResult(this, descriptors->GetDetails(number), number);  } else {    result->NotFound();  }}void JSObject::LocalLookupRealNamedProperty(String* name,                                            LookupResult* result) {  if (HasFastProperties()) {    LookupInDescriptor(name, result);    if (result->IsValid()) {      ASSERT(result->holder() == this && result->type() != NORMAL);      // Disallow caching for uninitialized constants. These can only      // occur as fields.      if (result->IsReadOnly() && result->type() == FIELD &&          properties()->get(result->GetFieldIndex())->IsTheHole()) {        result->DisallowCaching();      }      return;    }  } else {    int entry = property_dictionary()->FindStringEntry(name);    if (entry != DescriptorArray::kNotFound) {      // Make sure to disallow caching for uninitialized constants      // found in the dictionary-mode objects.      if (property_dictionary()->ValueAt(entry)->IsTheHole()) {        result->DisallowCaching();      }      result->DictionaryResult(this, entry);      return;    }    // Slow case object skipped during lookup. Do not use inline caching.    result->DisallowCaching();  }  result->NotFound();}void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) {  LocalLookupRealNamedProperty(name, result);  if (result->IsProperty()) return;  LookupRealNamedPropertyInPrototypes(name, result);}void JSObject::LookupRealNamedPropertyInPrototypes(String* name,                                                   LookupResult* result) {  for (Object* pt = GetPrototype();       pt != Heap::null_value();       pt = JSObject::cast(pt)->GetPrototype()) {    JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result);    if (result->IsValid()) {      switch (result->type()) {        case NORMAL:        case FIELD:        case CONSTANT_FUNCTION:        case CALLBACKS:          return;        default: break;      }    }  }  result->NotFound();}// We only need to deal with CALLBACKS and INTERCEPTORSObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result,                                                   String* name,                                                   Object* value) {  if (!result->IsProperty()) {    LookupCallbackSetterInPrototypes(name, result);  }  if (result->IsProperty()) {    if (!result->IsReadOnly()) {      switch (result->type()) {        case CALLBACKS: {          Object* obj = result->GetCallbackObject();          if (obj->IsAccessorInfo()) {            AccessorInfo* info = AccessorInfo::cast(obj);            if (info->all_can_write()) {              return SetPropertyWithCallback(result->GetCallbackObject(),                                             name,                                             value,                                             result->holder());            }          }          break;        }        case INTERCEPTOR: {          // Try lookup real named properties. Note that only property can be          // set is callbacks marked as ALL_CAN_WRITE on the prototype chain.          LookupResult r;          LookupRealNamedProperty(name, &r);          if (r.IsProperty()) {            return SetPropertyWithFailedAccessCheck(&r, name, value);          }          break;        }        default: {          break;        }      }    }  }  Top::ReportFailedAccessCheck(this, v8::ACCESS_SET);  return value;}Object* JSObject::SetProperty(LookupResult* result,                              String* name,                              Object* value,                              PropertyAttributes attributes) {  // Make sure that the top context does not change when doing callbacks or  // interceptor calls.  AssertNoContextChange ncc;  // Check access rights if needed.  if (IsAccessCheckNeeded()    && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) {    return SetPropertyWithFailedAccessCheck(result, name, value);  }  if (result->IsNotFound() || !result->IsProperty()) {    // We could not find a local property so let's check whether there is an    // accessor that wants to handle the property.    LookupResult accessor_result;    LookupCallbackSetterInPrototypes(name, &accessor_result);    if (accessor_result.IsValid()) {      return SetPropertyWithCallback(accessor_result.GetCallbackObject(),                                     name,                                     value,                                     accessor_result.holder());    }  }  if (result->IsNotFound()) {    return AddProperty(name, value, attributes);  }  if (!result->IsLoaded()) {    return SetLazyProperty(result, name, value, attributes);  }  if (result->IsReadOnly() && result->IsProperty()) return value;  // This is a real property that is not read-only, or it is a  // transition or null descriptor and there are no setters in the prototypes.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -