mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-24 02:59:12 +02:00

an empty virtual method in thlcgobj and modified the WebAssembly implementation, so that it can be called from any exceptions mode (so it emits no code in exception modes that don't require it, instead of generating an internal error). This will allow .g_maybe_checkforexceptions to be called from the generic parts of the code generator, after calls to systemprocs that could raise an exceptions.
91 lines
2.8 KiB
ObjectPascal
91 lines
2.8 KiB
ObjectPascal
{
|
|
Copyright (c) 2019 by Dmitry Boyarintsev
|
|
|
|
WebAssembly-specific code for call nodes
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
****************************************************************************
|
|
}
|
|
unit nwasmcal;
|
|
|
|
{$i fpcdefs.inc}
|
|
|
|
interface
|
|
|
|
uses
|
|
cgbase,
|
|
symtype,symdef,cgutils,parabase,
|
|
node,ncal,ncgcal,hlcgobj,aasmcpu,cpubase, wasmdef;
|
|
|
|
type
|
|
{ twasmcallparanode }
|
|
|
|
twasmcallparanode = class(tcgcallparanode)
|
|
end;
|
|
|
|
{ twasmcallnode }
|
|
|
|
twasmcallnode = class(tcgcallnode)
|
|
protected
|
|
procedure extra_post_call_code; override;
|
|
procedure do_release_unused_return_value; override;
|
|
procedure set_result_location(realresdef: tstoreddef); override;
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
uses
|
|
globals, globtype, aasmdata, defutil, tgobj, hlcgcpu, symconst, symcpu;
|
|
|
|
{ twasmcallnode }
|
|
|
|
procedure twasmcallnode.extra_post_call_code;
|
|
begin
|
|
thlcgwasm(hlcg).g_adjust_stack_after_call(current_asmdata.CurrAsmList,procdefinition);
|
|
hlcg.g_maybe_checkforexceptions(current_asmdata.CurrAsmList);
|
|
end;
|
|
|
|
procedure twasmcallnode.do_release_unused_return_value;
|
|
var
|
|
ft: TWasmFuncType;
|
|
i: Integer;
|
|
begin
|
|
if procdefinition.typ=procvardef then
|
|
ft:=tcpuprocvardef(procdefinition).create_functype
|
|
else
|
|
ft:=tcpuprocdef(procdefinition).create_functype;
|
|
for i:=1 to Length(ft.results) do
|
|
begin
|
|
current_asmdata.CurrAsmList.concat(taicpu.op_none(a_drop));
|
|
thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
|
|
end;
|
|
ft.free;
|
|
end;
|
|
|
|
procedure twasmcallnode.set_result_location(realresdef: tstoreddef);
|
|
begin
|
|
// default implementation is placing the return value on LOC_REGISTER.
|
|
// WebAssembly always returns the value on stack.
|
|
location_reset_ref(location,LOC_REFERENCE,def_cgsize(realresdef),1,[]);
|
|
tg.gethltemp(current_asmdata.CurrAsmList,realresdef,retloc.intsize,tt_normal,location.reference);
|
|
end;
|
|
|
|
begin
|
|
ccallnode:=twasmcallnode;
|
|
ccallparanode:=twasmcallparanode;
|
|
end.
|