Merge pull request #3835 from oderwat/OderWat-PHPFix1

Some fixes for the PHP CodeGen
This commit is contained in:
Andreas Rumpf 2016-02-07 21:11:54 +01:00
commit b557153ab7

View file

@ -400,13 +400,23 @@ proc binaryExpr(p: PProc, n: PNode, r: var TCompRes, magic, frmt: string) =
r.res = frmt % [x.rdLoc, y.rdLoc] r.res = frmt % [x.rdLoc, y.rdLoc]
r.kind = resExpr r.kind = resExpr
proc unsignedTrimmer(size: BiggestInt): Rope = proc unsignedTrimmerJS(size: BiggestInt): Rope =
case size case size
of 1: rope"& 0xff" of 1: rope"& 0xff"
of 2: rope"& 0xffff" of 2: rope"& 0xffff"
of 4: rope">>> 0" of 4: rope">>> 0"
else: rope"" else: rope""
proc unsignedTrimmerPHP(size: BiggestInt): Rope =
case size
of 1: rope"& 0xff"
of 2: rope"& 0xffff"
of 4: rope"& 0xffffffff"
else: rope""
template unsignedTrimmer(size: BiggestInt): Rope =
size.unsignedTrimmerJS | size.unsignedTrimmerPHP
proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, reassign: bool = false) = proc binaryUintExpr(p: PProc, n: PNode, r: var TCompRes, op: string, reassign: bool = false) =
var x, y: TCompRes var x, y: TCompRes
gen(p, n.sons[1], x) gen(p, n.sons[1], x)
@ -456,6 +466,10 @@ proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
gen(p, n.sons[1], x) gen(p, n.sons[1], x)
gen(p, n.sons[2], y) gen(p, n.sons[2], y)
let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size) let trimmer = unsignedTrimmer(n[1].typ.skipTypes(abstractRange).size)
if p.target == targetPHP:
# XXX prevent multi evaluations
r.res = "(($1 $2) >= 0) ? (($1 $2) >> $3) : ((($1 $2) & 0x7fffffff) >> $3) | (0x40000000 >> ($3 - 1))" % [x.rdLoc, trimmer, y.rdLoc]
else:
r.res = "(($1 $2) >>> $3)" % [x.rdLoc, trimmer, y.rdLoc] r.res = "(($1 $2) >>> $3)" % [x.rdLoc, trimmer, y.rdLoc]
of mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, of mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr,
mCStrToStr, mStrToStr, mEnumToStr: mCStrToStr, mStrToStr, mEnumToStr:
@ -464,6 +478,10 @@ proc arith(p: PProc, n: PNode, r: var TCompRes, op: TMagic) =
var x: TCompRes var x: TCompRes
gen(p, n.sons[1], x) gen(p, n.sons[1], x)
r.res = "$#[$#]" % [genEnumInfoPHP(p, n.sons[1].typ), x.rdLoc] r.res = "$#[$#]" % [genEnumInfoPHP(p, n.sons[1].typ), x.rdLoc]
elif op == mCharToStr:
var x: TCompRes
gen(p, n.sons[1], x)
r.res = "chr($#)" % [x.rdLoc]
else: else:
gen(p, n.sons[1], r) gen(p, n.sons[1], r)
else: else:
@ -838,7 +856,10 @@ proc genFieldAddr(p: PProc, n: PNode, r: var TCompRes) =
let b = if n.kind == nkHiddenAddr: n.sons[0] else: n let b = if n.kind == nkHiddenAddr: n.sons[0] else: n
gen(p, b.sons[0], a) gen(p, b.sons[0], a)
if skipTypes(b.sons[0].typ, abstractVarRange).kind == tyTuple: if skipTypes(b.sons[0].typ, abstractVarRange).kind == tyTuple:
r.res = makeJSString("Field" & $getFieldPosition(b.sons[1])) if p.target == targetJS:
r.res = makeJSString( "Field" & $getFieldPosition(b.sons[1]) )
else:
r.res = getFieldPosition(b.sons[1]).rope
else: else:
if b.sons[1].kind != nkSym: internalError(b.sons[1].info, "genFieldAddr") if b.sons[1].kind != nkSym: internalError(b.sons[1].info, "genFieldAddr")
var f = b.sons[1].sym var f = b.sons[1].sym
@ -885,6 +906,12 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
else: first = 0 else: first = 0
if optBoundsCheck in p.options and not isConstExpr(m.sons[1]): if optBoundsCheck in p.options and not isConstExpr(m.sons[1]):
useMagic(p, "chckIndx") useMagic(p, "chckIndx")
if p.target == targetPHP:
if typ.kind != tyString:
r.res = "chckIndx($1, $2, count($3))-$2" % [b.res, rope(first), a.res]
else:
r.res = "chckIndx($1, $2, strlen($3))-$2" % [b.res, rope(first), a.res]
else:
r.res = "chckIndx($1, $2, $3.length)-$2" % [b.res, rope(first), a.res] r.res = "chckIndx($1, $2, $3.length)-$2" % [b.res, rope(first), a.res]
elif first != 0: elif first != 0:
r.res = "($1)-$2" % [b.res, rope(first)] r.res = "($1)-$2" % [b.res, rope(first)]
@ -1839,7 +1866,9 @@ proc genCast(p: PProc, n: PNode, r: var TCompRes) =
r.res = "($1 $2)" % [r.res, trimmer] r.res = "($1 $2)" % [r.res, trimmer]
elif fromUint: elif fromUint:
if src.size == 4 and dest.size == 4: if src.size == 4 and dest.size == 4:
r.res = "($1|0)" % [r.res] # XXX prevent multi evaluations
r.res = "($1|0)" % [r.res] |
"($1>(float)2147483647?(int)$1-4294967296:$1)" % [r.res]
else: else:
let trimmer = unsignedTrimmer(dest.size) let trimmer = unsignedTrimmer(dest.size)
let minuend = case dest.size let minuend = case dest.size