|
@@ -48,6 +48,8 @@ unit pararv;
|
|
|
|
|
|
function create_varargs_paraloc_info(p: tabstractprocdef; side: tcallercallee; varargspara: tvarargsparalist): longint;override;
|
|
|
|
|
|
+ function push_addr_param(varspez: tvarspez; def: tdef; calloption: tproccalloption): boolean;override;
|
|
|
+
|
|
|
protected
|
|
|
procedure init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
|
|
|
end;
|
|
@@ -198,6 +200,52 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ function trvparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
|
|
|
+ begin
|
|
|
+ result:=false;
|
|
|
+ { var,out,constref always require address }
|
|
|
+ if varspez in [vs_var,vs_out,vs_constref] then
|
|
|
+ begin
|
|
|
+ result:=true;
|
|
|
+ exit;
|
|
|
+ end;
|
|
|
+ case def.typ of
|
|
|
+ variantdef,
|
|
|
+ formaldef :
|
|
|
+ result:=true;
|
|
|
+ { regular procvars must be passed by value, because you cannot pass
|
|
|
+ the address of a local stack location when calling e.g.
|
|
|
+ pthread_create with the address of a function (first of all it
|
|
|
+ expects the address of the function to execute and not the address
|
|
|
+ of a memory location containing that address, and secondly if you
|
|
|
+ first store the address on the stack and then pass the address of
|
|
|
+ this stack location, then this stack location may no longer be
|
|
|
+ valid when the newly started thread accesses it.
|
|
|
+
|
|
|
+ However, for "procedure of object" we must use the same calling
|
|
|
+ convention as for "8 byte record" due to the need for
|
|
|
+ interchangeability with the TMethod record type.
|
|
|
+ }
|
|
|
+ procvardef,
|
|
|
+ recorddef:
|
|
|
+ result := not(def.size in [0..sizeof(aint)*2]) or (varspez = vs_const);
|
|
|
+ arraydef:
|
|
|
+ result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
|
|
|
+ is_open_array(def) or
|
|
|
+ is_array_of_const(def) or
|
|
|
+ is_array_constructor(def);
|
|
|
+ objectdef :
|
|
|
+ result:=is_object(def);
|
|
|
+ setdef :
|
|
|
+ result:=not is_smallset(def);
|
|
|
+ stringdef :
|
|
|
+ result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
|
|
|
+ else
|
|
|
+ ;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
function trvparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; forcetempdef: tdef): tcgpara;
|
|
|
var
|
|
|
paraloc : pcgparalocation;
|