MCPcopy Create free account
hub / github.com/ZDoom/gzdoom / Build

Method Build

src/common/scripting/backend/vmbuilder.cpp:839–971  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

837
838
839void FFunctionBuildList::Build()
840{
841 VMDisassemblyDumper disasmdump(VMDisassemblyDumper::Overwrite);
842
843 for (auto &item : mItems)
844 {
845 // [Player701] Do not emit code for abstract functions
846 bool isAbstract = item.Func->Variants[0].Implementation->VarFlags & VARF_Abstract;
847 if (isAbstract) continue;
848
849 assert(item.Code != NULL);
850
851 // We don't know the return type in advance for anonymous functions.
852 FCompileContext ctx(item.CurGlobals, item.Func, item.Func->SymbolName == NAME_None ? nullptr : item.Func->Variants[0].Proto, item.FromDecorate, item.StateIndex, item.StateCount, item.Lump, item.Version);
853
854 // Allocate registers for the function's arguments and create local variable nodes before starting to resolve it.
855 VMFunctionBuilder buildit(item.Func->GetImplicitArgs());
856 for (unsigned i = 0; i < item.Func->Variants[0].Proto->ArgumentTypes.Size(); i++)
857 {
858 auto type = item.Func->Variants[0].Proto->ArgumentTypes[i];
859 auto name = item.Func->Variants[0].ArgNames[i];
860 auto flags = item.Func->Variants[0].ArgFlags[i];
861 // this won't get resolved and won't get emitted. It is only needed so that the code generator can retrieve the necessary info about this argument to do its work.
862 auto local = new FxLocalVariableDeclaration(type, name, nullptr, flags, FScriptPosition());
863 if (!(flags & VARF_Out)) local->RegNum = buildit.Registers[type->GetRegType()].Get(type->GetRegCount());
864 else local->RegNum = buildit.Registers[REGT_POINTER].Get(1);
865 ctx.FunctionArgs.Push(local);
866 }
867
868 FScriptPosition::StrictErrors = !item.FromDecorate || strictdecorate;
869 item.Code = item.Code->Resolve(ctx);
870 // If we need extra space, load the frame pointer into a register so that we do not have to call the wasteful LFP instruction more than once.
871 if (item.Function->ExtraSpace > 0)
872 {
873 buildit.FramePointer = ExpEmit(&buildit, REGT_POINTER);
874 buildit.FramePointer.Fixed = true;
875 buildit.Emit(OP_LFP, buildit.FramePointer.RegNum);
876 }
877
878 // Make sure resolving it didn't obliterate it.
879 if (item.Code != nullptr)
880 {
881 if (!item.Code->CheckReturn())
882 {
883 if (ctx.ReturnProto == nullptr || !ctx.ReturnProto->ReturnTypes.Size())
884 {
885 auto newcmpd = new FxCompoundStatement(item.Code->ScriptPosition);
886 newcmpd->Add(item.Code);
887 newcmpd->Add(new FxReturnStatement(nullptr, item.Code->ScriptPosition));
888 item.Code = newcmpd->Resolve(ctx);
889 }
890 else
891 {
892 item.Code->ScriptPosition.Message(MSG_ERROR, "Missing return statement in %s", item.PrintableName.GetChars());
893 continue;
894 }
895 }
896

Callers 1

LoadActorsFunction · 0.80

Calls 15

ExpEmitClass · 0.85
NewPrototypeFunction · 0.85
NewPointerFunction · 0.85
GetImplicitArgsMethod · 0.80
GetRegTypeMethod · 0.80
GetRegCountMethod · 0.80
MessageMethod · 0.80
BeginStatementMethod · 0.80
EndStatementMethod · 0.80
MakeFunctionMethod · 0.80
JitCompileMethod · 0.80
GetMessageMethod · 0.80

Tested by

no test coverage detected