This function should prepare system functions so that it will be faster to call them
| 178 | |
| 179 | // This function should prepare system functions so that it will be faster to call them |
| 180 | int PrepareSystemFunctionGeneric(asCScriptFunction *func, asSSystemFunctionInterface *internal, asCScriptEngine *engine) |
| 181 | { |
| 182 | asASSERT(internal->callConv == ICC_GENERIC_METHOD || internal->callConv == ICC_GENERIC_FUNC); |
| 183 | |
| 184 | // Calculate the size needed for the parameters |
| 185 | internal->paramSize = func->GetSpaceNeededForArguments(); |
| 186 | |
| 187 | // Prepare the clean up instructions for the function arguments |
| 188 | internal->cleanArgs.SetLength(0); |
| 189 | int offset = 0; |
| 190 | for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ ) |
| 191 | { |
| 192 | asCDataType &dt = func->parameterTypes[n]; |
| 193 | |
| 194 | if( (dt.IsObject() || dt.IsFuncdef()) && !dt.IsReference() ) |
| 195 | { |
| 196 | if (dt.IsFuncdef()) |
| 197 | { |
| 198 | // If the generic call mode is set to old behaviour then always release handles |
| 199 | // else only release the handle if the function is declared with auto handles |
| 200 | if (engine->ep.genericCallMode == 0 || (internal->paramAutoHandles.GetLength() > n && internal->paramAutoHandles[n])) |
| 201 | { |
| 202 | asSSystemFunctionInterface::SClean clean; |
| 203 | clean.op = 0; // call release |
| 204 | clean.ot = &engine->functionBehaviours; |
| 205 | clean.off = short(offset); |
| 206 | internal->cleanArgs.PushLast(clean); |
| 207 | } |
| 208 | } |
| 209 | else if( dt.GetTypeInfo()->flags & asOBJ_REF ) |
| 210 | { |
| 211 | // If the generic call mode is set to old behaviour then always release handles |
| 212 | // else only release the handle if the function is declared with auto handles |
| 213 | if (!dt.IsObjectHandle() || |
| 214 | engine->ep.genericCallMode == 0 || |
| 215 | (internal->paramAutoHandles.GetLength() > n && internal->paramAutoHandles[n]) ) |
| 216 | { |
| 217 | asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh; |
| 218 | asASSERT((dt.GetTypeInfo()->flags & asOBJ_NOCOUNT) || beh->release); |
| 219 | if (beh->release) |
| 220 | { |
| 221 | asSSystemFunctionInterface::SClean clean; |
| 222 | clean.op = 0; // call release |
| 223 | clean.ot = CastToObjectType(dt.GetTypeInfo()); |
| 224 | clean.off = short(offset); |
| 225 | internal->cleanArgs.PushLast(clean); |
| 226 | } |
| 227 | } |
| 228 | } |
| 229 | else |
| 230 | { |
| 231 | asSSystemFunctionInterface::SClean clean; |
| 232 | clean.op = 1; // call free |
| 233 | clean.ot = CastToObjectType(dt.GetTypeInfo()); |
| 234 | clean.off = short(offset); |
| 235 | |
| 236 | // Call the destructor then free the memory |
| 237 | asSTypeBehaviour *beh = &CastToObjectType(dt.GetTypeInfo())->beh; |
no test coverage detected