Closed zamtmn closed 9 months ago
long time ago, when i try to achive lape to working state, i use construction like
Result := LapeCompiler.Compile();
....
if Result then
begin
PPCode := LapeCompiler.Emitter.Code;
CodeLen := LapeCompiler.Emitter.CodeLen;
end;
function TBaseLapeScriptThread.execfunction(ProcName : String; Params : array of Variant; IsEvent : Boolean = False) : Variant;
var ParamVars : TObjectList<TLapeGlobalVar>;
m : TLapeType_Method;
i : Integer;
VarStack2: lptypes.TByteArray;
function getVar(BaseType: TLapeType; Value: String) : lptypes.TByteArray;
var LapeVar : TLapeGlobalVar;
begin
LapeVar := BaseType.NewGlobalVarStr(Value);
ParamVars.Add(LapeVar);
SetLength(Result, LapeVar.Size);
Move(PPointer(LapeVar.Ptr)^, Result[0], LapeVar.Size);
end;
begin
if not Assigned(LapeCompiler) then
Exit;
if (not Assigned(LapeCompiler[ProcName])) then
begin
ExecEvMethodError := 'Error exec method: - Method with name "' + ProcName + '" is not exists!';
Exit;
end;
if not Assigned(LapeCompiler[ProcName].VarType) then
begin
ExecEvMethodError := 'Error exec method: - Method with name "' + ProcName + '" has incorrect type!';
Exit;
end;
m := TLapeType_Method(LapeCompiler[ProcName].VarType);
if Length(Params) < m.Params.Count then
begin
ExecEvMethodError := Format('Error exec method: Wrong number of parameters found (%d), expected %d',
[Length(Params), m.Params.Count]);
Exit;
end;
//pushing params & vars to stack
ParamVars := TObjectList<TLapeGlobalVar>.Create;
for i := 0 to m.Params.Count - 1 do
VarStack2 := VarStack2 + getVar(m.Params[i].VarType, VarToStr(Params[i]));
if Assigned(m.Res) then
VarStack2 := VarStack2 + getVar(m.Res, Result);
//lpinterpreter.pas
RunCode(PPCode, CodeLen, VarStack2, PCodePos(LapeCompiler[ProcName].Ptr)^);
ParamVars.Free;
if not ExecEvMethodError.IsEmpty and ValidObject(CharObj) then
Script_AddToSystemJournal(ExecEvMethodError);
end;
maybe will be useful for you.
You can do above, but you have to construct everything yourself.
Using lape's libffi interface is ideal for this. You can generate a native method which will call a script method.
Some lape code...
function test(a, b: Int32): String;
begin
Result := IntToStr(a) + '-' + IntToStr(b);
end;
In FPC after script has been compiled, this will call the above lape function
uses
lpffiwrappers;
type
TMyTest = function(a, b: Integer): String;
WriteLn(TMyTest(LapeExportWrapper(Compiler['test']).Func)(123,456));
methodType := TLapeType_Method(TLapeGlobalVar(Compiler['Test']).VarType);
WriteLn(methodType.Params.Count);
WriteLn(methodType.Params[0].VarType.Name);
WriteLn(methodType.Res.Name);
Thanks! It's nice to have a quick response!
Using lape's libffi interface is ideal for this.
yes, if you use lape only in windows :)
doesn't ffi work on linux?
it does work fine on other platforms.
it does work fine on other platforms.
But not all of them, thats why i have to do those strange things with script methods execution :)
Do you have any examples? All current tests pass
Do you have any examples? All current tests pass
Thanks! This can be closed. If there are problems, I will make a new report
Do we have the opportunity to run a separate function in script without running the script as a whole? naturally, from native pascal code, send the parameters to her and taking the result? Please show an example of doing this if possible