mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-03 12:29:25 +01:00
* moved JVM-specific code of tloadvmtaddrnode.pass_1 to njvmmem
* create separate nodes for Objective-C in tloadvmtaddrnode.pass_1
instead of implicitly relying on the fact that the Objective-C
ISA field is at the same offset as the VMT of Object-Pascal
classes
o translate the resulting loads of ISA field into direct pointer
accesses, so that even on non-fragile ABI platforms we don't
go via an indirection (like clang/gcc)
git-svn-id: trunk@30947 -
This commit is contained in:
parent
033c28e5ac
commit
703e31512d
@ -52,6 +52,7 @@ interface
|
||||
end;
|
||||
|
||||
tjvmloadvmtaddrnode = class(tcgloadvmtaddrnode)
|
||||
function pass_1: tnode; override;
|
||||
procedure pass_generate_code; override;
|
||||
end;
|
||||
|
||||
@ -317,6 +318,28 @@ implementation
|
||||
TJVMLOADVMTADDRNODE
|
||||
*****************************************************************************}
|
||||
|
||||
function tjvmloadvmtaddrnode.pass_1: tnode;
|
||||
var
|
||||
vs: tsym;
|
||||
begin
|
||||
result:=nil;
|
||||
if is_javaclass(left.resultdef) and
|
||||
(left.nodetype<>typen) and
|
||||
(left.resultdef.typ<>classrefdef) then
|
||||
begin
|
||||
{ call java.lang.Object.getClass() }
|
||||
vs:=search_struct_member(tobjectdef(left.resultdef),'GETCLASS');
|
||||
if not assigned(vs) or
|
||||
(tsym(vs).typ<>procsym) then
|
||||
internalerror(2011041901);
|
||||
result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[]);
|
||||
inserttypeconv_explicit(result,resultdef);
|
||||
{ reused }
|
||||
left:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tjvmloadvmtaddrnode.pass_generate_code;
|
||||
begin
|
||||
current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_ldc,current_asmdata.RefAsmSymbol(
|
||||
|
||||
@ -153,7 +153,7 @@ implementation
|
||||
globtype,systems,constexp,
|
||||
cutils,verbose,globals,
|
||||
symconst,symbase,defutil,defcmp,
|
||||
nbas,ninl,nutils,
|
||||
nbas,ninl,nutils,objcutil,
|
||||
wpobase,
|
||||
{$ifdef i8086}
|
||||
cpuinfo,
|
||||
@ -248,39 +248,26 @@ implementation
|
||||
include(current_procinfo.flags,pi_needs_got);
|
||||
if left.nodetype<>typen then
|
||||
begin
|
||||
if (target_info.system=system_aarch64_darwin) and
|
||||
(is_objc_class_or_protocol(left.resultdef) or
|
||||
if (is_objc_class_or_protocol(left.resultdef) or
|
||||
is_objcclassref(left.resultdef)) then
|
||||
begin
|
||||
{ on Darwin/AArch64, the isa field is opaque and we must
|
||||
call Object_getClass to obtain the actual ISA pointer }
|
||||
result:=ccallnode.createinternfromunit('OBJC','OBJECT_GETCLASS',ccallparanode.create(left,nil));
|
||||
inserttypeconv_explicit(result,resultdef);
|
||||
{ reused }
|
||||
left:=nil;
|
||||
end
|
||||
else if is_javaclass(left.resultdef) and
|
||||
(left.nodetype<>typen) and
|
||||
(left.resultdef.typ<>classrefdef) then
|
||||
begin
|
||||
{ call java.lang.Object.getClass() }
|
||||
vs:=search_struct_member(tobjectdef(left.resultdef),'GETCLASS');
|
||||
if not assigned(vs) or
|
||||
(tsym(vs).typ<>procsym) then
|
||||
internalerror(2011041901);
|
||||
result:=ccallnode.create(nil,tprocsym(vs),vs.owner,left,[]);
|
||||
inserttypeconv_explicit(result,resultdef);
|
||||
if target_info.system=system_aarch64_darwin then
|
||||
begin
|
||||
{ on Darwin/AArch64, the isa field is opaque and we must
|
||||
call Object_getClass to obtain the actual ISA pointer }
|
||||
result:=ccallnode.createinternfromunit('OBJC','OBJECT_GETCLASS',ccallparanode.create(left,nil));
|
||||
inserttypeconv_explicit(result,resultdef);
|
||||
end
|
||||
else
|
||||
result:=objcloadbasefield(left,'ISA');
|
||||
{ reused }
|
||||
left:=nil;
|
||||
end
|
||||
else
|
||||
firstpass(left)
|
||||
firstpass(left);
|
||||
end
|
||||
else if not is_objcclass(left.resultdef) and
|
||||
not is_objcclassref(left.resultdef) and
|
||||
not is_javaclass(left.resultdef) and
|
||||
not is_javaclassref(left.resultdef) and
|
||||
not is_javainterface(left.resultdef) then
|
||||
not is_objcclassref(left.resultdef) then
|
||||
begin
|
||||
if not(nf_ignore_for_wpo in flags) and
|
||||
(not assigned(current_procinfo) or
|
||||
|
||||
@ -45,6 +45,10 @@ interface
|
||||
{ Exports all assembler symbols related to the obj-c class }
|
||||
procedure exportobjcclass(def: tobjectdef);
|
||||
|
||||
{ loads a field of an Objective-C root class (such as ISA) }
|
||||
function objcloadbasefield(n: tnode; const fieldname: string): tnode;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -112,12 +116,23 @@ end;
|
||||
var
|
||||
vs : tsym;
|
||||
begin
|
||||
result:=cderefnode.create(ctypeconvnode.create_internal(n,objc_idtype));
|
||||
vs:=tsym(tabstractrecorddef(objc_objecttype).symtable.Find(fieldname));
|
||||
if not assigned(vs) or
|
||||
(vs.typ<>fieldvarsym) then
|
||||
internalerror(200911301);
|
||||
result:=csubscriptnode.create(vs,result);
|
||||
if fieldname='ISA' then
|
||||
result:=ctypeconvnode.create_internal(
|
||||
cderefnode.create(
|
||||
ctypeconvnode.create_internal(n,
|
||||
getpointerdef(getpointerdef(voidpointertype))
|
||||
)
|
||||
),tfieldvarsym(vs).vardef
|
||||
)
|
||||
else
|
||||
begin
|
||||
result:=cderefnode.create(ctypeconvnode.create_internal(n,objc_idtype));
|
||||
result:=csubscriptnode.create(vs,result);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -147,10 +162,7 @@ end;
|
||||
{$endif onlymacosx10_6 or arm aarch64}
|
||||
result:=cloadvmtaddrnode.create(ctypenode.create(tobjectdef(tclassrefdef(def).pointeddef).childof.childof));
|
||||
tloadvmtaddrnode(result).forcall:=true;
|
||||
if target_info.system<>system_aarch64_darwin then
|
||||
result:=objcloadbasefield(result,'ISA')
|
||||
else
|
||||
result:=cloadvmtaddrnode.create(result);
|
||||
result:=cloadvmtaddrnode.create(result);
|
||||
typecheckpass(result);
|
||||
{ we're done }
|
||||
exit;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user