void *asCScriptObject::AllocateObject(asCObjectType *objType, asCScriptEngine *engine) { void *ptr = 0; if( objType->flags & asOBJ_SCRIPT_OBJECT ) { ptr = ScriptObjectFactory(objType, engine); } else if( objType->flags & asOBJ_TEMPLATE ) { ptr = ArrayObjectFactory(objType); } else if( objType->flags & asOBJ_REF ) { ptr = engine->CallGlobalFunctionRetPtr(objType->beh.factory); } else { ptr = engine->CallAlloc(objType); int funcIndex = objType->beh.construct; if( funcIndex ) engine->CallObjectMethod(ptr, funcIndex); } return ptr; }
void *asCScriptObject::AllocateObject(asCObjectType *objType, asCScriptEngine *engine, bool doInitialize) { void *ptr = 0; if( objType->flags & asOBJ_SCRIPT_OBJECT ) { if( doInitialize ) ptr = ScriptObjectFactory(objType, engine); else { ptr = engine->CallAlloc(objType); ScriptObject_ConstructUnitialized(objType, reinterpret_cast<asCScriptObject*>(ptr)); } } else if( objType->flags & asOBJ_TEMPLATE ) { // Templates store the original factory that takes the object // type as a hidden parameter in the construct behaviour ptr = engine->CallGlobalFunctionRetPtr(objType->beh.construct, objType); } else if( objType->flags & asOBJ_REF ) { ptr = engine->CallGlobalFunctionRetPtr(objType->beh.factory); } else { ptr = engine->CallAlloc(objType); int funcIndex = objType->beh.construct; if( funcIndex ) engine->CallObjectMethod(ptr, funcIndex); } return ptr; }
asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize) { refCount.set(1); objType = ot; objType->AddRef(); isDestructCalled = false; weakRefFlag = 0; hasRefCountReachedZero = false; // Notify the garbage collector of this object if( objType->flags & asOBJ_GC ) objType->engine->gc.AddScriptObjectToGC(this, objType); // Initialize members to zero. Technically we only need to zero the pointer // members, but just the memset is faster than having to loop and check the datatypes memset((void*)(this+1), 0, objType->size - sizeof(asCScriptObject)); if( doInitialize ) { #ifdef AS_NO_MEMBER_INIT // When member initialization is disabled the constructor must make sure // to allocate and initialize all members with the default constructor for( asUINT n = 0; n < objType->properties.GetLength(); n++ ) { asCObjectProperty *prop = objType->properties[n]; if( prop->type.IsObject() && !prop->type.IsObjectHandle() ) { if( prop->type.IsReference() || prop->type.GetObjectType()->flags & asOBJ_REF ) { asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset); if( prop->type.GetObjectType()->flags & asOBJ_SCRIPT_OBJECT ) *ptr = (asPWORD)ScriptObjectFactory(prop->type.GetObjectType(), ot->engine); else *ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), ot->engine); } } } #endif } else { // When the object is created without initialization, all non-handle members must be allocated, but not initialized asCScriptEngine *engine = objType->engine; for( asUINT n = 0; n < objType->properties.GetLength(); n++ ) { asCObjectProperty *prop = objType->properties[n]; if( prop->type.IsObject() && !prop->type.IsObjectHandle() ) { if( prop->type.IsReference() || (prop->type.GetObjectType()->flags & asOBJ_REF) ) { asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset); *ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), engine); } } } } }
asCScriptObject::asCScriptObject(asCObjectType *ot, bool doInitialize) { refCount.set(1); objType = ot; objType->AddRef(); isDestructCalled = false; // Notify the garbage collector of this object if( objType->flags & asOBJ_GC ) objType->engine->gc.AddScriptObjectToGC(this, objType); if( doInitialize ) { #ifndef AS_NO_MEMBER_INIT // The actual initialization will be done by the bytecode, so here we should just clear the // memory to guarantee that no pointers with have scratch values in case of an exception // TODO: runtime optimize: Is it quicker to just do a memset on the entire object? for( asUINT n = 0; n < objType->properties.GetLength(); n++ ) { asCObjectProperty *prop = objType->properties[n]; if( prop->type.IsObject() ) { asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset); *ptr = 0; } } #else // When member initialization is disabled the constructor must make sure // to allocate and initialize all members with the default constructor for( asUINT n = 0; n < objType->properties.GetLength(); n++ ) { asCObjectProperty *prop = objType->properties[n]; if( prop->type.IsObject() ) { asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset); if( prop->type.IsObjectHandle() ) *ptr = 0; else { if( prop->type.GetObjectType()->flags & asOBJ_SCRIPT_OBJECT ) *ptr = (asPWORD)ScriptObjectFactory(prop->type.GetObjectType(), ot->engine); else *ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), ot->engine); } } } #endif } else { // When the object is created without initialization, all non-handle members must be allocated, but not initialized asCScriptEngine *engine = objType->engine; for( asUINT n = 0; n < objType->properties.GetLength(); n++ ) { asCObjectProperty *prop = objType->properties[n]; if( prop->type.IsObject() ) { asPWORD *ptr = reinterpret_cast<asPWORD*>(reinterpret_cast<asBYTE*>(this) + prop->byteOffset); if( prop->type.IsObjectHandle() ) *ptr = 0; else *ptr = (asPWORD)AllocateUninitializedObject(prop->type.GetObjectType(), engine); } } } // Urho3D: initialize userdata userData = 0; }