diff --git a/compiler/aasmcnst.pas b/compiler/aasmcnst.pas index 83849ff78b..56bd0fe0e3 100644 --- a/compiler/aasmcnst.pas +++ b/compiler/aasmcnst.pas @@ -348,6 +348,12 @@ type { emits a tasmlabofs as returned by emit_*string_const } procedure emit_string_offset(const ll: tasmlabofs; const strlength: longint; const st: tstringtype; const winlikewidestring: boolean; const charptrdef: tdef);virtual; + { emits a tasmlabofs as returned by begin_dynarray_const } + procedure emit_dynarray_offset(const ll:tasmlabofs;const arrlength:asizeint;const arrdef:tdef);virtual; + { starts a dynamic array constant so that its data can be emitted directly afterwards } + function begin_dynarray_const(arrdef:tdef;var startlab:tasmlabel;out arrlengthloc:ttypedconstplaceholder):tasmlabofs;virtual; + function end_dynarray_const(arrdef:tdef;arrlength:asizeint;arrlengthloc:ttypedconstplaceholder):tdef;virtual; + { emit a shortstring constant, and return its def } function emit_shortstring_const(const str: shortstring): tdef; { emit a pchar string constant (the characters, not a pointer to them), and return its def } @@ -1701,6 +1707,53 @@ implementation end; + procedure ttai_typedconstbuilder.emit_dynarray_offset(const ll:tasmlabofs;const arrlength:asizeint;const arrdef:tdef); + begin + emit_tai(tai_const.create_sym_offset(ll.lab,ll.ofs),arrdef); + end; + + + function ttai_typedconstbuilder.begin_dynarray_const(arrdef:tdef;var startlab:tasmlabel;out arrlengthloc:ttypedconstplaceholder):tasmlabofs; + var + dynarray_symofs: asizeint; + elesize: word; + begin + result.lab:=startlab; + result.ofs:=0; + { pack the data, so that we don't add unnecessary null bytes after the + constant string } + begin_anonymous_record('',1,sizeof(TConstPtrUInt),1,1); + dynarray_symofs:=get_dynarray_symofs; + { what to do if ptrsinttype <> sizesinttype??? } + emit_tai(tai_const.create_sizeint(-1),ptrsinttype); + inc(result.ofs,ptrsinttype.size); + arrlengthloc:=emit_placeholder(sizesinttype); + inc(result.ofs,sizesinttype.size); + if dynarray_symofs=0 then + begin + { results in slightly more efficient code } + emit_tai(tai_label.create(result.lab),arrdef); + result.ofs:=0; + { create new label of the same kind (including whether or not the + name starts with target_asm.labelprefix in case it's AB_LOCAL, + so we keep the difference depending on whether the original was + allocated via getstatic/getlocal/getglobal datalabel) } + startlab:=tasmlabel.create(current_asmdata.AsmSymbolDict,startlab.name+'$dynarrlab',startlab.bind,startlab.typ); + end; + { sanity check } + if result.ofs<>dynarray_symofs then + internalerror(2018020601); + end; + + + function ttai_typedconstbuilder.end_dynarray_const(arrdef:tdef;arrlength:asizeint;arrlengthloc:ttypedconstplaceholder):tdef; + begin + { we emit the high value, not the count } + arrlengthloc.replace(tai_const.Create_sizeint(arrlength-1),sizesinttype); + result:=end_anonymous_record; + end; + + function ttai_typedconstbuilder.emit_shortstring_const(const str: shortstring): tdef; begin { we use an arraydef instead of a shortstringdef, because we don't have