[fpc-pascal] Creating capturers

2023-10-31 Thread Hairy Pixels via fpc-pascal
I'm curious how the capturer is created in the case of anonymous functions. I 
know the function needs to create a capturer when nested functions are declared 
but what happens if there is an anonymous function which is declared in the 
code section?

I think the compiler will only know about the requirement to create a capturer 
at this point but local variables have already been assigned so do they need to 
do an extra copy to the capturer when it's created?

With nested function this is not a problem since the capturer can be created 
before any locals are assigned and thus not copying is needed, if I understand 
correctly.

==

var
  gProc: reference to procedure;

procedure DoThis;
var
  a: array[0..2] of integer;
begin
  // Compiler does not yet know the function requires a capturer
  a := [1,2,3];

  // DoThis requires a capturer now since the function reference is assigned to 
an anonymous (nested) function.
  // Does it copy the array (and other local variables) or does the compiler 
always make a capturer for all functions if the "anonymousfunctions" mode 
switch is enabled?
  gProc := procedure
  begin
writeln(Length(a));
  end;
end;


Regards,
Ryan Joseph

___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal


[fpc-pascal] IDispatch with Variant is not working on Linux. Why?

2023-10-31 Thread Anthony Walter via fpc-pascal
Is there any reason why the late binding of properties and methods through
of IDispatch interface with the Variant type is not working on Linux?

I am writing a cross platform embeddable JavaScript toolkit for Free
Pascal. I wanted to use IDispatch with variants so that the experience with
be more fluid for eventual end users. My goal of was to allow code like
this to run:

var
  Script: IScript;
  V: Variant;
begin
  Script := NewScript('let person = {"name":  "James", age: 24}; let speak
= () => log(person.name)')
  V := Script.This;
  V.person.name = 'Ralph';
  V.speak(); // writes out Ralph
  V := V.person;
  WriteLn(V.age); // write out 24
  V.address.street := '123 Skippy Lane'; // add address object with a
street to person
  WriteLn(V.state); // writes out Undefined
end;

In the above code Script.This is a property returning an IDispatch
interface holding an internal reference to the top level script object. The
problem I am having with my current trunk version of fpc is that when I use
a Variant that is assigned an IDispatch, no IDispatch methods to lookup and
things like "person", "name", or "age" are ever evaluated.

Instead I get this:

Project dispatcher raised exception class 'External: SIGSEGV'.

Here is an example program. Not one WriteLn() in the example ever executes.
Instead at runtime when V.Hello is evaluated I get the above exception. I
believe fpc does support late time binding of IDispatch even on Linux as no
inherent tie to Microsoft Windows functions are needed to make use of the
IDispatch interface. So what is going on?

program Dispatcher;

{$mode delphi}

type
  TDispatcher = class(TInterfacedObject, IDispatch)
  public
function GetTypeInfoCount(out Count: LongInt): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: LongInt; out TypeInfo): HResult;
stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
  NameCount, LocaleID: LongInt; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: LongInt;const IID: TGUID; LocaleID: LongInt;
  Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer):
HResult; stdcall;
  end;

function TDispatcher.GetTypeInfoCount(out Count: LongInt): HResult;
begin
  WriteLn('GetTypeInfoCount');
  Count := 0;
  Result := S_OK;
end;

function TDispatcher.GetTypeInfo(Index, LocaleID: LongInt; out TypeInfo):
HResult;
begin
  WriteLn('GetTypeInfo');
  Result := E_NOTIMPL;
end;

function TDispatcher.GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount,
  LocaleID: LongInt; DispIDs: Pointer): HResult;
begin
  WriteLn('GetIDsOfNames');
  Result := S_OK;
end;

function TDispatcher.Invoke(DispID: LongInt; const IID: TGUID;
  LocaleID: LongInt; Flags: Word; var Params; VarResult, ExcepInfo,
  ArgErr: Pointer): HResult;
begin
  WriteLn('Invoke');
  Result := S_OK;
end;

procedure Test;
var
  D: IDispatch;
  V: Variant;
begin
  D := TDispatcher.Create;
  V := D;
  V.Hello();
end;

begin
  Test;
end.
___
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal