SRL Archive - OSR Help

Initializing function references, access violation exceptions


bonsai

2013-10-13 20:10:54

Why do I get access violation exceptions if I try to initialize function references with

var xxx = @reference

Exception in Script: Runtime error: "Access violation" at line 31, column 23

If I manually initialize it it works fine.

program new;

function realfunction() : boolean;
begin
result := true
end;

type
trec = record
callthis : function:boolean;
end;

var
noinit : function:boolean;
norec : function:boolean = @realfunction;
onerec : trec = [@realfunction];
funcarr : array[0..0] of trec = [[@realfunction]];
b : boolean;

begin
noinit := @realfunction;
noinit();
writeln(b);

try
b := norec();
writeln(b);
except
writeln('got access violation');
end;

try
b := onerec.callthis();
writeln(b);
except
writeln('got access violation');
end;

try
with funcarr[0] do
b := callthis();
writeln(b);
except
writeln('got access violation');
end;
end.

False
got access violation
got access violation
got access violation
Successfully executed.

Kevin

2013-10-14 10:47:54

I don't remember the entire scenario, but I recall in pascalscript I was having troubles using function pointers, despite having no such issues with procedure pointers. I wonder if a similar issue exists in Lape due to their similar natures. @Dgby714 As you're the name I'm most familiar with in all these updates… Ideas?

Brandon

2013-10-14 11:04:10

Try initialising it with := instead of = and see what happens?

Dgby714

2013-10-14 14:52:15

From: Brandon
Try initialising it with := instead of = and see what happens?


^^^

Lape parses variable initialization before assigning methods a stack position. (Meaning using "=" makes them nil)

Using ":=" basicly tells Lape to add delayed code, and the variable gets assigned right before the code starts being ran.

bonsai

2013-10-14 15:11:07

That fixes the simple case but still no joy with the record/array initialization.

I figured I was doing something wrong. I'll just init the array with assignments in a function to bypass.

program new;

function realfunction() : boolean;
begin
result := true
end;

type
trec = record
callthis : function:boolean;
end;

var
noinit : function:boolean;
norec : function:boolean := @realfunction;
onerec : trec := [@realfunction];
funcarr : array[0..0] of trec := [[@realfunction]];
b : boolean;

begin
noinit := @realfunction;
b := noinit();
writeln(b);

try
b := norec();
writeln(b);
except
writeln('got access violation');
end;

try
b := onerec.callthis();
writeln(b);
except
writeln('got access violation');
end;

try
with funcarr[0] do
b := callthis();
writeln(b);
except
writeln('got access violation');
end;
end.

True
True
got access violation
got access violation
Successfully executed.

Brandon

2013-10-14 16:15:53

This is because Lape's delay initialisation is flawed and useless and only initialises right before the variable or function is used.. You can't really depend on it to do anything right.. Just trick it then.. Or initialise within the body of the main.

The way to get around it is to do:


type T = record
func: function: Boolean;
end;

function callme: boolean;
begin
writeln('called');
result := true;
end;

var
Ptr: Pointer := [@Callme]; //Delay initialisation here..
R: T := [Ptr]; //It is initialised here because this is where the variable is being used..
begin
R.func();
end.

Doing
R: T := [AddressOf(Callme)];

does nothing because it initialises it to 0xFFFFFFFF.


EDIT: Ahh the old villavu mention tag bug.. Can't use the @ sign because villavu's keeps parsing it as a mention tag.. How stupid.

Dgby714

2013-10-15 06:04:38

From: Brandon
This is because Lape's delay initialisation is flawed and useless and only initialises right before the variable or function is used.. You can't really depend on it to do anything right.. Just trick it then.. Or initialise within the body of the main.

The way to get around it is to do:


type T = record
func: function: Boolean;
end;

function callme: boolean;
begin
writeln('called');
result := true;
end;

var
Ptr: Pointer := [@Callme]; //Delay initialisation here..
R: T := [Ptr]; //It is initialised here because this is where the variable is being used..
begin
R.func();
end.

Doing
R: T := [AddressOf(Callme)];

does nothing because it initialises it to 0xFFFFFFFF.


EDIT: Ahh the old villavu mention tag bug.. Can't use the @ sign because villavu's keeps parsing it as a mention tag.. How stupid.


I think it's creating the array on the stack, then calling the assign in the delayed code.

The delayed initialization isn't that smart iirc, it just does the initialization before the first Call.
The first call being the first call on this scope, the main begin end. for global and the method contents on local.