} Variant::Variant(CVarWithRefBind v) { constructWithRefHelper(variant(v)); } /* * The destruct functions below all arbitrarily take RefData* as an * example of a refcounted object, then just cast to the proper type. * This is safe because we have compile time assertions that guarantee that * the _count field will always be exactly FAST_REFCOUNT_OFFSET bytes from * the beginning of the object for the StringData, ArrayData, ObjectData, * ResourceData, and RefData classes. */ static_assert(TYPE_TO_DESTR_IDX(KindOfString) == 1, "String destruct index"); static_assert(TYPE_TO_DESTR_IDX(KindOfArray) == 2, "Array destruct index"); static_assert(TYPE_TO_DESTR_IDX(KindOfObject) == 3, "Object destruct index"); static_assert(TYPE_TO_DESTR_IDX(KindOfResource) == 4, "Resource destruct index"); static_assert(TYPE_TO_DESTR_IDX(KindOfRef) == 5, "Ref destruct index"); static_assert(kDestrTableSize == 6, "size of g_destructors[] must be kDestrTableSize"); const RawDestructor g_destructors[] = { nullptr, (RawDestructor)getMethodPtr(&StringData::release), (RawDestructor)getMethodPtr(&ArrayData::release), (RawDestructor)getMethodPtr(&ObjectData::release), (RawDestructor)getMethodPtr(&ResourceData::release),
void tweak_variant_dtors() { if (RuntimeOption::EnableObjDestructCall) return; g_destructors[TYPE_TO_DESTR_IDX(KindOfObject)] = (RawDestructor)getMethodPtr(&ObjectData::releaseNoObjDestructCheck); }