Esempio n. 1
0
ObjectData* new_ZendObjectData_Instance(Class* cls) {
  TSRMLS_FETCH();
  size_t nProps = cls->numDeclProperties();
  size_t builtinObjSize = sizeof(c_ZendObjectData) - sizeof(ObjectData);
  size_t size = ObjectData::sizeForNProps(nProps) + builtinObjSize;
  auto obj = new (MM().objMallocLogged(size)) c_ZendObjectData(cls);

  zend_class_entry* ce = zend_hphp_class_to_class_entry(cls);
  auto create_func = ce->create_object;
  Class * current_class = cls;
  while (!create_func) {
    Class* parent = current_class->parent();
    if (!parent) {
      break;
    }
    zend_class_entry* parent_ce = zend_hphp_class_to_class_entry(parent);
    create_func = parent_ce->create_object;
    current_class = parent;
  }

  zend_object_value ov;
  if (create_func) {
    ov = create_func(ce TSRMLS_CC);
  } else {
    zend_object *object;
    ov = zend_objects_new(&object, ce TSRMLS_CC);
  }
  obj->setHandle(ov.handle);

  if (UNLIKELY(cls->callsCustomInstanceInit())) {
    /*
      This must happen after the constructor finishes,
      because it can leak references to obj AND it can
      throw exceptions. If we have this in the ObjectData
      constructor, and it throws, obj will be partially
      destroyed (ie ~ObjectData will be called, resetting
      the vtable pointer) leaving dangling references
      to the object (eg in backtraces).
    */
    obj->callCustomInstanceInit();
  }

  return obj;
}
Esempio n. 2
0
void ZendObject::initZendObject(Class * cls) {
  TSRMLS_FETCH();
  zend_class_entry* ce = zend_hphp_class_to_class_entry(cls);
  auto create_func = ce->create_object;
  Class * current_class = cls;
  while (!create_func) {
    Class* parent = current_class->parent();
    if (!parent) {
      break;
    }
    zend_class_entry* parent_ce = zend_hphp_class_to_class_entry(parent);
    create_func = parent_ce->create_object;
    current_class = parent;
  }

  zend_object_value ov;
  if (create_func) {
    ov = create_func(ce TSRMLS_CC);
  } else {
    zend_object *object;
    ov = zend_objects_new(&object, ce TSRMLS_CC);
  }
  setHandle(ov.handle);
}