mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 16:59:11 +02:00
* changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
* in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck") * in cgai386: also small fixes to emitrangecheck
This commit is contained in:
parent
228829bd86
commit
1e6d667c3b
@ -338,25 +338,91 @@ implementation
|
|||||||
emitcall('FPC_WRITE_TEXT_'+float_name[pfloatdef(pararesult)^.typ],true);
|
emitcall('FPC_WRITE_TEXT_'+float_name[pfloatdef(pararesult)^.typ],true);
|
||||||
end;
|
end;
|
||||||
orddef : begin
|
orddef : begin
|
||||||
|
{in the range checking code, hp^.left is stil the current parameter, since
|
||||||
|
hp only gets modified when doread is false (JM)}
|
||||||
case porddef(pararesult)^.typ of
|
case porddef(pararesult)^.typ of
|
||||||
u8bit : if doread then
|
u8bit : if doread then
|
||||||
emitcall('FPC_READ_TEXT_BYTE',true);
|
{$IfDef ReadRangeCheck}
|
||||||
|
Begin
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
emitcall('FPC_READ_TEXT_BYTE',true);
|
||||||
|
{$IfDef ReadRangeCheck}
|
||||||
|
If (porddef(pararesult)^.low <> 0) or
|
||||||
|
(porddef(pararesult)^.high <> 255) Then
|
||||||
|
emitrangecheck(hp^.left,pararesult);
|
||||||
|
End;
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
|
||||||
s8bit : if doread then
|
s8bit : if doread then
|
||||||
emitcall('FPC_READ_TEXT_SHORTINT',true);
|
{$IfDef ReadRangeCheck}
|
||||||
|
Begin
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
emitcall('FPC_READ_TEXT_SHORTINT',true);
|
||||||
|
{$IfDef ReadRangeCheck}
|
||||||
|
If (porddef(pararesult)^.low <> -128) or
|
||||||
|
(porddef(pararesult)^.high <> 127) Then
|
||||||
|
emitrangecheck(hp^.left,pararesult);
|
||||||
|
End;
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
u16bit : if doread then
|
u16bit : if doread then
|
||||||
emitcall('FPC_READ_TEXT_WORD',true);
|
{$IfDef ReadRangeCheck}
|
||||||
|
Begin
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
emitcall('FPC_READ_TEXT_WORD',true);
|
||||||
|
{$IfDef ReadRangeCheck}
|
||||||
|
If (porddef(pararesult)^.low <> 0) or
|
||||||
|
(porddef(pararesult)^.high <> 65535) Then
|
||||||
|
emitrangecheck(hp^.left,pararesult);
|
||||||
|
End;
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
s16bit : if doread then
|
s16bit : if doread then
|
||||||
emitcall('FPC_READ_TEXT_INTEGER',true);
|
{$IfDef ReadRangeCheck}
|
||||||
|
Begin
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
emitcall('FPC_READ_TEXT_INTEGER',true);
|
||||||
|
{$IfDef ReadRangeCheck}
|
||||||
|
If (porddef(pararesult)^.low <> -32768) or
|
||||||
|
(porddef(pararesult)^.high <> 32767) Then
|
||||||
|
emitrangecheck(hp^.left,pararesult);
|
||||||
|
End;
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
s32bit : if doread then
|
s32bit : if doread then
|
||||||
emitcall('FPC_READ_TEXT_LONGINT',true)
|
{$IfDef ReadRangeCheck}
|
||||||
|
Begin
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
emitcall('FPC_READ_TEXT_LONGINT',true)
|
||||||
|
{$IfDef ReadRangeCheck}
|
||||||
|
;If (porddef(pararesult)^.low <> $80000000) or
|
||||||
|
(porddef(pararesult)^.high <> $7fffffff) Then
|
||||||
|
emitrangecheck(hp^.left,pararesult);
|
||||||
|
End
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
else
|
else
|
||||||
emitcall('FPC_WRITE_TEXT_LONGINT',true);
|
emitcall('FPC_WRITE_TEXT_LONGINT',true);
|
||||||
u32bit : if doread then
|
u32bit : if doread then
|
||||||
emitcall('FPC_READ_TEXT_CARDINAL',true)
|
{$IfDef ReadRangeCheck}
|
||||||
|
Begin
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
emitcall('FPC_READ_TEXT_CARDINAL',true)
|
||||||
|
{$IfDef ReadRangeCheck}
|
||||||
|
;If (porddef(pararesult)^.low <> $0) or
|
||||||
|
(porddef(pararesult)^.high <> $ffffffff) Then
|
||||||
|
emitrangecheck(hp^.left,pararesult);
|
||||||
|
End
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
else
|
else
|
||||||
emitcall('FPC_WRITE_TEXT_CARDINAL',true);
|
emitcall('FPC_WRITE_TEXT_CARDINAL',true);
|
||||||
uchar : if doread then
|
uchar : if doread then
|
||||||
emitcall('FPC_READ_TEXT_CHAR',true)
|
{$IfDef ReadRangeCheck}
|
||||||
|
Begin
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
|
emitcall('FPC_READ_TEXT_CHAR',true)
|
||||||
|
{$IfDef ReadRangeCheck}
|
||||||
|
;If (porddef(pararesult)^.low <> 0) or
|
||||||
|
(porddef(pararesult)^.high <> 255) Then
|
||||||
|
emitrangecheck(hp^.left,pararesult);
|
||||||
|
End
|
||||||
|
{$EndIf ReadRangeCheck}
|
||||||
else
|
else
|
||||||
emitcall('FPC_WRITE_TEXT_CHAR',true);
|
emitcall('FPC_WRITE_TEXT_CHAR',true);
|
||||||
s64bitint:
|
s64bitint:
|
||||||
@ -535,7 +601,7 @@ implementation
|
|||||||
exit;
|
exit;
|
||||||
|
|
||||||
if is_real then
|
if is_real then
|
||||||
emitcall(procedureprefix++float_name[pfloatdef(hp^.resulttype)^.typ],true)
|
emitcall(procedureprefix+float_name[pfloatdef(hp^.resulttype)^.typ],true)
|
||||||
else
|
else
|
||||||
case porddef(hp^.resulttype)^.typ of
|
case porddef(hp^.resulttype)^.typ of
|
||||||
u32bit:
|
u32bit:
|
||||||
@ -553,6 +619,216 @@ implementation
|
|||||||
popusedregisters(pushed);
|
popusedregisters(pushed);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$IfDef ValIntern}
|
||||||
|
|
||||||
|
Procedure Handle_Val;
|
||||||
|
|
||||||
|
var
|
||||||
|
hp,node, code_para, dest_para : ptree;
|
||||||
|
hreg: TRegister;
|
||||||
|
hdef: POrdDef;
|
||||||
|
pushed2: TPushed;
|
||||||
|
procedureprefix : string;
|
||||||
|
hr: TReference;
|
||||||
|
dummycoll : tdefcoll;
|
||||||
|
has_code, has_32bit_code, oldregisterdef: boolean;
|
||||||
|
|
||||||
|
begin
|
||||||
|
{save the register variables}
|
||||||
|
pushusedregisters(pushed,$ff);
|
||||||
|
node:=p^.left;
|
||||||
|
hp:=node;
|
||||||
|
node:=node^.right;
|
||||||
|
hp^.right:=nil;
|
||||||
|
has_32bit_code := false;
|
||||||
|
{if we have 3 parameters, we have a code parameter}
|
||||||
|
has_code := Assigned(node^.right);
|
||||||
|
reset_reference(hr);
|
||||||
|
hreg := R_NO;
|
||||||
|
|
||||||
|
{the function result will be in EAX, so we need to reserve it so
|
||||||
|
that secondpass(dest_para^.left) and secondpass(code_para^.left)
|
||||||
|
won't use it}
|
||||||
|
hreg := getexplicitregister32(R_EAX);
|
||||||
|
{if EAX is already in use, it's a register variable (ok, we've saved
|
||||||
|
those with pushusedregisters). Since we don't need another
|
||||||
|
register besides EAX, release it}
|
||||||
|
If hreg <> R_EAX Then ungetregister32(hreg);
|
||||||
|
|
||||||
|
If has_code then
|
||||||
|
Begin
|
||||||
|
{code is an orddef, that's checked in tcinl}
|
||||||
|
If (porddef(hp^.left^.resulttype)^.typ in [u32bit,s32bit]) Then
|
||||||
|
Begin
|
||||||
|
has_32bit_code := true;
|
||||||
|
code_para := hp;
|
||||||
|
hp:=node;
|
||||||
|
node:=node^.right;
|
||||||
|
hp^.right:=nil;
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
secondpass(hp^.left);
|
||||||
|
code_para := hp;
|
||||||
|
hp := node;
|
||||||
|
node:=node^.right;
|
||||||
|
hp^.right:=nil;
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
{hp = destination now, save for later use}
|
||||||
|
dest_para := hp;
|
||||||
|
secondpass(dest_para^.left);
|
||||||
|
|
||||||
|
{unget EAX (if we got it before), since otherwise pushusedregisters
|
||||||
|
will push it on the stack. No more registers are allocated before
|
||||||
|
the function call that will also have to be accessed afterwards,
|
||||||
|
so if EAX is allocated now before the function call, it doesn't
|
||||||
|
matter.}
|
||||||
|
If (hreg = R_EAX) then Ungetregister32(R_EAX);
|
||||||
|
|
||||||
|
{(if necessary) save the address loading of code_para and dest_para}
|
||||||
|
|
||||||
|
pushusedregisters(pushed2,$ff);
|
||||||
|
|
||||||
|
{now that we've already pushed the results from
|
||||||
|
secondpass(code_para^.left) and secondpass(dest_para^.left) on the
|
||||||
|
stack, we can put the real parameters on the stack}
|
||||||
|
|
||||||
|
If has_32bit_code Then
|
||||||
|
Begin
|
||||||
|
dummycoll.paratyp:=vs_var;
|
||||||
|
dummycoll.data:=code_para^.resulttype;
|
||||||
|
secondcallparan(code_para,@dummycoll,false,false,0);
|
||||||
|
if codegenerror then
|
||||||
|
exit;
|
||||||
|
Disposetree(code_para);
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
{only 32bit code parameter is supported, so fake one}
|
||||||
|
GetTempOfSizeReference(4,hr);
|
||||||
|
emitpushreferenceaddr(exprasmlist,hr);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Case dest_para^.resulttype^.deftype of
|
||||||
|
floatdef: procedureprefix := 'FPC_VAL_REAL_';
|
||||||
|
orddef:
|
||||||
|
Case PordDef(dest_para^.resulttype)^.typ of
|
||||||
|
u8bit,u16bit,u32bit{,u64bit}: procedureprefix := 'FPC_VAL_UINT_';
|
||||||
|
s8bit,s16bit,s32bit{,s64bitint}: procedureprefix := 'FPC_VAL_SINT_';
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
{node = first parameter = string}
|
||||||
|
dummycoll.paratyp:=vs_const;
|
||||||
|
dummycoll.data:=node^.resulttype;
|
||||||
|
secondcallparan(node,@dummycoll,false,false,0);
|
||||||
|
if codegenerror then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{if we are converting to a signed number, we have to include the
|
||||||
|
size of the destination, so the Val function can extend the sign
|
||||||
|
of the result to allow proper range checking}
|
||||||
|
If (dest_para^.resulttype^.deftype = orddef) Then
|
||||||
|
Case PordDef(dest_para^.resulttype)^.typ of
|
||||||
|
s8bit: exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,1)));
|
||||||
|
s16bit: exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,2)));
|
||||||
|
s32bit: exprasmlist^.concat(new(pai386,op_const(A_PUSH,S_W,4)));
|
||||||
|
End;
|
||||||
|
|
||||||
|
case pstringdef(node^.resulttype)^.string_typ of
|
||||||
|
st_widestring:
|
||||||
|
emitcall(procedureprefix+'STRWIDE',true);
|
||||||
|
st_ansistring:
|
||||||
|
emitcall(procedureprefix+'STRANSI',true);
|
||||||
|
st_shortstring:
|
||||||
|
emitcall(procedureprefix+'SSTRING',true);
|
||||||
|
st_longstring:
|
||||||
|
emitcall(procedureprefix+'STRLONG',true);
|
||||||
|
end;
|
||||||
|
disposetree(node);
|
||||||
|
p^.left := nil;
|
||||||
|
|
||||||
|
{restore the addresses loaded by secondpass}
|
||||||
|
popusedregisters(pushed2);
|
||||||
|
{reload esi in case the dest_para/code_para is a class variable or so}
|
||||||
|
maybe_loadesi;
|
||||||
|
|
||||||
|
If has_code and Not(has_32bit_code) Then
|
||||||
|
{only 16bit code is possible}
|
||||||
|
Begin
|
||||||
|
exprasmlist^.concat(new(pai386,op_ref_reg(A_MOV,S_L,NewReference(hr),R_EDI)));
|
||||||
|
emit_mov_reg_loc(R_DI,code_para^.left^.location);
|
||||||
|
Disposetree(code_para);
|
||||||
|
End;
|
||||||
|
|
||||||
|
{save the function result in the destinatin variable}
|
||||||
|
Case dest_para^.left^.resulttype^.deftype of
|
||||||
|
floatdef: floatstore(PFloatDef(dest_para^.left^.resulttype)^.typ,
|
||||||
|
dest_para^.left^.location.reference);
|
||||||
|
orddef:
|
||||||
|
Case PordDef(dest_para^.left^.resulttype)^.typ of
|
||||||
|
u8bit,s8bit:
|
||||||
|
emit_mov_reg_loc(R_AL,dest_para^.left^.location);
|
||||||
|
u16bit,s16bit:
|
||||||
|
emit_mov_reg_loc(R_AX,dest_para^.left^.location);
|
||||||
|
u32bit,s32bit:
|
||||||
|
emit_mov_reg_loc(R_EAX,dest_para^.left^.location);
|
||||||
|
{u64bit,s64bitint: ???}
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
If (cs_check_range in aktlocalswitches) and
|
||||||
|
(dest_para^.left^.resulttype^.deftype = orddef) and
|
||||||
|
{the following has to be changed to 64bit checking, once Val
|
||||||
|
returns 64 bit values (unless a special Val function is created
|
||||||
|
for that}
|
||||||
|
{no need to rangecheck longints or cardinals on 32bit processors}
|
||||||
|
not((porddef(dest_para^.left^.resulttype)^.typ = s32bit) and
|
||||||
|
(porddef(dest_para^.left^.resulttype)^.low = $80000000) and
|
||||||
|
(porddef(dest_para^.left^.resulttype)^.high = $7fffffff)) and
|
||||||
|
not((porddef(dest_para^.left^.resulttype)^.typ = u32bit) and
|
||||||
|
(porddef(dest_para^.left^.resulttype)^.low = 0) and
|
||||||
|
(porddef(dest_para^.left^.resulttype)^.high = $ffffffff)) then
|
||||||
|
Begin
|
||||||
|
If has_32bit_code then
|
||||||
|
{we don't have temporary variable space yet}
|
||||||
|
GetTempOfSizeReference(4,hr);
|
||||||
|
{save the result in a temp variable, because EAX may be
|
||||||
|
overwritten by popusedregs()}
|
||||||
|
exprasmlist^.concat(new(pai386,op_reg_ref(A_MOV,S_L,R_EAX,NewReference(hr))));
|
||||||
|
{clean up the stack, so a backtrace is possible if range check
|
||||||
|
fails}
|
||||||
|
popusedregisters(pushed);
|
||||||
|
{create a temporary 32bit location for the returned value}
|
||||||
|
hp := getcopy(dest_para^.left);
|
||||||
|
hp^.location.loc := LOC_REFERENCE;
|
||||||
|
hp^.location.reference := hr;
|
||||||
|
{do not register this temporary def}
|
||||||
|
OldRegisterDef := RegisterDef;
|
||||||
|
RegisterDef := False;
|
||||||
|
Case PordDef(dest_para^.left^.resulttype)^.typ of
|
||||||
|
u8bit,u16bit,u32bit: new(hdef,init(u32bit,0,$fffffff));
|
||||||
|
s8bit,s16bit,s32bit: new(hdef,init(s32bit,$fffffff,$7ffffff));
|
||||||
|
end;
|
||||||
|
hp^.resulttype := hdef;
|
||||||
|
emitrangecheck(hp,dest_para^.left^.resulttype);
|
||||||
|
hp^.right := nil;
|
||||||
|
Dispose(hp^.resulttype, Done);
|
||||||
|
RegisterDef := OldRegisterDef;
|
||||||
|
disposetree(hp);
|
||||||
|
{it's possible that the range cheking was handled by a
|
||||||
|
procedure that has destroyed ESI}
|
||||||
|
maybe_loadesi;
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
{clean up the stack}
|
||||||
|
popusedregisters(pushed);
|
||||||
|
{dest_para^right is already nil}
|
||||||
|
disposetree(dest_para);
|
||||||
|
UnGetIfTemp(hr);
|
||||||
|
end;
|
||||||
|
{$EndIf ValIntern}
|
||||||
|
|
||||||
var
|
var
|
||||||
r : preference;
|
r : preference;
|
||||||
hp : ptree;
|
hp : ptree;
|
||||||
@ -943,6 +1219,12 @@ implementation
|
|||||||
handle_str;
|
handle_str;
|
||||||
maybe_loadesi;
|
maybe_loadesi;
|
||||||
end;
|
end;
|
||||||
|
{$IfDef ValIntern}
|
||||||
|
in_val_x :
|
||||||
|
Begin
|
||||||
|
handle_val;
|
||||||
|
End;
|
||||||
|
{$EndIf ValIntern}
|
||||||
in_include_x_y,
|
in_include_x_y,
|
||||||
in_exclude_x_y:
|
in_exclude_x_y:
|
||||||
begin
|
begin
|
||||||
@ -1027,7 +1309,12 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.29 1999-02-25 21:02:27 peter
|
Revision 1.30 1999-03-16 17:52:56 jonas
|
||||||
|
* changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
|
||||||
|
* in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
|
||||||
|
* in cgai386: also small fixes to emitrangecheck
|
||||||
|
|
||||||
|
Revision 1.29 1999/02/25 21:02:27 peter
|
||||||
* ag386bin updates
|
* ag386bin updates
|
||||||
+ coff writer
|
+ coff writer
|
||||||
|
|
||||||
|
@ -417,6 +417,29 @@ unit pexpr;
|
|||||||
pd:=voiddef;
|
pd:=voiddef;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$IfDef ValIntern}
|
||||||
|
in_val_x:
|
||||||
|
Begin
|
||||||
|
consume(LKLAMMER);
|
||||||
|
in_args := true;
|
||||||
|
p1:= gencallparanode(comp_expr(true), nil);
|
||||||
|
Must_be_valid := False;
|
||||||
|
consume(COMMA);
|
||||||
|
p2 := gencallparanode(comp_expr(true),p1);
|
||||||
|
if (token = COMMA) then
|
||||||
|
Begin
|
||||||
|
consume(COMMA);
|
||||||
|
p2 := gencallparanode(comp_expr(true),p2)
|
||||||
|
End;
|
||||||
|
consume(RKLAMMER);
|
||||||
|
p2 := geninlinenode(l,false,p2);
|
||||||
|
do_firstpass(p2);
|
||||||
|
statement_syssym := p2;
|
||||||
|
pd := voiddef;
|
||||||
|
End;
|
||||||
|
{$EndIf ValIntern}
|
||||||
|
|
||||||
|
|
||||||
in_include_x_y,
|
in_include_x_y,
|
||||||
in_exclude_x_y :
|
in_exclude_x_y :
|
||||||
begin
|
begin
|
||||||
@ -1936,7 +1959,12 @@ unit pexpr;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.86 1999-03-04 13:55:44 pierre
|
Revision 1.87 1999-03-16 17:52:52 jonas
|
||||||
|
* changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
|
||||||
|
* in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
|
||||||
|
* in cgai386: also small fixes to emitrangecheck
|
||||||
|
|
||||||
|
Revision 1.86 1999/03/04 13:55:44 pierre
|
||||||
* some m68k fixes (still not compilable !)
|
* some m68k fixes (still not compilable !)
|
||||||
* new(tobj) does not give warning if tobj has no VMT !
|
* new(tobj) does not give warning if tobj has no VMT !
|
||||||
|
|
||||||
|
@ -63,6 +63,9 @@ begin
|
|||||||
p^.insert(new(psyssym,init('INC',in_inc_x)));
|
p^.insert(new(psyssym,init('INC',in_inc_x)));
|
||||||
p^.insert(new(psyssym,init('STR',in_str_x_string)));
|
p^.insert(new(psyssym,init('STR',in_str_x_string)));
|
||||||
p^.insert(new(psyssym,init('ASSERT',in_assert_x_y)));
|
p^.insert(new(psyssym,init('ASSERT',in_assert_x_y)));
|
||||||
|
{$IfDef ValIntern}
|
||||||
|
p^.insert(new(psyssym,init('VAL',in_val_x)));
|
||||||
|
{$EndIf ValIntern}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -253,7 +256,12 @@ end;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.16 1999-03-02 02:56:17 peter
|
Revision 1.17 1999-03-16 17:52:54 jonas
|
||||||
|
* changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
|
||||||
|
* in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
|
||||||
|
* in cgai386: also small fixes to emitrangecheck
|
||||||
|
|
||||||
|
Revision 1.16 1999/03/02 02:56:17 peter
|
||||||
+ stabs support for binary writers
|
+ stabs support for binary writers
|
||||||
* more fixes and missing updates from the previous commit :(
|
* more fixes and missing updates from the previous commit :(
|
||||||
|
|
||||||
|
@ -106,6 +106,9 @@ implementation
|
|||||||
count_ref:=false;
|
count_ref:=false;
|
||||||
if not (p^.inlinenumber in [in_read_x,in_readln_x,in_sizeof_x,
|
if not (p^.inlinenumber in [in_read_x,in_readln_x,in_sizeof_x,
|
||||||
in_typeof_x,in_ord_x,in_str_x_string,
|
in_typeof_x,in_ord_x,in_str_x_string,
|
||||||
|
{$IfDef ValIntern}
|
||||||
|
in_val_x,
|
||||||
|
{$EndIf ValIntern}
|
||||||
in_reset_typedfile,in_rewrite_typedfile]) then
|
in_reset_typedfile,in_rewrite_typedfile]) then
|
||||||
must_be_valid:=true
|
must_be_valid:=true
|
||||||
else
|
else
|
||||||
@ -807,6 +810,73 @@ implementation
|
|||||||
{ calc registers }
|
{ calc registers }
|
||||||
left_right_max(p);
|
left_right_max(p);
|
||||||
end;
|
end;
|
||||||
|
{$IfDef ValIntern}
|
||||||
|
|
||||||
|
in_val_x :
|
||||||
|
begin
|
||||||
|
procinfo.flags:=procinfo.flags or pi_do_call;
|
||||||
|
p^.resulttype:=voiddef;
|
||||||
|
{ check the amount of parameters }
|
||||||
|
if not(assigned(p^.left)) or
|
||||||
|
not(assigned(p^.left^.right)) then
|
||||||
|
begin
|
||||||
|
CGMessage(parser_e_wrong_parameter_size);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
If Assigned(p^.left^.right^.right) Then
|
||||||
|
{there is a "code" parameter}
|
||||||
|
Begin
|
||||||
|
{ first pass just the code parameter for first local use}
|
||||||
|
hp := p^.left^.right;
|
||||||
|
p^.left^.right := nil;
|
||||||
|
must_be_valid := false;
|
||||||
|
count_ref := true;
|
||||||
|
firstcallparan(p^.left, nil);
|
||||||
|
if codegenerror then exit;
|
||||||
|
p^.left^.right := hp;
|
||||||
|
{code has to be a var parameter}
|
||||||
|
if (p^.left^.left^.location.loc<>LOC_REFERENCE) then
|
||||||
|
CGMessage(type_e_variable_id_expected)
|
||||||
|
else
|
||||||
|
if (p^.left^.left^.resulttype^.deftype <> orddef) or
|
||||||
|
not(porddef(p^.left^.left^.resulttype)^.typ in
|
||||||
|
[u16bit,s16bit,u32bit,s32bit]) then
|
||||||
|
CGMessage(type_e_mismatch);
|
||||||
|
hpp := p^.left^.right
|
||||||
|
End
|
||||||
|
Else hpp := p^.left;
|
||||||
|
{now hpp = the destination value tree}
|
||||||
|
{ first pass just the destination parameter for first local use}
|
||||||
|
hp:=hpp^.right;
|
||||||
|
must_be_valid:=false;
|
||||||
|
count_ref:=true;
|
||||||
|
hpp^.right:=nil;
|
||||||
|
{hpp = destination}
|
||||||
|
firstcallparan(hpp,nil);
|
||||||
|
if codegenerror then exit;
|
||||||
|
hpp^.right := hp;
|
||||||
|
if (hpp^.left^.location.loc<>LOC_REFERENCE) then
|
||||||
|
CGMessage(type_e_variable_id_expected)
|
||||||
|
else
|
||||||
|
If Not((hpp^.left^.resulttype^.deftype = floatdef) or
|
||||||
|
((hpp^.left^.resulttype^.deftype = orddef) And
|
||||||
|
(POrdDef(hpp^.left^.resulttype)^.typ in
|
||||||
|
[u32bit,s32bit,{s64bitint,u64bit, -- not supported yet in RTL}
|
||||||
|
u8bit,s8bit,u16bit,s16bit])))
|
||||||
|
Then CGMessage(type_e_mismatch);
|
||||||
|
must_be_valid:=true;
|
||||||
|
{hp = source (String)}
|
||||||
|
count_ref := false;
|
||||||
|
must_be_valid := true;
|
||||||
|
firstcallparan(hp,nil);
|
||||||
|
if codegenerror then exit;
|
||||||
|
If (hp^.resulttype^.deftype<>stringdef) then
|
||||||
|
CGMessage(type_e_mismatch);
|
||||||
|
{ firstcallparan(p^.left,nil);}
|
||||||
|
{ calc registers }
|
||||||
|
left_right_max(p);
|
||||||
|
end;
|
||||||
|
{$EndIf ValIntern}
|
||||||
in_include_x_y,
|
in_include_x_y,
|
||||||
in_exclude_x_y:
|
in_exclude_x_y:
|
||||||
begin
|
begin
|
||||||
@ -978,7 +1048,12 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.19 1999-02-22 12:36:34 florian
|
Revision 1.20 1999-03-16 17:52:55 jonas
|
||||||
|
* changes for internal Val code (do a "make cycle OPT=-dvalintern" to test)
|
||||||
|
* in cgi386inl: also range checking for subrange types (compile with "-dreadrangecheck")
|
||||||
|
* in cgai386: also small fixes to emitrangecheck
|
||||||
|
|
||||||
|
Revision 1.19 1999/02/22 12:36:34 florian
|
||||||
+ warning for lo/hi(longint/dword) in -So and -Sd mode added
|
+ warning for lo/hi(longint/dword) in -So and -Sd mode added
|
||||||
|
|
||||||
Revision 1.18 1999/02/22 02:15:49 peter
|
Revision 1.18 1999/02/22 02:15:49 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user