| 3069 | } |
| 3070 | |
| 3071 | void FunctionStart(const char* pos) |
| 3072 | { |
| 3073 | FunctionInfo &lastFunc = *currDefinedFunc.back(); |
| 3074 | // Remove function arguments used to enable typeof |
| 3075 | for(VariableInfo *curr = lastFunc.firstParam; curr; curr = curr->next) |
| 3076 | varMap.remove(curr->nameHash, curr); |
| 3077 | if(lastFunc.lastParam && !lastFunc.lastParam->varType) |
| 3078 | ThrowError(pos, "ERROR: function parameter cannot be an auto type"); |
| 3079 | |
| 3080 | lastFunc.implemented = true; |
| 3081 | // Resolve function type if the return type is known |
| 3082 | lastFunc.funcType = lastFunc.retType ? CodeInfo::GetFunctionType(lastFunc.retType, lastFunc.firstParam, lastFunc.paramCount) : NULL; |
| 3083 | if(lastFunc.type == FunctionInfo::NORMAL) |
| 3084 | lastFunc.pure = true; // normal function is pure by default |
| 3085 | if(lastFunc.parentFunc) |
| 3086 | lastFunc.parentFunc->pure = false; // local function invalidates parent function purity |
| 3087 | |
| 3088 | BeginBlock(); |
| 3089 | cycleDepth.push_back(0); |
| 3090 | |
| 3091 | varTop = 0; |
| 3092 | |
| 3093 | for(VariableInfo *curr = lastFunc.firstParam; curr; curr = curr->next) |
| 3094 | { |
| 3095 | CheckCollisionWithFunction(pos, curr->name, curr->nameHash, varInfoTop.size()); |
| 3096 | varTop += GetAlignmentOffset(pos, 4); |
| 3097 | CodeInfo::varInfo.push_back(curr); |
| 3098 | CodeInfo::varInfo.back()->blockDepth = varInfoTop.size(); |
| 3099 | varMap.insert(curr->nameHash, curr); |
| 3100 | varTop += curr->varType->size ? curr->varType->size : 4; // 0-byte size arguments use up 4 bytes |
| 3101 | if(curr->varType->type == TypeInfo::TYPE_COMPLEX || curr->varType->refLevel) |
| 3102 | lastFunc.pure = false; // Pure functions can only accept simple types |
| 3103 | } |
| 3104 | |
| 3105 | char *hiddenHame = AllocateString(lastFunc.nameLength + 24); |
| 3106 | int length = 0; |
| 3107 | if(lastFunc.type == FunctionInfo::THISCALL) |
| 3108 | { |
| 3109 | memcpy(hiddenHame, "this", 5); |
| 3110 | length = 4; |
| 3111 | }else{ |
| 3112 | length = sprintf(hiddenHame, "$%s_%d_ext", lastFunc.name, CodeInfo::FindFunctionByPtr(&lastFunc)); |
| 3113 | } |
| 3114 | currType = CodeInfo::GetReferenceType(lastFunc.type == FunctionInfo::THISCALL ? lastFunc.parentClass : typeInt); |
| 3115 | currAlign = 4; |
| 3116 | lastFunc.extraParam = (VariableInfo*)AddVariable(pos, InplaceStr(hiddenHame, length), false); |
| 3117 | |
| 3118 | if(lastFunc.type == FunctionInfo::COROUTINE) |
| 3119 | { |
| 3120 | currType = typeInt; |
| 3121 | VariableInfo *jumpOffset = (VariableInfo*)AddVariable(pos, InplaceStr("$jmpOffset", 10)); |
| 3122 | AddFunctionExternal(&lastFunc, jumpOffset); |
| 3123 | } |
| 3124 | varDefined = false; |
| 3125 | |
| 3126 | // If this is a constructor |
| 3127 | if(lastFunc.typeConstructor) |
| 3128 | { |
no test coverage detected