Entry
| 754 | |
| 755 | // Entry |
| 756 | int asCCompiler::CompileFunction(asCBuilder *in_builder, asCScriptCode *in_script, asCArray<asCString> &in_parameterNames, asCScriptNode *in_func, asCScriptFunction *in_outFunc, sClassDeclaration *in_classDecl) |
| 757 | { |
| 758 | TimeIt("asCCompiler::CompileFunction"); |
| 759 | |
| 760 | Reset(in_builder, in_script, in_outFunc); |
| 761 | int buildErrors = builder->numErrors; |
| 762 | |
| 763 | int stackPos = SetupParametersAndReturnVariable(in_parameterNames, in_func); |
| 764 | |
| 765 | // If there are compile errors, there is no reason to build the final code |
| 766 | if (hasCompileErrors || builder->numErrors != buildErrors) |
| 767 | return -1; |
| 768 | |
| 769 | //-------------------------------------------- |
| 770 | // Compile the statement block |
| 771 | |
| 772 | if( m_isConstructor ) |
| 773 | m_classDecl = in_classDecl; |
| 774 | |
| 775 | // We need to parse the statement block now |
| 776 | asCScriptNode *blockBegin; |
| 777 | |
| 778 | // If the function signature was implicit, e.g. virtual property accessor or |
| 779 | // lambda function, then the received node already is the statement block |
| 780 | if( in_func->nodeType != snStatementBlock ) |
| 781 | blockBegin = in_func->lastChild; |
| 782 | else |
| 783 | blockBegin = in_func; |
| 784 | |
| 785 | // TODO: memory: We can parse the statement block one statement at a time, thus save even more memory |
| 786 | // TODO: optimize: For large functions, the parsing of the statement block can take a long time. Presumably because a lot of memory needs to be allocated |
| 787 | asCParser parser(builder); |
| 788 | int r = parser.ParseStatementBlock(script, blockBegin); |
| 789 | if( r < 0 ) return -1; |
| 790 | asCScriptNode *block = parser.GetScriptNode(); |
| 791 | |
| 792 | // Reserve a label for the cleanup code |
| 793 | nextLabel++; |
| 794 | |
| 795 | bool hasReturn; |
| 796 | asCByteCode bc(engine); |
| 797 | LineInstr(&bc, blockBegin->tokenPos); |
| 798 | CompileStatementBlock(block, false, &hasReturn, &bc); |
| 799 | LineInstr(&bc, blockBegin->tokenPos + blockBegin->tokenLength); |
| 800 | |
| 801 | // Make sure there is a return in all paths (if not return type is void) |
| 802 | // Don't bother with this check if there are compiler errors, e.g. Unreachable code |
| 803 | if( !hasCompileErrors && outFunc->returnType != asCDataType::CreatePrimitive(ttVoid, false) ) |
| 804 | { |
| 805 | if( hasReturn == false ) |
| 806 | Error(TXT_NOT_ALL_PATHS_RETURN, blockBegin); |
| 807 | } |
| 808 | |
| 809 | //------------------------------------------------ |
| 810 | // Concatenate the bytecode |
| 811 | |
| 812 | // Insert a JitEntry at the start of the function for JIT compilers |
| 813 | byteCode.InstrPTR(asBC_JitEntry, 0); |
nothing calls this directly
no test coverage detected