unit RuntimeBuilder.Lua; interface uses System.Classes,System.TypInfo,System.IOUtils,System.Rtti,Winapi.Windows,System.Generics.Collections, pLuaObject,pLuaRecord,pLuaTable,uWordList,Lua,LuaObject,LuaWrapper,pLua,RuntimeBuilder; type TRTBLuaCompiler=class(TRTBCompiler) protected type TRTBLuaSource=class(TRTBSource) protected type TRTBLuaModule=class(TRTBModule) protected type TRTBLuaFunc=class(TRTBFunc) protected //p:Pointer; public //constructor Create(s:string); //function Call(OutType:PTypeInfo;args:TArray;CallType:TRTBCallType=CRTBCallTypeDefault):TValue;override; //destructor Destroy;override; end; TRTBFasmVar=class(TRTBVar) protected //p:pointer; //&Type:TRTBType; //procedure SetVal(Val:TValue);override; //function GetVal:TValue;override; public //constructor Create(p:pointer;&Type:TRTBType); //destructor Destroy;override; end; private //p:Pointer; //sb:NativeUInt; //funcs:TDictionary; //regvars:TDictionary>; //function GetFuntion(Name:string):TRTBFunc;override; //function GetVar(Name:string):TRTBVar;override; public //constructor Create(p:Pointer;sb:NativeUInt;funcs:TDictionary;regvars:TDictionary>); //destructor Destroy;override; end; protected libs:TStringList; funcs:TStringList; regvars:TList>; consts:TList>; FText:string; //function GetIncLibs():string; //function GetText:string;override; //procedure SetText(S:string);override; public constructor Create(Compiler:TRTBLuaCompiler); procedure LoadLib(Name:string);override; procedure UnLoadLib(Name:string);override; //procedure AddNameSpace(Name:string);override; //procedure DelNameSpace(Name:string);override; //procedure AddType(NameSpace:string;Name:string;&Type:TRTBType);override; //procedure DelType(NameSpace:string;Name:string);override; //procedure AddConst(NameSpace:string;Name:string;Val:TValue);override; //procedure DelConst(NameSpace:string;Name:string);override; //procedure AddCallBack(NameSpace:string;Name:string;CallBack:TRTBCallBack);override; //procedure DelCallBack(NameSpace:string;Name:string);override; //procedure AddVariable(NameSpace:string;Name:string;var Data);override; //procedure ExportVariable(NameSpace:string;Name:string;var Data);override; //procedure DelVariable(NameSpace:string;Name:string);override; //procedure &Register(NameSpace:string;Name:string;&Type:TRTBType);override; //procedure UnRegister(NameSpace:string;Name:string);override; //procedure RegisterFunction(NameSpace:string;Name:string);override; //procedure UnRegisterFunction(NameSpace:string;Name:string);override; function Compilate:TRTBModule;override; destructor Destroy;override; end; public constructor Create(); function GenNewSrc():TRTBSource;override; end; implementation uses System.SysUtils; (*constructor TRTBLuaCompiler.TRTBLuaSource.TRTBLuaModule.TRTBLuaFunc.Create(p:Pointer); begin inherited Create(); Self.p:=p; end; function TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.TRTBFasmFunc.Call(OutType:PTypeInfo;args:TArray;CallType:TRTBCallType=CRTBCallTypeDefault):TValue; begin {$IFDEF CPUX64} Result:=Invoke(p,args,ccReg,OutType); {$ELSE} case CallType of CRTBCallTypeRegister:Result:=Invoke(p,args,ccReg,OutType); CRTBCallTypeStdCall:Result:=Invoke(p,args,ccStdCall,OutType); CRTBCallTypeCdecl:Result:=Invoke(p,args,ccCdecl,OutType); CRTBCallTypePascal:Result:=Invoke(p,args,ccPascal,OutType); CRTBCallTypeSafeCall:Result:=Invoke(p,args,ccSafeCall,OutType); end; {$ENDIF} end; destructor TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.TRTBFasmFunc.Destroy; begin p:=nil; end; procedure TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.TRTBFasmVar.SetVal(Val:TValue); begin if Val.TypeInfo=&Type then Val.ExtractRawData(p); end; function TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.TRTBFasmVar.GetVal:TValue; begin TValue.Make(p,&Type,Result); end; constructor TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.TRTBFasmVar.Create(p:pointer;&Type:TRTBType); begin Self.p:=p; Self.&Type:=&Type; end; destructor TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.TRTBFasmVar.Destroy; begin p:=nil; &Type:=nil; end; function TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.GetFuntion(Name:string):TRTBFunc; begin Result:=TRTBFasmFunc.Create(PPointer(NativeUInt(funcs.Items[Name])+NativeUInt(p))^); end; function TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.GetVar(Name:string):TRTBVar; begin Result:=TRTBFasmVar.Create(PPointer(NativeUInt(regvars.Items[Name].Key)+NativeUInt(p))^,regvars.Items[Name].Value) end; constructor TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.Create(p:Pointer;sb:NativeUInt;funcs:TDictionary;regvars:TDictionary>); begin Self.p:=p; Self.sb:=sb; Self.funcs:=funcs; Self.regvars:=regvars; end; destructor TRTBFasmCompiler.TRTBFasmSource.TRTBFasmModule.Destroy; begin VirtualFree(p,sb,MEM_RELEASE); end; function TRTBFasmCompiler.TRTBFasmSource.GetIncLibs():string; var i:integer; begin Result:=''; for i:=0 to libs.count-1 do Result:=Result+sLineBreak+'include '+#39+libs.Strings[i]+#39; end; function TRTBFasmCompiler.TRTBFasmSource.GetText:string; begin Result:=FText; end; procedure TRTBFasmCompiler.TRTBFasmSource.SetText(S:string); begin FText:=S; end; procedure TRTBFasmCompiler.TRTBFasmSource.AddNameSpace(Name:string); begin end; procedure TRTBFasmCompiler.TRTBFasmSource.DelNameSpace(Name:string); label funcscontinue,regvarscontinue,constscontinue; var i,i0:NativeUInt; begin Name:=Name+'.'; i:=0; while i'' then consts.Add(TPair.Create(NameSpace+'.'+Name,Val)) else consts.Add(TPair.Create(Name,Val)); end; procedure TRTBFasmCompiler.TRTBFasmSource.DelConst(NameSpace:string;Name:string); var i:NativeUInt; begin if NameSpace<>'' then Name:=NameSpace+'.'+Name; if consts.Count<>0 then for i:=0 to consts.Count-1 do if consts.Items[i].Key=Name then begin consts.Delete(i); Break; end; end; procedure TRTBFasmCompiler.TRTBFasmSource.AddVariable(NameSpace:string;Name:string;var Data); begin if NameSpace<>'' then consts.Add(TPair.Create(NameSpace+'.'+Name,addr(Data))) else consts.Add(TPair.Create(Name,addr(Data))); end; procedure TRTBFasmCompiler.TRTBFasmSource.ExportVariable(NameSpace:string;Name:string;var Data); begin if NameSpace<>'' then consts.Add(TPair.Create(NameSpace+'.'+Name,Addr(Data))) else consts.Add(TPair.Create(Name,Addr(Data))); end; procedure TRTBFasmCompiler.TRTBFasmSource.DelVariable(NameSpace:string;Name:string); begin DelConst(NameSpace,Name); end; procedure TRTBFasmCompiler.TRTBFasmSource.&Register(NameSpace:string;Name:string;&Type:TRTBType); begin if NameSpace<>'' then regvars.Add(TPair.Create(NameSpace+'.'+Name,&Type)) else regvars.Add(TPair.Create(Name,&Type)); end; procedure TRTBFasmCompiler.TRTBFasmSource.UnRegister(NameSpace:string;Name:string); var i:NativeUInt; begin if NameSpace<>'' then Name:=NameSpace+'.'+Name; if regvars.Count<>0 then for i:=0 to regvars.Count-1 do if regvars.Items[i].Key=Name then begin regvars.Delete(i); Break; end; end; procedure TRTBFasmCompiler.TRTBFasmSource.RegisterFunction(NameSpace:string;Name:string); begin if NameSpace<>'' then funcs.Add(NameSpace+'.'+Name) else funcs.Add(Name); end; procedure TRTBFasmCompiler.TRTBFasmSource.UnRegisterFunction(NameSpace:string;Name:string); var i:NativeUInt; begin if NameSpace<>'' then Name:=NameSpace+'.'+Name; with funcs do Delete(IndexOf(Name)); end; {constructor TRTBLuaCompiler.TRTBLuaSource.TRTBLuaFunc.Create(p:Pointer;sb:NativeUInt); begin Self.p:=VirtualAlloc(nil,sb,MEM_COMMIT ,PAGE_EXECUTE_READWRITE); CopyMemory(Self.p,p,sb); Self.sb:=sb; FreeMem(p); end; function TRTBLuaCompiler.TRTBLuaSource.TRTBLuaFunc.Call(OutType:PTypeInfo;args:TArray;CallType:TRTBCallType=CRTBCallTypeDefault):TValue; begin end; destructor TRTBLuaCompiler.TRTBLuaSource.TRTBLuaFunc.Destroy; begin VirtualFree(p,sb,MEM_RELEASE); p:=nil; end; constructor TRTBLuaCompiler.TRTBLuaSource.TRTBLuaLib.TRTBLuaLibFunc.Create(p:Pointer); begin Self.p:=p; end; destructor TRTBLuaCompiler.TRTBLuaSource.TRTBLuaLib.TRTBLuaLibFunc.Destroy; begin p:=nil; end; function TRTBLuaCompiler.TRTBLuaSource.TRTBLuaLib.GetFuntion(Name:string):TRTBFunc; begin Result:=TRTBLuaLibFunc.Create(GetProcAddress(Lib,pwidechar(Name))); end; constructor TRTBLuaCompiler.TRTBLuaSource.TRTBLuaLib.Create(Name:string); begin filename:=Name; Lib:=LoadLibrary(pwidechar(Name)); end; destructor TRTBLuaCompiler.TRTBLuaSource.TRTBLuaLib.Destroy; begin FreeLibrary(Lib); end;} function TRTBLuaCompiler.TRTBLuaSource.GetText:string; begin Result:=FText; end; procedure TRTBLuaCompiler.TRTBLuaSource.SetText(S:string); begin FText:=S; end; constructor TRTBLuaCompiler.TRTBLuaSource.Create(Compiler:TRTBLuaCompiler); begin inherited Create(Compiler); FText:=''; end; function TRTBLuaCompiler.TRTBLuaSource.CompilateAsFunc:TRTBFunc; begin //lua_(lua_tocfunction()); //(Compiler as TRTBLuaCompiler).Lua.RegisterFunction(); end;*) {function TRTBLuaCompiler.GetIncLibs():string; var i:integer; begin Result:=''; for i:=0 to libs.count-1 do Result:=Result+sLineBreak+'include '+#39+libs.Strings[i]+#39; end;} constructor TRTBLuaCompiler.TRTBLuaSource.Create(Compiler:TRTBLuaCompiler); begin inherited Create(Compiler); FText:=''; libs:=TStringList.Create; funcs:=TStringList.Create; regvars:=TList>.Create; consts:=TList>.Create; end; procedure TRTBLuaCompiler.TRTBLuaSource.LoadLib(Name:string); begin libs.Add(Name); end; procedure TRTBLuaCompiler.TRTBLuaSource.UnLoadLib(Name:string); begin with libs do Delete(IndexOf(Name)); end; function TRTBLuaCompiler.TRTBLuaSource.Compilate:TRTBModule; procedure VarParse(key:string;value:TValue;var PreDecl:string;var base:NativeUInt); var i:NativeUInt; p0:PByte; begin if Value.IsType or Value.IsType or Value.IsType then begin PreDecl:=PreDecl+Key+' db '+#39+Value.AsType+#39+',0'+sLineBreak; inc(base,length(Value.AsType)); end else if Value.IsType then begin PreDecl:=PreDecl+Key+' db '+#39+Value.AsType+#39+',0'+sLineBreak; inc(base,length(Value.AsType)); end else if Value.IsType then begin PreDecl:=PreDecl+Key+' db '; p0:=Pointer(PWideChar(Value.AsType)); for i:={$IFDEF NEXTGEN}0{$ELSE}1{$ENDIF} to length(Value.AsType){$IFDEF NEXTGEN}-1{$ENDIF} do begin PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); end; PreDecl:=PreDecl+'0,0'+sLineBreak; inc(base,length(Value.AsType)*2); end else if Value.IsType then begin PreDecl:=PreDecl+Key+' db '; p0:=Pointer(PWideChar(Value.AsType)); for i:={$IFDEF NEXTGEN}0{$ELSE}1{$ENDIF} to length(Value.AsType){$IFDEF NEXTGEN}-1{$ENDIF} do begin PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); end; PreDecl:=PreDecl+'0,0,0,0'+sLineBreak; inc(base,length(Value.AsType)*4); end else if Value.IsOrdinal then case Value.DataSize of 1:PreDecl:=PreDecl+Key+' db '+Value.AsOrdinal.ToString+sLineBreak; 2:PreDecl:=PreDecl+Key+' dw '+Value.AsOrdinal.ToString+sLineBreak; 4:PreDecl:=PreDecl+Key+' dd '+Value.AsOrdinal.ToString+sLineBreak; 8:PreDecl:=PreDecl+Key+' dq '+Value.AsOrdinal.ToString+sLineBreak; end else if Value.Kind=tkFloat then begin if Value.IsType then PreDecl:=PreDecl+Key+' dd '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' dq '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+{$IF 8=SizeOf(Extended)}' dq '{$ELSEIF 10=SizeOf(Extended)}' dt '{$ELSE}' ddq '{$IFEND}+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' dq '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' df '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' dq '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' dq '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else PreDecl:=PreDecl+Key+' dd 0.0'+sLineBreak; end else if Value.Kind=tkPointer then PreDecl:=PreDecl+Key+' equ '+NativeUInt(Value.AsType).ToString+sLineBreak else if Value.IsArray then begin if Value.GetArrayLength=0 then begin PreDecl:=PreDecl+Key+' equ 0'+sLineBreak; end else begin PreDecl:=PreDecl+Key+':'+sLineBreak; for i:=0 to Value.GetArrayLength-1 do VarParse(key+'.i'+i.ToString,Value.GetArrayElement(i),PreDecl,Base); end; end {else if Value.Kind=tkRecord then begin PreDecl:=PreDecl+Key+':'+sLineBreak; for i:=1 to Value.TypeData.ManagedFldCount do end} else //if Value.Kind=tkUnknown then PreDecl:=PreDecl+Key+': times '+ Value.DataSize.ToString+' db 0'+sLineBreak; end; procedure ConstParse(key:string;value:TValue;var PreDecl:string;var base:NativeUInt); var i:NativeUInt; p0:PByte; begin if Value.IsType or Value.IsType or Value.IsType then begin PreDecl:=PreDecl+Key+' db '+#39+Value.AsType+#39+',0'+sLineBreak; inc(base,length(Value.AsType)); end else if Value.IsType then begin PreDecl:=PreDecl+Key+' db '+#39+Value.AsType+#39+',0'+sLineBreak; inc(base,length(Value.AsType)); end else if Value.IsType then begin PreDecl:=PreDecl+Key+' db '; p0:=Pointer(PWideChar(Value.AsType)); for i:={$IFDEF NEXTGEN}0{$ELSE}1{$ENDIF} to length(Value.AsType){$IFDEF NEXTGEN}-1{$ENDIF} do begin PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); end; PreDecl:=PreDecl+'0,0'+sLineBreak; inc(base,length(Value.AsType)*2); end else if Value.IsType then begin PreDecl:=PreDecl+Key+' db '; p0:=Pointer(PWideChar(Value.AsType)); for i:={$IFDEF NEXTGEN}0{$ELSE}1{$ENDIF} to length(Value.AsType){$IFDEF NEXTGEN}-1{$ENDIF} do begin PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); PreDecl:=PreDecl+inttostr(p0^)+','; inc(p0); end; PreDecl:=PreDecl+'0,0,0,0'+sLineBreak; inc(base,length(Value.AsType)*4); end else if Value.IsOrdinal then PreDecl:=PreDecl+Key+' equ '+Value.AsOrdinal.ToString+sLineBreak else if Value.Kind=tkFloat then begin if Value.IsType then PreDecl:=PreDecl+Key+' equ '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' equ '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' equ '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' equ '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' equ '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' equ '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else if Value.IsType then PreDecl:=PreDecl+Key+' equ '+FloatToStrF(Value.AsType,ffFixed,1000,1000)+sLineBreak else PreDecl:=PreDecl+Key+' equ 0.0'+sLineBreak; end else if Value.Kind=tkPointer then PreDecl:=PreDecl+Key+' equ '+NativeUInt(Value.AsType).ToString+sLineBreak else if Value.IsArray then begin if Value.GetArrayLength=0 then begin PreDecl:=PreDecl+Key+' equ 0'+sLineBreak; end else begin PreDecl:=PreDecl+Key+':'+sLineBreak; for i:=0 to Value.GetArrayLength-1 do VarParse(key+'.i'+i.ToString,Value.GetArrayElement(i),PreDecl,Base); end; end else //if Value.Kind=tkUnknown then PreDecl:=PreDecl+Key+' equ 0'+sLineBreak; end; var templib,PreDecl:string; i,sb:NativeUInt; RegVarDict:TDictionary>; p:pointer; begin {RegVarDict:=TDictionary>.Create(); with regvars do if Count<>0 then for i:=0 to Count-1 do begin PreDecl:=PreDecl+pointerDecl+Items[i].Key+sLineBreak; RegVarDict.Add(Items[i].Key,TPair.Create(base,Items[i].Value)); inc(base,SizeOf(pointer)); end; with consts do if Count<>0 then for i:=0 to Count-1 do with Items[i] do ConstParse(Key,Value,PreDecl,base);} //Result:=TRTBLuaModule.Create(FText,funcs); end; destructor TRTBLuaCompiler.TRTBLuaSource.Destroy; begin FreeAndNil(libs); FreeAndNil(funcs); FreeAndNil(regvars); FreeAndNil(consts); end; constructor TRTBLuaCompiler.Create(); begin inherited Create(); //Lua:=luaL_newstate; end; function TRTBLuaCompiler.GenNewSrc():TRTBSource; begin Result:=TRTBLuaSource.Create(Self); end; end.