home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 November / Chip_2002-11_cd1.bin / zkuste / delphi / kompon / d456 / CAJSCRPT.ZIP / ifps3 / ifpiclassruntime.pas < prev    next >
Pascal/Delphi Source File  |  2002-07-22  |  47KB  |  1,744 lines

  1. {Classes runtime unit}
  2. unit ifpiclassruntime;
  3. {
  4. Innerfuse Pascal Script III
  5. Copyright (C) 2000-2002 by Carlo Kok (ck@carlo-kok.com)
  6. }
  7. {$I ifps3_def.inc}
  8. interface
  9. uses ifps3, ifps3utl, ifps3common, ifpicall;
  10.  
  11. type
  12.   {TIFPSRuntimeClass is one class at runtime}
  13.   TIFPSRuntimeClass = class
  14.   private
  15.     FClassName: string;
  16.     FClassNameHash: Longint;
  17.  
  18.     FClassItems: TIFList;
  19.     FClass: TClass;
  20.  
  21.     FEndOfVmt: Longint;
  22.   public
  23.     {Register a constructor}
  24.     procedure RegisterConstructor(ProcPtr: Pointer; const Name: string);
  25.     {Register a virtual constructor}
  26.     procedure RegisterVirtualConstructor(ProcPtr: Pointer; const Name: string);
  27.     {Register a method}
  28.     procedure RegisterMethod(ProcPtr: Pointer; const Name: string);
  29.     {Register a virtual method}
  30.     procedure RegisterVirtualMethod(ProcPtr: Pointer; const Name: string);
  31.     {Register an abstract virtual method}
  32.     procedure RegisterVirtualAbstractMethod(ClassDef: TClass; ProcPtr: Pointer; const Name: string);
  33.     {Register a property helper}
  34.     procedure RegisterPropertyHelper(ReadFunc, WriteFunc: Pointer; const Name: string);
  35.     {Register a property helper that is an event}
  36.     procedure RegisterEventPropertyHelper(ReadFunc, WriteFunc: Pointer; const Name: string);
  37.     {create}
  38.     constructor Create(aClass: TClass);
  39.     {destroy}
  40.     destructor Destroy; override;
  41.   end;
  42.   {TIFPSRuntimeClassImporter is the runtime class importer}
  43.   TIFPSRuntimeClassImporter = class
  44.   private
  45.     FClasses: TIFList;
  46.   public
  47.     {create}
  48.     constructor Create;
  49.     {destroy}
  50.     destructor Destroy; override;
  51.     {Add a class}
  52.     function Add(aClass: TClass): TIFPSRuntimeClass;
  53.     {Clear}
  54.     procedure Clear;
  55.     {Search for a class}
  56.     function FindClass(const Name: string): TIFPSRuntimeClass;
  57.   end;
  58.  
  59.  
  60. {Register the classes at runtime}
  61. procedure RegisterClassLibraryRuntime(SE: TIFPSExec; Importer: TIFPSRuntimeClassImporter);
  62. {Set a runtime variant}
  63. procedure SetVariantToClass(V: PIFVariant; Cl: TObject);
  64. {Return the RPFuncs for other libraries}
  65. function ClassRuntimeGetRPFuncs: PResourcePtrSupportFuncs;
  66.  
  67. {Internal function: Script Event Handler}
  68. procedure MyAllMethodsHandler;
  69. {Internal Function: Returns the Data pointer of a TMethod for a ProcNo}
  70. function GetMethodInfoRec(SE: TIFPSExec; ProcNo: Cardinal): Pointer;
  71.  
  72. implementation
  73. uses
  74.   SysUtils, TypInfo, ifpidelphiruntime;
  75.  
  76. type
  77.   TIFPSExecHack = class (TIFPSExec) end;
  78.   PScriptMethodInfo = ^TScriptMethodInfo;
  79.   TScriptMethodInfo = record
  80.     Se: TIFPSExecHack;
  81.     ProcNo: Cardinal;
  82.   end;
  83.  
  84. procedure PFree(Sender: TIFPSExec; P: PScriptMethodInfo);
  85. begin
  86.   Dispose(p);
  87. end;
  88.  
  89. function GetMethodInfoRec(SE: TIFPSExec; ProcNo: Cardinal): Pointer;
  90. var
  91.   I: Longint;
  92.   pp: PScriptMethodInfo;
  93. begin
  94.   I := 0;
  95.   repeat
  96.     pp := Se.FindProcResource2(@PFree, I);
  97.     if (i <> -1) and (pp^.ProcNo = ProcNo) then
  98.     begin
  99.       Result := Pp;
  100.       exit;
  101.     end;
  102.   until i = -1;
  103.   New(pp);
  104.   pp^.Se := TIFPSExecHack(Se);
  105.   pp^.ProcNo := Procno;
  106.   Se.AddResource(@PFree, pp);
  107.   Result := pp;
  108. end;
  109.  
  110. function DummyResourceFree(FMode: TVRFMode; P, IntoP: PIFVariant): Boolean;
  111. begin
  112.   if FMode = vrfDuplicate then
  113.   begin
  114.     IntoP.tResourceP1 := p.tResourceP1;
  115.     IntoP.tResourceFreeProc := p.tResourceFreeProc;
  116.   end;
  117.   Result := True;
  118. end;
  119.  
  120. function ResourcePtrToStr(PSelf: PResourcePtrSupportFuncs; Sender: TIFPSExec; P: PIFVariant): string;
  121. begin
  122.   SetLength(Result, 4);
  123.   Pointer((@Result[1])^) := P^.tResourceP1;
  124. end;
  125.  
  126. function VarResourcePtrToStr(PSelf: PResourcePtrSupportFuncs; Sender: TIFPSExec; P: PIFVariant): string;
  127. begin
  128.   SetLength(Result, 4);
  129.   Pointer((@Result[1])^) := @P^.tResourceP1;
  130.   p^.tResourceFreeProc := DummyResourceFree;
  131. end;
  132.  
  133. procedure ResultToResourcePtr(PSelf: PResourcePtrSupportFuncs; Sender: TIFPSExec; Data: Longint; P: PIFVariant);
  134. begin
  135.   if Data = 0 then
  136.   begin
  137.     p^.tResourceP1 := nil;
  138.     p^.tResourceFreeProc := nil;
  139.   end else
  140.   begin
  141.     p^.tResourceP1 := Pointer(Data);
  142.     p^.tResourceFreeProc := DummyResourceFree;
  143.   end;
  144. end;
  145.  
  146. const
  147.   ResourcePtrSupport: TResourcePtrSupportFuncs = (
  148.     ptr: nil;
  149.     PtrToStr: ResourcePtrToStr;
  150.     VarPtrToStr: VarResourcePtrToStr;
  151.     ResultMethod: rmRegister;
  152.     ResToPtr: ResultToResourcePtr);
  153.  
  154. function ClassRuntimeGetRPFuncs: PResourcePtrSupportFuncs;
  155. begin
  156.   Result := @ResourcePtrSupport;
  157. end;
  158.  
  159. type
  160.   TPtrArr = array[0..1000] of Pointer;
  161.   PPtrArr = ^TPtrArr;
  162.   TByteArr = array[0..1000] of byte;
  163.   PByteArr = ^TByteArr;
  164.   PPointer = ^Pointer;
  165.  
  166.  
  167. function VirtualMethodPtrToPtr(Ptr, FSelf: Pointer): Pointer;
  168. begin
  169.   Result := PPtrArr(PPointer(FSelf)^)^[Longint(Ptr)];
  170. end;
  171.  
  172. function VirtualClassMethodPtrToPtr(Ptr, FSelf: Pointer): Pointer;
  173. begin
  174.   Result := PPtrArr(FSelf)^[Longint(Ptr)];
  175. end;
  176.  
  177.  
  178. procedure CheckPackagePtr(var P: PByteArr);
  179. begin
  180.   if (word((@p[0])^) = $25FF) and (word((@p[6])^)=$C08B)then
  181.   begin
  182.     p := PPointer((@p[2])^)^;
  183.   end;
  184. end;
  185.  
  186. function FindVirtualMethodPtr(Ret: TIFPSRuntimeClass; FClass: TClass; Ptr: Pointer): Pointer;
  187. // Idea of getting the number of VMT items from GExperts
  188. var
  189.   p: PPtrArr;
  190.   I: Longint;
  191. begin
  192.   p := Pointer(FClass);
  193.   CheckPackagePtr(PByteArr(Ptr));
  194.   if Ret.FEndOfVMT = MaxInt then
  195.   begin
  196.     I := {$IFDEF VER90}-48{$ELSE}vmtSelfPtr{$ENDIF} div SizeOf(Pointer) + 1;
  197.     while I < 0 do
  198.     begin
  199.       if I < 0 then
  200.       begin
  201.         if I <> ({$IFDEF VER90}-44{$ELSE}vmtTypeInfo{$ENDIF} div SizeOf(Pointer)) then
  202.         begin // from GExperts code
  203.           if (Longint(p^[I]) > Longint(p)) and ((Longint(p^[I]) - Longint(p))
  204.             div
  205.             4 < Ret.FEndOfVMT) then
  206.           begin
  207.             Ret.FEndOfVMT := (Longint(p^[I]) - Longint(p)) div SizeOf(Pointer);
  208.           end;
  209.         end;
  210.       end;
  211.       Inc(I);
  212.     end;
  213.     if Ret.FEndOfVMT = MaxInt then
  214.     begin
  215.       Ret.FEndOfVMT := 0; // cound not find EndOfVMT
  216.       Result := nil;
  217.       exit;
  218.     end;
  219.   end;
  220.   I := 0;
  221.   while I < Ret.FEndOfVMT do
  222.   begin
  223.     if p^[I] = Ptr then
  224.     begin
  225.       Result := Pointer(I);
  226.       exit;
  227.     end;
  228.     I := I + 1;
  229.   end;
  230.   Result := nil;
  231. end;
  232.  
  233.  
  234. type
  235.   PClassItem = ^TClassItem;
  236.   TClassItem = record
  237.     FName: string;
  238.     FNameHash: Longint;
  239.     b: byte;
  240.     case byte of
  241.     0: (Ptr: Pointer); {Method}
  242.     1: (PointerInList: Pointer); {Virtual Method}
  243.     3: (FReadFunc, FWriteFunc: Pointer); {Property Helper}
  244.     4: (Ptr2: Pointer); {Constructor}
  245.     5: (PointerInList2: Pointer); {virtual constructor}
  246.     6: (); {Property helper, like 3}
  247.   end;
  248.  
  249.  
  250. function ClassCallProc01(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  251. var
  252.   i: Integer;
  253.   MyList: TIfList;
  254.   n: PIFVariant;
  255.   FSelf: Pointer;
  256.   CurrStack: Cardinal;
  257.   cc: TCallingConvention;
  258.   s: string;
  259. begin
  260.   s := p^.ExportDecl;
  261.   if length(S) < 2 then
  262.   begin
  263.     Result := False;
  264.     exit;
  265.   end;
  266.   cc := TCallingConvention(s[1]);
  267.   delete(s, 1, 1);
  268.   if s[1] = #0 then
  269.     n := Stack.GetItem(Stack.Count -1)
  270.   else
  271.     n := Stack.GetItem(Stack.Count -2);
  272.   if (n = nil) or (n^.Ftype^.BaseType <> btResourcePointer) or (@n^.tResourceFreeProc <> @DummyResourceFree) or (n^.tresourcep1 = nil) then
  273.   begin
  274.     result := false;
  275.     exit;
  276.   end;
  277.   FSelf := n^.tResourceP1;
  278.   CurrStack := Stack.Count - Cardinal(length(s)) -1;
  279.   if s[1] = #0 then inc(CurrStack);
  280.   MyList := tIfList.Create;
  281.   for i := 2 to length(s) do
  282.   begin
  283.     MyList.Add(nil);
  284.   end;
  285.   for i := length(s) downto 2 do
  286.   begin
  287.     n :=Stack.GetItem(CurrStack);
  288.     if s[i] <> #0 then
  289.     begin
  290.       n^.RefCount := n^.RefCount or IFPSAddrStackStart;
  291.     end;
  292.     MyList.SetItem(i - 2, n);
  293.     inc(CurrStack);
  294.   end;
  295.   try
  296.     if s[1] <> #0 then
  297.     begin
  298.       n := Stack.GetItem(CurrStack + 1);
  299.     end else n := nil;
  300.     if p^.Ext2 = nil then
  301.       InnerfuseCall(Caller, FSelf, p^.Ext1, cc, MyList, n, @ResourcePtrSupport)
  302.     else
  303.       InnerfuseCall(Caller, FSelf, VirtualMethodPtrToPtr(p^.Ext1, FSelf), cc, MyList, n, @ResourcePtrSupport);
  304.     result := true;
  305.   except
  306.     result := false;
  307.   end;
  308.   MyList.Free;
  309. end;
  310.  
  311. const
  312.   IntType: TIFTypeRec = (BaseType: btU32);
  313.   IntVal: TIFVariant = (FType: @IntType; RefCount: 1; tu32: 1);
  314.  
  315.  
  316. function ClassCallProc04(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  317. var
  318.   i, h: Longint;
  319.   MyList: TIfList;
  320.   n: PIFVariant;
  321.   FSelf: Pointer;
  322.   CurrStack: Cardinal;
  323.   cc: TCallingConvention;
  324.   s: string;
  325.   FType: PIFTypeRec;
  326.   x: TIFPSRuntimeClass;
  327. begin
  328.   n := Stack.GetItem(Stack.Count -2);
  329.   if (n = nil) or (n^.Ftype^.BaseType <> btU32)  then
  330.   begin
  331.     result := false;
  332.     exit;
  333.   end;
  334.   FType := Caller.GetTypeNo(N^.tu32);
  335.   if (FType = nil)  then
  336.   begin
  337.     Result := False;
  338.     exit;
  339.   end;
  340.   h := MakeHash(FType^.ExportName);
  341.   FSelf := nil;
  342.   for i := 0 to TIFPSRuntimeClassImporter(p^.Ext2).FClasses.Count -1 do
  343.   begin
  344.     x:= TIFPSRuntimeClassImporter(p^.Ext2).FClasses.GetItem(i);
  345.     if (x.FClassNameHash = h) and (x.FClassName = FType^.ExportName) then
  346.     begin
  347.       FSelf := x.FClass;
  348.     end;
  349.   end;
  350.   if FSelf = nil then begin
  351.     Result := False;
  352.     exit;
  353.   end;
  354.   s := p^.ExportDecl;
  355.   if length(S) < 2 then
  356.   begin
  357.     Result := False;
  358.     exit;
  359.   end;
  360.   cc := TCallingConvention(s[1]);
  361.   delete(s, 1, 1);
  362.   CurrStack := Stack.Count - Cardinal(length(s)) -1;
  363. //CurrStack := Stack.Count - Cardinal(length(s));
  364.   if s[1] = #0 then inc(CurrStack);
  365.   MyList := tIfList.Create;
  366.   MyList.Add(@IntVal);
  367.   for i := 2 to length(s) do
  368.   begin
  369.     MyList.Add(nil);
  370.   end;
  371.   for i := length(s) downto 2 do
  372.   begin
  373.     n :=Stack.GetItem(CurrStack);
  374.     if s[i] <> #0 then
  375.     begin
  376.       n^.RefCount := n^.RefCount or IFPSAddrStackStart;
  377.     end;
  378.     MyList.SetItem(i - 1, n);
  379.     inc(CurrStack);
  380.   end;
  381.   try
  382.     if s[1] <> #0 then
  383.     begin
  384.       n := Stack.GetItem(CurrStack +1);
  385.     end else n := nil;
  386.     InnerfuseCall(Caller, FSelf, p^.Ext1, cc, MyList, n, @ResourcePtrSupport);
  387.     result := true;
  388.   except
  389.     result := false;
  390.   end;
  391.   MyList.Free;
  392. end;
  393. function ClassCallProc05(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  394. var
  395.   i, h: Longint;
  396.   MyList: TIfList;
  397.   n: PIFVariant;
  398.   FSelf: Pointer;
  399.   CurrStack: Cardinal;
  400.   cc: TCallingConvention;
  401.   s: string;
  402.   FType: PIFTypeRec;
  403.   x: TIFPSRuntimeClass;
  404. begin
  405.   n := Stack.GetItem(Stack.Count -2);
  406.   if (n = nil) or (n^.Ftype^.BaseType <> btU32)  then
  407.   begin
  408.     result := false;
  409.     exit;
  410.   end;
  411.   FType := Caller.GetTypeNo(N^.tu32);
  412.   if (FType = nil)  then
  413.   begin
  414.     Result := False;
  415.     exit;
  416.   end;
  417.   h := MakeHash(FType^.ExportName);
  418.   FSelf := nil;
  419.   for i := 0 to TIFPSRuntimeClassImporter(p^.Ext2).FClasses.Count -1 do
  420.   begin
  421.     x:= TIFPSRuntimeClassImporter(p^.Ext2).FClasses.GetItem(i);
  422.     if (x.FClassNameHash = h) and (x.FClassName = FType^.ExportName) then
  423.     begin
  424.       FSelf := x.FClass;
  425.       Break;
  426.     end;
  427.   end;
  428.   if FSelf = nil then begin
  429.     Result := False;
  430.     exit;
  431.   end;
  432.   s := p^.ExportDecl;
  433.   if length(S) < 2 then
  434.   begin
  435.     Result := False;
  436.     exit;
  437.   end;
  438.   cc := TCallingConvention(s[1]);
  439.   delete(s, 1, 1);
  440.   CurrStack := Stack.Count - Cardinal(length(s)) -1;
  441.   if s[1] = #0 then inc(CurrStack);
  442.   MyList := tIfList.Create;
  443.   MyList.Add(@IntVal);
  444.   for i := 2 to length(s) do
  445.   begin
  446.     MyList.Add(nil);
  447.   end;
  448.   for i := length(s) downto 2 do
  449.   begin
  450.     n :=Stack.GetItem(CurrStack);
  451.     if s[i] <> #0 then
  452.     begin
  453.       n^.RefCount := n^.RefCount or IFPSAddrStackStart;
  454.     end;
  455.     MyList.SetItem(i - 1, n);
  456.     inc(CurrStack);
  457.   end;
  458.   try
  459.     if s[1] <> #0 then
  460.     begin
  461.       n := Stack.GetItem(CurrStack + 1);
  462.     end else n := nil;
  463.     InnerfuseCall(Caller, FSelf, VirtualClassMethodPtrToPtr(p^.Ext1, FSelf), cc, MyList, n, @ResourcePtrSupport);
  464.     result := true;
  465.   except
  466.     result := false;
  467.   end;
  468.   MyList.Free;
  469. end;
  470.  
  471. function CastProc(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  472. var
  473.   TypeNo, InVar, ResVar: PIFVariant;
  474.   FSelf: TClass;
  475.   FType: PIFTypeRec;
  476.   H, I: Longint;
  477.   x: TIFPSRuntimeClass;
  478. begin
  479.   TypeNo := Stack.GetItem(Stack.Count-3);
  480.   InVar := Stack.GetItem(Stack.Count-2);
  481.   ResVar := Stack.GetItem(Stack.Count-1);
  482.   if (TypeNo = nil) or (InVar = nil) or (ResVar = nil) or (InVar^.FType^.BaseType <> btResourcePointer) or (ResVar^.FType^.BaseType <> btResourcePointer) or (TypeNo^.FType^.BaseType <> btu32) then
  483.   begin
  484.     Result := False;
  485.     Exit;
  486.   end;
  487.   if InVar^.tResourceP1 = nil then
  488.   begin
  489.     ResVar^.tResourceP1 := nil;
  490.     ResVar^.tResourceFreeProc:= nil;
  491.     result := True;
  492.     exit;
  493.   end;
  494.   FType := Caller.GetTypeNo(TypeNo^.tu32);
  495.   if (FType = nil)  then
  496.   begin
  497.     Result := False;
  498.     exit;
  499.   end;
  500.   h := MakeHash(FType^.ExportName);
  501.   FSelf := nil;
  502.   for i := 0 to TIFPSRuntimeClassImporter(p^.Ext2).FClasses.Count -1 do
  503.   begin
  504.     x:= TIFPSRuntimeClassImporter(p^.Ext2).FClasses.GetItem(i);
  505.     if (x.FClassNameHash = h) and (x.FClassName = FType^.ExportName) then
  506.     begin
  507.       FSelf := x.FClass;
  508.     end;
  509.   end;
  510.   if FSelf = nil then begin
  511.     Result := False;
  512.     exit;
  513.   end;
  514.   ResVar^.tResourceFreeProc := DummyResourceFree;
  515.   try
  516.     resVar^.tResourceP1 := TObject(InVar^.tResourceP1) as FSelf;
  517.   except
  518.     Result := False;
  519.     exit;
  520.   end;
  521.   result := True;
  522. end;
  523.  
  524. function CompareProc(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  525. var
  526.   p1, p2, pres: PIFVariant;
  527. begin
  528.   p1 := Stack.GetItem(Stack.Count -3);
  529.   p2 := Stack.GetItem(Stack.Count -2);
  530.   pres := Stack.GetItem(Stack.Count -1);
  531.   if (p1=nil) or (p2=nil) or (pres = nil) or (p1^.FType^.BaseType <> btResourcePointer) or (p2^.FType^.BaseType <> btResourcePointer) or (pres^.FType^.BaseType <> btu8) then
  532.   begin
  533.     Result := False;
  534.     exit;
  535.   end;
  536.   if (p1^.tResourceP1 = p2^.tResourceP1) and (@p1^.tResourceFreeProc = @p2^.tResourceFreeProc) then
  537.     pres^.tu32 := 1
  538.   else
  539.     pres^.tu32 := 0;
  540.   Result := True;
  541. end;
  542.  
  543. function NilProc(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  544. var
  545.   n: PIFVariant;
  546. begin
  547.   n := Stack.GetItem(Stack.Count-1);
  548.   if (n = nil) or (n^.FType^.BaseType <> btResourcePointer) then
  549.   begin
  550.     Result := False;
  551.     Exit;
  552.   end;
  553.   n^.tResourceP1 := nil;
  554.   n^.tResourceFreeProc := nil;
  555.   result := True;
  556. end;
  557.  
  558. function MkMethod(FSE: TIFPSExec; No: Cardinal): TMethod;
  559. begin
  560.   if no = 0 then
  561.   begin
  562.     Result.Code := nil;
  563.     Result.Data := nil;
  564.   end else begin
  565.     Result.Code := @MyAllMethodsHandler;
  566.     Result.Data := GetMethodInfoRec(FSE, No);
  567.   end;
  568. end;
  569.  
  570. function getMethodNo(P: TMethod): Cardinal;
  571. begin
  572.   if (p.Code <> @MyAllMethodsHandler) or (p.Data = nil) then
  573.     Result := 0
  574.   else
  575.   begin
  576.     Result := PScriptMethodInfo(p.Data)^.ProcNo;
  577.   end;
  578. end;
  579.  
  580. function ClassCallProc2(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  581. var
  582.   n: PIFVariant;
  583.   FSelf: Pointer;
  584. begin
  585.   if p^.Ext2 = Pointer(0) then
  586.   begin
  587.     n := Stack.GetItem(Stack.Count -1);
  588.     if (n = nil) or (n^.Ftype^.BaseType <> btResourcePointer) or (@n^.tResourceFreeProc <> @DummyResourceFree) then
  589.     begin
  590.       result := false;
  591.       exit;
  592.     end;
  593.     FSelf := n^.tResourceP1;
  594.     n := Stack.GetItem(Stack.Count -2);
  595.     if (PPropInfo(p^.Ext1)^.PropType^.Kind = tkMethod) and (n^.FType^.BaseType = btu32) then
  596.     begin
  597.         SetMethodProp(TObject(FSelf), PPropInfo(p^.Ext1), MkMethod(Caller, n^.tu32));
  598.     end else
  599.     case n^.FType^.BaseType of
  600.       btU8: SetOrdProp(TObject(FSelf), PPropInfo(p^.Ext1), n^.tu8);
  601.       btS8: SetOrdProp(TObject(FSelf), PPropInfo(p^.Ext1), n^.ts8);
  602.       btU16: SetOrdProp(TObject(FSelf), PPropInfo(p^.Ext1), n^.tu16);
  603.       btS16: SetOrdProp(TObject(FSelf), PPropInfo(p^.Ext1), n^.ts16);
  604.       btU32: SetOrdProp(TObject(FSelf), PPropInfo(p^.Ext1), n^.tu32);
  605.       btS32: SetOrdProp(TObject(FSelf), PPropInfo(p^.Ext1), n^.ts32);
  606.       btSingle: SetFloatProp(TObject(FSelf), p^.Ext1, n^.tsingle);
  607.       btDouble: SetFloatProp(TObject(FSelf), p^.Ext1, n^.tdouble);
  608.       btExtended: SetFloatProp(TObject(FSelf), p^.Ext1, Extended(n^.textended));
  609.       btString: SetStrProp(TObject(FSelf), p^.Ext1, string(n^.tstring));
  610.       btPChar: SetStrProp(TObject(FSelf), p^.Ext1, string(n^.tstring));
  611.       btResourcePointer:
  612.       begin
  613.         if (@n^.tResourceFreeProc = nil) then
  614.           SetOrdProp(TObject(FSelf), p^.Ext1, Longint(n^.tResourceP1))
  615.         else if @n^.tResourceFreeProc = @DummyResourceFree then
  616.           SetOrdProp(TObject(FSelf), p^.Ext1, Longint(n^.tResourceP1))
  617.         else begin
  618.           Result := False;
  619.           exit;
  620.         end;
  621.  
  622.       end;
  623.       else
  624.       begin
  625.         Result := False;
  626.         exit;
  627.       end;
  628.     end;
  629.     Result := true;
  630.   end else begin
  631.     n := Stack.GetItem(Stack.Count -2);
  632.     if (n = nil) or (n^.Ftype^.BaseType <> btResourcePointer) or (@n^.tResourceFreeProc <> @DummyResourceFree) then
  633.     begin
  634.       result := false;
  635.       exit;
  636.     end;
  637.     FSelf := n^.tResourceP1;
  638.     n := Stack.GetItem(Stack.Count -1);
  639.     if (PPropInfo(p^.Ext1)^.PropType^.Kind = tkMethod) and (n^.FType^.BaseType = btu32) then
  640.     begin
  641.       n^.tu32 := GetMethodNo(GetMethodProp(TObject(FSelf), PPropInfo(p^.Ext1)));
  642.     end else
  643.     case n^.FType^.BaseType of
  644.       btU8: n^.tu8 := GetOrdProp(TObject(FSelf), p^.Ext1);
  645.       btS8: n^.tS8 := GetOrdProp(TObject(FSelf), p^.Ext1);
  646.       btU16: n^.tu16 := GetOrdProp(TObject(FSelf), p^.Ext1);
  647.       btS16: n^.tS16 := GetOrdProp(TObject(FSelf), p^.Ext1);
  648.       btU32: n^.tu32 := GetOrdProp(TObject(FSelf), p^.Ext1);
  649.       btS32: n^.tS32 := GetOrdProp(TObject(FSelf), p^.Ext1);
  650.       btSingle: n^.tsingle := GetFloatProp(TObject(FSelf), p^.Ext1);
  651.       btDouble: n^.tdouble := GetFloatProp(TObject(FSelf), p^.Ext1);
  652.       btExtended: n^.textended := GetFloatProp(TObject(FSelf), p^.Ext1);
  653.       btString: string(n^.tstring) := GetStrProp(TObject(FSelf), p^.Ext1);
  654.       btPChar: string(n^.tstring) := GetStrProp(TObject(FSelf), p^.Ext1);
  655.       btResourcePointer:
  656.       begin
  657.         n^.tResourceP1 := Pointer(GetOrdProp(TObject(FSelf), p^.Ext1));
  658.         n^.tResourceFreeProc := DummyResourceFree;
  659.       end;
  660.     else
  661.       begin
  662.         Result := False;
  663.         exit;
  664.       end;
  665.  
  666.     end;
  667.     Result := True;
  668.   end;
  669. end;
  670.  
  671. function ClassCallProc3(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  672. var
  673.   I, ParamCount: Longint;
  674.   Params: TIfList;
  675.   n: PIfVariant;
  676.   FSelf: Pointer;
  677. begin
  678.   if Length(P^.ExportDecl) < 4 then begin
  679.     Result := False;
  680.     exit;
  681.   end;
  682.   ParamCount := Longint((@P^.ExportDecl[1])^);
  683.   if Longint(Stack.Count) < ParamCount +1 then begin
  684.     Result := False;
  685.     exit;
  686.   end;
  687.   Dec(ParamCount);
  688.   if p^.Ext1 <> nil then // read
  689.   begin
  690.     n := Stack.GetItem(Longint(Stack.Count) - 2);
  691.     if (n = nil) or (n^.Ftype^.BaseType <> btResourcePointer) or (@n^.tResourceFreeProc <> @DummyResourceFree) then
  692.     begin
  693.       result := false;
  694.       exit;
  695.     end;
  696.     FSelf := n^.tResourceP1;
  697.     Params := TIfList.Create;
  698.     n := Stack.GetItem(Longint(Stack.Count) - 1); // Result
  699.     n^.RefCount := n^.RefCount or IFPSAddrStackStart;
  700.     Params.Add(n);
  701.     for i := Stack.Count -3 downto Longint(Stack.Count) - ParamCount -2 do
  702.     begin
  703.       n := Stack.GetItem(I);
  704.       Params.Add(n);
  705.     end;
  706.     InnerfuseCall(Caller, FSelf, p^.Ext1, ccRegister, Params, nil, @ResourcePtrSupport);
  707.     Params.Free;
  708.     Result := True;
  709.   end else begin
  710.     n := Stack.GetItem(Stack.Count -1);
  711.     if (n = nil) or (n^.Ftype^.BaseType <> btResourcePointer) or (@n^.tResourceFreeProc <> @DummyResourceFree) then
  712.     begin
  713.       result := false;
  714.       exit;
  715.     end;
  716.     FSelf := n^.tResourceP1;
  717.     Params := TIfList.Create;
  718.     Params.Add(Stack.GetItem(Longint(Stack.Count) - ParamCount - 2));
  719.  
  720.     for i := Stack.Count -2 downto Longint(Stack.Count) - ParamCount -1 do
  721.     begin
  722.       Params.Add(Stack.GetItem(I));
  723.     end;
  724.     InnerfuseCall(Caller, FSelf, p^.Ext2, ccregister, Params, nil, @ResourcePtrSupport);
  725.     Params.Free;
  726.     Result := True;
  727.   end;
  728. end;
  729.  
  730.  
  731. const
  732.   TMethodType: TIFTypeRec = (Ext: nil; BaseType: btDouble);
  733.  
  734.  
  735. function ClassCallProc06(Caller: TIFPSExec; p: PIFProcRec; Global, Stack: TIfList): Boolean;
  736. {Event property helper}
  737. var
  738.   I, ParamCount: Longint;
  739.   Params: TIfList;
  740.   n, n2: PIfVariant;
  741.   FSelf: Pointer;
  742. begin
  743.   if Length(P^.ExportDecl) < 4 then begin
  744.     Result := False;
  745.     exit;
  746.   end;
  747.   ParamCount := Longint((@P^.ExportDecl[1])^);
  748.   if Longint(Stack.Count) < ParamCount +1 then begin
  749.     Result := False;
  750.     exit;
  751.   end;
  752.   Dec(ParamCount);
  753.   if p^.Ext1 <> nil then // read
  754.   begin
  755.     n := Stack.GetItem(Longint(Stack.Count) - 2);
  756.     if (n = nil) or (n^.Ftype^.BaseType <> btResourcePointer) or (@n^.tResourceFreeProc <> @DummyResourceFree) then
  757.     begin
  758.       result := false;
  759.       exit;
  760.     end;
  761.     FSelf := n^.tResourceP1;
  762.     n := Stack.GetItem(Longint(Stack.Count) - 1); // Result
  763.     if n^.FType^.BaseType <> btU32 then
  764.     begin
  765.       Result := False;
  766.       exit;
  767.     end;
  768.     Params := TIfList.Create;
  769.     new(n2);
  770.     n2^.FType := @TMethodType;
  771.     n2^.RefCount := 1 + IFPSAddrStackStart;
  772.     TMethod(n2^.tdouble).Code := nil;
  773.     TMethod(n2^.tdouble).Data := nil;
  774.     Params.Add(n2);
  775.     for i := Stack.Count -3 downto Longint(Stack.Count) - ParamCount -2 do
  776.     begin
  777.       n := Stack.GetItem(I);
  778.       Params.Add(n);
  779.     end;
  780.     InnerfuseCall(Caller, FSelf, p^.Ext1, ccRegister, Params, nil, @ResourcePtrSupport);
  781.     n^.tu32 := getMethodNo(TMethod(n2^.tdouble));
  782.     Params.Free;
  783.     Result := True;
  784.   end else begin
  785.     n := Stack.GetItem(Stack.Count -1);
  786.     if (n = nil) or (n^.Ftype^.BaseType <> btResourcePointer) or (@n^.tResourceFreeProc <> @DummyResourceFree) then
  787.     begin
  788.       result := false;
  789.       exit;
  790.     end;
  791.     FSelf := n^.tResourceP1;
  792.     n := Stack.GetItem(Longint(Stack.Count) - ParamCount - 2);
  793.     if n^.FType^.BaseType <> btu32 then
  794.     begin
  795.       result := false;
  796.       exit;
  797.     end;
  798.     new(n2);
  799.     n2^.FType := @TMethodType;
  800.     n2^.RefCount := 1;
  801.     TMethod(n2^.tdouble) := MkMethod(Caller, n^.tu32);
  802.     Params := TIfList.Create;
  803.     Params.Add(n2);
  804.  
  805.     for i := Stack.Count -2 downto Longint(Stack.Count) - ParamCount -1 do
  806.     begin
  807.       Params.Add(Stack.GetItem(I));
  808.     end;
  809.     InnerfuseCall(Caller, FSelf, p^.Ext2, ccregister, Params, nil, @ResourcePtrSupport);
  810.     Dispose(n2);
  811.     Params.Free;
  812.     Result := True;
  813.   end;
  814. end;
  815.  
  816.  
  817. {'class:'+CLASSNAME+'|'+FUNCNAME+'|'+chr(CallingConv)+chr(hasresult)+params
  818.  
  819. For property write functions there is an '@' after the funcname.
  820. }
  821. function SpecImport(Sender: TIFPSExec; p: PIFProcRec; Tag: Pointer): Boolean;
  822. var
  823.   H, I: Longint;
  824.   S, s2: string;
  825.   CL: TIFPSRuntimeClass;
  826.   Px: PClassItem;
  827.   pp: PPropInfo;
  828.   IsRead: Boolean;
  829. begin
  830.   s := p^.ExportDecl;
  831.   delete(s, 1, 6);
  832.   if s = '-' then {nil function}
  833.   begin
  834.     p^.ProcPtr := NilProc;
  835.     Result := True;
  836.     exit;
  837.   end;
  838.   if s = '+' then {cast function}
  839.   begin
  840.     p^.ProcPtr := CastProc;
  841.     p^.Ext2 := Tag;
  842.     Result := True;
  843.     exit;
  844.   end;
  845.   if s = '*' then {compare function}
  846.   begin
  847.     p^.ProcPtr := CompareProc;
  848.     p^.Ext2 := Tag;
  849.     Result := True;
  850.     exit;
  851.   end;
  852.   s2 := copy(S, 1, pos('|', s)-1);
  853.   delete(s, 1, length(s2) + 1);
  854.   H := MakeHash(s2);
  855.   ISRead := False;
  856.   cl := nil;
  857.   for I := TIFPSRuntimeClassImporter(Tag).FClasses.Count -1 downto 0 do
  858.   begin
  859.     Cl := TIFPSRuntimeClassImporter(Tag).FClasses.GetItem(I);
  860.     if (Cl.FClassNameHash = h) and (cl.FClassName = s2) then
  861.     begin
  862.       IsRead := True;
  863.       break;
  864.     end;
  865.   end;
  866.   if not isRead then begin
  867.     Result := False;
  868.     exit;                 
  869.   end;
  870.   s2 := copy(S, 1, pos('|', s)-1);
  871.   delete(s, 1, length(s2) + 1);
  872.   if (s2 <> '') and (s2[length(s2)] = '@') then
  873.   begin
  874.     IsRead := False;
  875.     Delete(S2, length(s2), 1);
  876.   end else
  877.     isRead := True;
  878.   H := MakeHash(s2);
  879.   for i := cl.FClassItems.Count -1 downto 0 do
  880.   begin
  881.     px := cl.FClassItems.GetItem(I);
  882.     if (px^.FNameHash = h) and (px^.FName = s2) then
  883.     begin
  884.       p^.ExportDecl := s;
  885.       case px^.b of
  886.   {0: ext1=ptr}
  887.   {1: ext1=pointerinlist}
  888.   {2: ext1=propertyinfo}
  889.   {3: ext1=readfunc; ext2=writefunc}
  890.         4:
  891.           begin
  892.             p^.ProcPtr := ClassCallProc04;
  893.             p^.Ext1 := px^.Ptr;
  894.             p^.Ext2 := Tag;
  895.           end;
  896.         5:
  897.           begin
  898.             p^.ProcPtr := ClassCallProc05;
  899.             p^.Ext1 := px^.Ptr;
  900.             p^.Ext2 := Tag;
  901.           end;
  902.         6:
  903.           begin
  904.             p^.ProcPtr := ClassCallProc06;
  905.             if IsRead then
  906.             begin
  907.               p^.Ext1 := px^.FReadFunc;
  908.               p^.Ext2 := nil;
  909.             end else
  910.             begin
  911.               p^.Ext1 := nil;
  912.               p^.Ext2 := px^.FWriteFunc;
  913.             end;
  914.           end;
  915.         0:
  916.           begin
  917.             p^.ProcPtr := ClassCallProc01;
  918.             p^.Ext1 := px^.Ptr;
  919.             p^.Ext2 := nil;
  920.           end;
  921.         1:
  922.           begin
  923.             p^.ProcPtr := ClassCallProc01;
  924.             p^.Ext1 := px^.PointerInList;
  925.             p^.ext2 := pointer(1);
  926.           end;
  927.         3:
  928.           begin
  929.             p^.ProcPtr := ClassCallProc3;
  930.             if IsRead then
  931.             begin
  932.               p^.Ext1 := px^.FReadFunc;
  933.               p^.Ext2 := nil;
  934.             end else
  935.             begin
  936.               p^.Ext1 := nil;
  937.               p^.Ext2 := px^.FWriteFunc;
  938.             end;
  939.           end;
  940.         else
  941.          begin
  942.            result := false;
  943.            exit;
  944.          end;
  945.       end;
  946.       Result := true;
  947.       exit;
  948.     end;
  949.   end;
  950.   pp := GetPropInfo(cl.FClass.ClassInfo, s2);
  951.   if pp <> nil then
  952.   begin
  953.      p^.ProcPtr := ClassCallProc2;
  954.      p^.Ext1 := pp;
  955.      if IsRead then
  956.        p^.Ext2 := Pointer(1)
  957.      else
  958.        p^.Ext2 := Pointer(0);
  959.      Result := True;
  960.   end else
  961.     result := false;
  962. end;
  963.  
  964. procedure RegisterClassLibraryRuntime(SE: TIFPSExec; Importer: TIFPSRuntimeClassImporter);
  965. begin
  966.   SE.AddSpecialProcImport('class', SpecImport, Importer);
  967. end;
  968.  
  969. { TIFPSRuntimeClass }
  970.  
  971. constructor TIFPSRuntimeClass.Create(aClass: TClass);
  972. begin
  973.   inherited Create;
  974.   FClass := AClass;
  975.   FClassName := FastUpperCase(aClass.ClassName);
  976.   FClassNameHash := MakeHash(FClassName);
  977.   FClassItems:= TIfList.Create;
  978.   FEndOfVmt := MaxInt;
  979. end;
  980.  
  981. destructor TIFPSRuntimeClass.Destroy;
  982. var
  983.   I: Longint;
  984.   P: PClassItem;
  985. begin
  986.   for i:= FClassItems.Count -1 downto 0 do
  987.   begin
  988.     P := FClassItems.GetItem(I);
  989.     Dispose(p);
  990.   end;
  991.   FClassItems.Free;
  992.   inherited Destroy;
  993. end;
  994.  
  995. procedure TIFPSRuntimeClass.RegisterVirtualAbstractMethod(ClassDef: TClass;
  996.   ProcPtr: Pointer; const Name: string);
  997. var
  998.   P: PClassItem;
  999. begin
  1000.   New(P);
  1001.   p^.FName := Name;
  1002.   p^.FNameHash := MakeHash(Name);
  1003.   p^.b := 1;
  1004.   p^.PointerInList := FindVirtualMethodPtr(Self, ClassDef, ProcPtr);
  1005.   FClassItems.Add(p);
  1006. end;
  1007.  
  1008. procedure TIFPSRuntimeClass.RegisterConstructor(ProcPtr: Pointer;
  1009.   const Name: string);
  1010. var
  1011.   P: PClassItem;
  1012. begin
  1013.   New(P);
  1014.   p^.FName := Name;
  1015.   p^.FNameHash := MakeHash(Name);
  1016.   p^.b := 4;
  1017.   p^.Ptr := ProcPtr;
  1018.   FClassItems.Add(p);
  1019. end;
  1020.  
  1021. procedure TIFPSRuntimeClass.RegisterMethod(ProcPtr: Pointer; const Name: string);
  1022. var
  1023.   P: PClassItem;
  1024. begin
  1025.   New(P);
  1026.   p^.FName := Name;
  1027.   p^.FNameHash := MakeHash(Name);
  1028.   p^.b := 0;
  1029.   p^.Ptr := ProcPtr;
  1030.   FClassItems.Add(p);
  1031. end;
  1032.  
  1033.  
  1034. procedure TIFPSRuntimeClass.RegisterPropertyHelper(ReadFunc,
  1035.   WriteFunc: Pointer; const Name: string);
  1036. var
  1037.   P: PClassItem;
  1038. begin
  1039.   New(P);
  1040.   p^.FName := Name;
  1041.   p^.FNameHash := MakeHash(Name);
  1042.   p^.b := 3;
  1043.   p^.FReadFunc := ReadFunc;
  1044.   p^.FWriteFunc := WriteFunc;
  1045.   FClassItems.Add(p);
  1046. end;
  1047.  
  1048. procedure TIFPSRuntimeClass.RegisterVirtualConstructor(ProcPtr: Pointer;
  1049.   const Name: string);
  1050. var
  1051.   P: PClassItem;
  1052. begin
  1053.   New(P);
  1054.   p^.FName := Name;
  1055.   p^.FNameHash := MakeHash(Name);
  1056.   p^.b := 5;
  1057.   p^.PointerInList := FindVirtualMethodPtr(Self, FClass, ProcPtr);
  1058.   FClassItems.Add(p);
  1059. end;
  1060.  
  1061. procedure TIFPSRuntimeClass.RegisterVirtualMethod(ProcPtr: Pointer; const Name: string);
  1062. var
  1063.   P: PClassItem;
  1064. begin
  1065.   New(P);
  1066.   p^.FName := Name;
  1067.   p^.FNameHash := MakeHash(Name);
  1068.   p^.b := 1;
  1069.   p^.PointerInList := FindVirtualMethodPtr(Self, FClass, ProcPtr);
  1070.   FClassItems.Add(p);
  1071. end;
  1072.  
  1073. procedure TIFPSRuntimeClass.RegisterEventPropertyHelper(ReadFunc,
  1074.   WriteFunc: Pointer; const Name: string);
  1075. var
  1076.   P: PClassItem;
  1077. begin
  1078.   New(P);
  1079.   p^.FName := Name;
  1080.   p^.FNameHash := MakeHash(Name);
  1081.   p^.b := 6;
  1082.   p^.FReadFunc := ReadFunc;
  1083.   p^.FWriteFunc := WriteFunc;
  1084.   FClassItems.Add(p);
  1085. end;
  1086.  
  1087. { TIFPSRuntimeClassImporter }
  1088.  
  1089. function TIFPSRuntimeClassImporter.Add(aClass: TClass): TIFPSRuntimeClass;
  1090. begin
  1091.   Result := TIFPSRuntimeClass.Create(aClass);
  1092.   FClasses.Add(Result);
  1093. end;
  1094.  
  1095. procedure TIFPSRuntimeClassImporter.Clear;
  1096. var
  1097.   I: Longint;
  1098. begin
  1099.   for i := 0 to FClasses.Count -1 do
  1100.   begin
  1101.     TIFPSRuntimeClass(FClasses.GetItem(I)).Free;
  1102.   end;
  1103.   FClasses.Clear;
  1104. end;
  1105.  
  1106. constructor TIFPSRuntimeClassImporter.Create;
  1107. begin
  1108.   inherited Create;
  1109.   FClasses := TIfList.Create;
  1110. end;
  1111.  
  1112. destructor TIFPSRuntimeClassImporter.Destroy;
  1113. begin
  1114.   Clear;
  1115.   FClasses.Free;
  1116.   inherited Destroy;
  1117. end;
  1118.  
  1119. procedure SetVariantToClass(V: PIFVariant; Cl: TObject);
  1120. begin
  1121.   if v <> nil then
  1122.   begin
  1123.     v^.tResourceP1 := cl;
  1124.     if cl <> nil then
  1125.       v^.tResourceFreeProc := DummyResourceFree
  1126.     else
  1127.       v^.TResourceFreeProc := nil;
  1128.   end;
  1129. end;
  1130.  
  1131. {
  1132.  
  1133.  
  1134.  
  1135.  
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145. }
  1146. function BGRFW(var s: string): string;
  1147. var
  1148.   l: Longint;
  1149. begin
  1150.   l := Length(s);
  1151.   while l >0 do
  1152.   begin
  1153.     if s[l] = ' ' then
  1154.     begin
  1155.       Result := copy(s, l + 1, Length(s) - l);
  1156.       Delete(s, l, Length(s) - l + 1);
  1157.       exit;
  1158.     end;
  1159.     Dec(l);
  1160.   end;
  1161.   Result := s;
  1162.   s := '';
  1163. end;
  1164.  
  1165.  
  1166.  
  1167. function MyAllMethodsHandler2(Self: PScriptMethodInfo; const Stack: PPointer; _EDX, _ECX: Pointer): Integer; forward;
  1168.  
  1169. procedure MyAllMethodsHandler;
  1170. //  On entry:
  1171. //     EAX = Self pointer
  1172. //     EDX, ECX = param1 and param2
  1173. //     STACK = param3... paramcount
  1174. asm
  1175.   push ecx
  1176.   push edx
  1177.   mov edx, esp
  1178.   add edx, 12
  1179.   pop ecx
  1180.   call MyAllMethodsHandler2
  1181.   mov edx, [esp]
  1182.   add esp, eax
  1183.   mov [esp], edx
  1184. end;
  1185.  
  1186. function MyAllMethodsHandler2(Self: PScriptMethodInfo; const Stack: PPointer; _EDX, _ECX: Pointer): Integer;
  1187. var
  1188.   Decl: string;
  1189.   I, C, regno: Integer;
  1190.   Params: TIfList;
  1191. //  VarParams: TIfList;
  1192.   Tmp: PIFVariant;
  1193.   cpt: PIFTypeRec;
  1194.   fmod: char;
  1195.   s,e: string;
  1196.   FStack: pointer;
  1197. begin
  1198.   Decl := PIFProcRec(Self^.Se.FProcs.GetItem(Self^.ProcNo))^.ExportDecl;
  1199.  
  1200.   FStack := Stack;
  1201.   Params := TIfList.Create;
  1202. //  VarParams := TIfList.Create;
  1203.   s := decl;
  1204.   grfw(s);
  1205.   while s <> '' do
  1206.   begin
  1207.     Params.Add(nil);
  1208.     grfw(s);
  1209.   end;
  1210.   c := Params.Count;
  1211.   regno := 0;
  1212.   I := C -1 ;
  1213.   Result := 0;
  1214.   s := decl;
  1215.   grfw(s);
  1216.   while I >= 0 do
  1217.   begin
  1218.     e := grfw(s);
  1219.     fmod := e[1];
  1220.     delete(e, 1, 1);
  1221.     cpt := Self.Se.GetTypeNo(StrToInt(e));
  1222.     if fmod = '!' then
  1223.     begin
  1224.       case cpt.BaseType of
  1225.       
  1226.         btResourcePointer:
  1227.           begin
  1228.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1229.             if regno = 0 then
  1230.             begin
  1231.               Inc(regno);
  1232.               Tmp^.tResourceP1:= Pointer(Pointer(_EDX)^);
  1233.               tmp^.tResourceFreeProc := DummyResourceFree;
  1234.  
  1235.             end
  1236.             else if regno = 1 then
  1237.             begin
  1238.               Inc(regno);
  1239.               Tmp^.tResourceP1:= Pointer(Pointer(_ECX)^);
  1240.               tmp^.tResourceFreeProc := DummyResourceFree;
  1241.             end;
  1242. //            VarParams.Add(tmp);
  1243.             Params.SetItem(I, Tmp);
  1244.           end;
  1245.  
  1246.         btString, btPChar:
  1247.           begin
  1248.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1249.             if regno = 0 then
  1250.             begin
  1251.               Inc(regno);
  1252.               string(Tmp^.tString):= string(Pointer(_EDX)^);
  1253.             end
  1254.             else if regno = 1 then
  1255.             begin
  1256.               Inc(regno);
  1257.               string(Tmp^.tstring):= string(Pointer(_ECX)^);
  1258.             end;
  1259. //            VarParams.Add(tmp);
  1260.             Params.SetItem(I,  Tmp);
  1261.           end;
  1262.         btDouble{$IFNDEF NOINT64}, btS64{$ENDIF}:
  1263.           begin
  1264.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1265.             if regno = 0 then
  1266.             begin
  1267.               Inc(regno);
  1268.               Move(Pointer(_EDX)^, tmp^.tDouble, 8);
  1269.             end
  1270.             else if regno = 1 then
  1271.             begin
  1272.               Inc(regno);
  1273.               Move(Pointer(_ECX)^, tmp^.tDouble, 8);
  1274.             end;
  1275. //            VarParams.Add(tmp);
  1276.             Params.SetItem(I,  Tmp);
  1277.           end;
  1278.         btExtended:
  1279.           begin
  1280.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1281.             if regno = 0 then
  1282.             begin
  1283.               Inc(regno);
  1284.               Move(Pointer(_EDX)^, tmp^.textended, 10);
  1285.             end
  1286.             else if regno = 1 then
  1287.             begin
  1288.               Inc(regno);
  1289.               Move(Pointer(_ECX)^, tmp^.textended, 10);
  1290.             end;
  1291. //            VarParams.Add(tmp);
  1292.             Params.SetItem(I,  Tmp);
  1293.           end;
  1294.         btSingle,
  1295.           btU8,
  1296.           btS8,
  1297.           Btu16,
  1298.           bts16,
  1299.           btu32,
  1300.           bts32:
  1301.           begin
  1302.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1303.             if regno = 0 then
  1304.             begin
  1305.               Inc(regno);
  1306.               Tmp^.ts32 := Longint(Pointer(_EDX)^);
  1307.             end
  1308.             else if regno = 1 then
  1309.             begin
  1310.               Inc(regno);
  1311.               Tmp^.ts32:= Longint(Pointer(_ECX)^);
  1312.             end;
  1313. //            VarParams.Add(tmp);
  1314.             Params.SetItem(I,  Tmp);
  1315.           end;
  1316.       else
  1317.         begin
  1318.           FreePIFVariantList({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF} Params);
  1319. //          FreePIFVariantList({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF} VarParams);
  1320.         end;
  1321.       end;
  1322.     end
  1323.     else
  1324.     begin
  1325.       case cpt.BaseType of
  1326.         btResourcePointer:
  1327.           begin
  1328.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);;
  1329.             if regno = 0 then
  1330.             begin
  1331.               Inc(regno);
  1332.               Tmp^.tResourceP1 := _EDX;
  1333.               tmp^.tResourceFreeProc := DummyResourceFree;
  1334.             end
  1335.             else if regno = 1 then
  1336.             begin
  1337.               Inc(regno);
  1338.               Tmp^.tResourceP1 := _ECX;
  1339.               tmp^.tResourceFreeProc := DummyResourceFree;
  1340.             end;
  1341.             Params.SetItem(I, Tmp);
  1342.           end;
  1343.  
  1344.         btString:
  1345.           begin
  1346.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1347.             if regno = 0 then
  1348.             begin
  1349.               Inc(regno);
  1350.               string(Tmp^.tstring) := string(_EDX);
  1351.             end
  1352.             else if regno = 1 then
  1353.             begin
  1354.               Inc(regno);
  1355.               string(Tmp^.tstring) := string(_ECX);
  1356.             end;
  1357.             Params.SetItem(I,  Tmp);
  1358.           end;
  1359.           btU8,
  1360.           btS8,
  1361.           Btu16,
  1362.           bts16,
  1363.           btu32,
  1364.           bts32:
  1365.           begin
  1366.             Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1367.             if regno = 0 then
  1368.             begin
  1369.               Inc(regno);
  1370.               Tmp^.ts32 := Longint(_EDX);
  1371.             end
  1372.             else if regno = 1 then
  1373.             begin
  1374.               Inc(regno);
  1375.               Tmp^.ts32 := Longint(_ECX);
  1376.             end;
  1377.             Params.SetItem(I,  Tmp);
  1378.           end;
  1379.       end;
  1380.     end;
  1381.     dec(i);
  1382.     if regno = 2 then
  1383.       break;
  1384.   end;
  1385.   s := decl;
  1386.   grfw(s);
  1387.   for I := 0 to C-1 do
  1388.   begin
  1389.     e := BGRFW(s);
  1390.     if Params.GetItem(I) = nil then
  1391.     begin
  1392.       fmod := e[1];
  1393.       Delete(e, 1, 1);
  1394.       cpt := Self.Se.GetTypeNo(StrToInt(e));
  1395.       if fmod = '!' then
  1396.       begin
  1397.         case cpt.BaseType of
  1398.  
  1399.           btResourcePointer:
  1400.             begin
  1401.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1402.               Tmp^.tResourceP1 := Pointer(Pointer(FStack^)^);
  1403.               tmp^.tResourceFreeProc := DummyResourceFree;
  1404.               FStack := Pointer(Longint(FStack) + 4);
  1405.               Inc(Result, 4);
  1406. //              VarParams.Add(Tmp);
  1407.               Params.SetItem(I, Tmp);
  1408.             end;
  1409.           btString:
  1410.             begin
  1411.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1412.               String(Tmp^.tstring) := string(FStack^);
  1413.               FStack := Pointer(Pointer(Longint(FStack) + 4)^);
  1414.               Inc(Result, 4);
  1415. //              VarParams.Add(Tmp);
  1416.               Params.SetItem(I, Tmp);
  1417.             end;
  1418.           btDouble{$IFNDEF NOINT64}, bts64{$ENDIF}:
  1419.             begin
  1420.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1421.               Move(Pointer(FStack^)^, Tmp^.tDouble, 8);
  1422.               FStack := Pointer(Longint(FStack) + 4);
  1423.               Inc(Result, 4);
  1424. //              VarParams.Add(Tmp);
  1425.               Params.SetItem(I, Tmp);
  1426.             end;
  1427.           btExtended:
  1428.             begin
  1429.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1430.               Move(Pointer(FStack^)^, Tmp^.tExtended, 10);
  1431.               FStack := Pointer(Longint(FStack) + 4);
  1432.               Inc(Result, 4);
  1433. //              VarParams.Add(Tmp);
  1434.               Params.SetItem(I, Tmp);
  1435.             end;
  1436.           btSingle,
  1437.           btS8,
  1438.           btu8,
  1439.           bts16,
  1440.           btu16,
  1441.           bts32,
  1442.           btu32:
  1443.             begin
  1444.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1445.               Move(Pointer(FStack^)^, Tmp^.ts32, 4);
  1446.               FStack := Pointer(Longint(FStack) + 4);
  1447.               Inc(Result, 4);
  1448. //              VarParams.Add(Tmp);
  1449.               Params.SetItem(I, Tmp);
  1450.             end;
  1451.         else
  1452.           begin
  1453.             FreePIFVariantList({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}Params);
  1454. //            VarParams.Free;
  1455.             exit;
  1456.           end;
  1457.         end;
  1458.       end
  1459.       else
  1460.       begin
  1461.         case cpt.BaseType of
  1462.           btResourcePointer:
  1463.             begin
  1464.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1465.               tmp^.tResourceP1 := Pointer(FStack^);
  1466.               tmp^.tResourceFreeProc := DummyResourceFree;
  1467.               FStack := Pointer(Longint(FStack) + 4);
  1468.               Inc(Result, 4);
  1469.               Params.SetItem(I, tmp);
  1470.             end;
  1471.           btString:
  1472.             begin
  1473.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1474.               string(Tmp^.tstring):= string(FStack^);
  1475.               FStack := Pointer(Longint(FStack) + 4);
  1476.               Inc(Result, 4);
  1477.               Params.SetItem(I, tmp);
  1478.             end;
  1479.           btDouble{$IFNDEF NOINT64}, bts64{$ENDIF}:
  1480.             begin
  1481.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1482.               Move(FStack^, Tmp^.tDouble, 8);
  1483.               FStack := Pointer(Longint(FStack) + 8);
  1484.               Inc(Result, 8);
  1485.               Params.SetItem(I, tmp);
  1486.             end;
  1487.           btExtended:
  1488.             begin
  1489.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1490.               Move(FStack^, Tmp^.tExtended, 10);
  1491.               FStack := Pointer(Longint(FStack) + 12);
  1492.               Inc(Result, 12);
  1493.               Params.SetItem(I, tmp);
  1494.             end;
  1495.           btSingle,
  1496.           bts8,
  1497.           btu8,
  1498.           bts16,
  1499.           btu16,
  1500.           bts32,
  1501.           btu32:
  1502.             begin
  1503.               Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1504.               Tmp^.ts32 := Longint(FStack^);
  1505.               Params.SetItem(I, tmp);
  1506.               FStack := Pointer(Longint(FStack) + 4);
  1507.               Inc(Result, 4);
  1508.             end;
  1509.         else
  1510.           begin
  1511.             FreePIFVariantList({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}Params);
  1512. //            VarParams.Free;
  1513.             exit;
  1514.           end;
  1515.         end;
  1516.       end;
  1517.     end;
  1518.   end;
  1519.   s := decl;
  1520.   e := grfw(s);
  1521.  
  1522. (*  if e <> '-1' then
  1523.   begin
  1524.     cpt := Self.Se.GetTypeNo(StrToInt(e));
  1525.     Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1526.     Params.Add(tmp);
  1527.   end;
  1528. *)
  1529.   Self.Se.RunProc(Params, Self.ProcNo);
  1530. (*
  1531.   if e <> '-1' then
  1532.   begin
  1533.     cpt := Self.Se.GetTypeNo(StrToInt(e));
  1534.     Tmp := CreateVariant({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}cpt);
  1535.     Params.Add(tmp);
  1536.   end;
  1537. *)
  1538.   FStack := Stack;
  1539.   regno := 0;
  1540.   I := C-1;
  1541.  
  1542.   while I >= 0 do
  1543.   begin
  1544.     e := grfw(s);
  1545.     fmod := e[1];
  1546.     delete(e, 1, 1);
  1547.     cpt := Self.Se.GetTypeNo(StrToInt(e));
  1548.     if fmod = '!' then
  1549.     begin
  1550.       case cpt.BaseType of
  1551.         btResourcePointer:
  1552.           begin
  1553.             tmp := Params.GetItem(I);
  1554.             if regno = 0 then
  1555.             begin
  1556.               Inc(regno);
  1557.               Pointer(Pointer(_EDX)^) := Tmp^.tResourceP1;
  1558.             end
  1559.             else if regno = 1 then
  1560.             begin
  1561.               Inc(regno);
  1562.               Pointer(Pointer(_ECX)^) := Tmp^.tResourceP1;
  1563.             end;
  1564.             DisposeVariant({$IFNDEF NOSMARTMM}Self.Se.mm, {$ENDIF}tmp);
  1565.             Params.SetItem(I, nil);
  1566.           end;
  1567.         btString:
  1568.           begin
  1569.             tmp := Params.GetItem(I);
  1570.             if regno = 0 then
  1571.             begin
  1572.               Inc(regno);
  1573.               string(Pointer(_EDX)^) := string(Tmp^.tstring);
  1574.             end
  1575.             else if regno = 1 then
  1576.             begin
  1577.               Inc(regno);
  1578.               string(Pointer(_ECX)^) := string(Tmp^.tstring);
  1579.             end;
  1580.             DisposeVariant({$IFNDEF NOSMARTMM}Self.Se.mm, {$ENDIF}tmp);
  1581.             Params.SetItem(I, nil);
  1582.           end;
  1583.         btDouble{$IFNDEF NOINT64}, bts64{$ENDIF}:
  1584.           begin
  1585.             tmp := Params.GetItem(I);
  1586.             if regno = 0 then
  1587.             begin
  1588.               Inc(regno);
  1589.               Move(tmp^.tDouble, Pointer(_EDX)^, 8);
  1590.             end
  1591.             else if regno = 1 then
  1592.             begin
  1593.               Inc(regno);
  1594.               Move(tmp^.tDouble, Pointer(_ECX)^, 8);
  1595.             end;
  1596.             DisposeVariant({$IFNDEF NOSMARTMM}Self.Se.mm, {$ENDIF}tmp);
  1597.             Params.SetItem(I, nil);
  1598.           end;
  1599.         btExtended:
  1600.           begin
  1601.             tmp := Params.GetItem(I);
  1602.             if regno = 0 then
  1603.             begin
  1604.               Inc(regno);
  1605.               Move(tmp^.tExtended, Pointer(_EDX)^, 10);
  1606.             end
  1607.             else if regno = 1 then
  1608.             begin
  1609.               Inc(regno);
  1610.               Move(tmp^.tExtended, Pointer(_ECX)^, 10);
  1611.             end;
  1612.             DisposeVariant({$IFNDEF NOSMARTMM}Self.Se.mm, {$ENDIF}tmp);
  1613.             Params.SetItem(I, nil);
  1614.           end;
  1615.           btSingle,
  1616.           bts8,
  1617.           btu8,
  1618.           bts16,
  1619.           btu16,
  1620.           bts32,
  1621.           btu32:
  1622.           begin
  1623.             tmp := Params.GetItem(I);
  1624.             if regno = 0 then
  1625.             begin
  1626.               Inc(regno);
  1627.               Longint(Pointer(_EDX)^) := Tmp^.ts32;
  1628.             end
  1629.             else if regno = 1 then
  1630.             begin
  1631.               Inc(regno);
  1632.               Longint(Pointer(_ECX)^) := Tmp^.ts32;
  1633.             end;
  1634.             DisposeVariant({$IFNDEF NOSMARTMM}Self.Se.mm, {$ENDIF}tmp);
  1635.             Params.SetItem(I, nil);
  1636.           end;
  1637.       else
  1638.         begin
  1639.           FreePIFVariantList({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}Params);
  1640. //          VarParams.Free;
  1641.           exit;
  1642.         end;
  1643.       end;
  1644.     end else begin
  1645.       case cpt.BaseType of
  1646.         btResourcePointer,
  1647.         btString,
  1648.         bts8,
  1649.         btu8,
  1650.         bts16,
  1651.         btu16,
  1652.         bts32,
  1653.         btu32:
  1654.           begin
  1655.             Inc(regno);
  1656.             DisposeVariant({$IFNDEF NOSMARTMM}Self.Se.mm, {$ENDIF}Params.GetItem(I));
  1657.             Params.SetItem(I, nil);
  1658.           end;
  1659.       end;
  1660.     end;
  1661.     Dec(i);
  1662.   end;
  1663.   s := Decl;
  1664.   grfw(s);
  1665.  
  1666.   for I := 0 to C - 1 do
  1667.   begin
  1668.     e := BGRFW(s);
  1669.     fmod := e[1];
  1670.     delete(e, 1, 1);
  1671.     cpt := Self.Se.GetTypeNo(StrToInt(e));
  1672.     tmp := Params.GetItem(i);
  1673.     if tmp <> nil then
  1674.     begin
  1675.       if (fmod = '!') then
  1676.       begin
  1677.         case cpt.BaseType of
  1678.          btResourcePointer:
  1679.             begin
  1680.               Pointer(Pointer(FStack^)^) := tmp^.tResourceP1;
  1681.               FStack := Pointer(Longint(FStack) + 4);
  1682.             end;
  1683.           btString:
  1684.             begin
  1685.               string(FStack^) := string(Tmp^.tstring);
  1686.               FStack := Pointer(Pointer(Longint(FStack) + 4)^);
  1687.             end;
  1688.           btDouble{$IFNDEF NOINT64}, bts64{$ENDIF}:
  1689.             begin
  1690.               Move(Tmp^.tDouble, Pointer(FStack^)^, 8);
  1691.               FStack := Pointer(Longint(FStack) + 4);
  1692.             end;
  1693.           btExtended:
  1694.             begin
  1695.               Move(Tmp^.tExtended, Pointer(FStack^)^, 10);
  1696.               FStack := Pointer(Longint(FStack) + 4);
  1697.             end;
  1698.             btSingle,
  1699.             bts8,
  1700.             btu8,
  1701.             bts16,
  1702.             btu16,
  1703.             bts32,
  1704.             btu32:
  1705.             begin
  1706.               Longint(Pointer(FStack^)^) := Tmp^.ts32;
  1707.               FStack := Pointer(Longint(FStack) + 4);
  1708.             end;
  1709.         else
  1710.           begin
  1711.             FreePIFVariantList({$IFNDEF NOSMARTMM}Self.Se.MM, {$ENDIF}Params);
  1712.             exit;
  1713.           end;
  1714.         end;
  1715.  
  1716.       end;
  1717.       DisposeVariant({$IFNDEF NOSMARTMM}Self.Se.mm, {$ENDIF}tmp);
  1718.     end;
  1719.   end;
  1720.   Params.Free;
  1721. end;
  1722.  
  1723. function TIFPSRuntimeClassImporter.FindClass(const Name: string): TIFPSRuntimeClass;
  1724. var
  1725.   h, i: Longint;
  1726.   p: TIFPSRuntimeClass;
  1727. begin
  1728.   h := MakeHash(Name);
  1729.   for i := FClasses.Count -1 downto 0 do
  1730.   begin
  1731.     p := FClasses.GetItem(i);
  1732.     if (p.FClassNameHash = h) and (p.FClassName = Name) then
  1733.     begin
  1734.       Result := P;
  1735.       exit;
  1736.     end;
  1737.   end;
  1738.   Result := nil;
  1739. end;
  1740. initialization
  1741.   DelphiRPFunc := ClassRuntimeGetRPFuncs;
  1742. end.
  1743.  
  1744.