diff options
author | metagn <metagngn@gmail.com> | 2023-08-21 21:08:00 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-21 20:08:00 +0200 |
commit | 942f846f04b4fa3c3154f7277ab1a8f6762d2714 (patch) | |
tree | 4949e988218d6fc76ab1ccaeea74e8bbb87cdd98 | |
parent | a4781dc4bcdf6e76076af80d0b21cb09865b3d44 (diff) | |
download | Nim-942f846f04b4fa3c3154f7277ab1a8f6762d2714.tar.gz |
fix getNullValue for cstring in VM, make other VM code aware of nil cstring (#22527)
* fix getNullValue for cstring in VM fixes #22524 * very ugly fixes, but fix #15730 * nil cstring len works, more test lines * fix high
-rw-r--r-- | compiler/vm.nim | 19 | ||||
-rw-r--r-- | compiler/vmdef.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 7 | ||||
-rw-r--r-- | tests/vm/tvmmisc.nim | 31 |
4 files changed, 53 insertions, 6 deletions
diff --git a/compiler/vm.nim b/compiler/vm.nim index 1f4e4333d..79832dbcb 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -1017,7 +1017,10 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcLenCstring: decodeBImm(rkInt) assert regs[rb].kind == rkNode - regs[ra].intVal = regs[rb].node.strVal.cstring.len - imm + if regs[rb].node.kind == nkNilLit: + regs[ra].intVal = -imm + else: + regs[ra].intVal = regs[rb].node.strVal.cstring.len - imm of opcIncl: decodeB(rkNode) let b = regs[rb].regToNode @@ -1215,6 +1218,12 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = of opcEqStr: decodeBC(rkInt) regs[ra].intVal = ord(regs[rb].node.strVal == regs[rc].node.strVal) + of opcEqCString: + decodeBC(rkInt) + let bNil = regs[rb].node.kind == nkNilLit + let cNil = regs[rc].node.kind == nkNilLit + regs[ra].intVal = ord((bNil and cNil) or + (not bNil and not cNil and regs[rb].node.strVal == regs[rc].node.strVal)) of opcLeStr: decodeBC(rkInt) regs[ra].intVal = ord(regs[rb].node.strVal <= regs[rc].node.strVal) @@ -1498,7 +1507,13 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg = regs[ra].node c.currentExceptionA = raised # Set the `name` field of the exception - c.currentExceptionA[2].skipColon.strVal = c.currentExceptionA.typ.sym.name.s + var exceptionNameNode = newStrNode(nkStrLit, c.currentExceptionA.typ.sym.name.s) + if c.currentExceptionA[2].kind == nkExprColonExpr: + exceptionNameNode.typ = c.currentExceptionA[2][1].typ + c.currentExceptionA[2][1] = exceptionNameNode + else: + exceptionNameNode.typ = c.currentExceptionA[2].typ + c.currentExceptionA[2] = exceptionNameNode c.exceptionInstr = pc var frame = tos diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index f369908ba..bdb0aeed1 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -99,7 +99,7 @@ type opcLeFloat, opcLtFloat, opcLeu, opcLtu, opcEqRef, opcEqNimNode, opcSameNodeType, opcXor, opcNot, opcUnaryMinusInt, opcUnaryMinusFloat, opcBitnotInt, - opcEqStr, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet, + opcEqStr, opcEqCString, opcLeStr, opcLtStr, opcEqSet, opcLeSet, opcLtSet, opcMulSet, opcPlusSet, opcMinusSet, opcConcatStr, opcContainsSet, opcRepr, opcSetLenStr, opcSetLenSeq, opcIsNil, opcOf, opcIs, diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 8aaac6272..e58ddbeb9 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1159,7 +1159,8 @@ proc genMagic(c: PCtx; n: PNode; dest: var TDest; m: TMagic) = c.gABC(n, opcNarrowU, dest, TRegister(size*8)) of mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr: genConv(c, n, n[1], dest) - of mEqStr, mEqCString: genBinaryABC(c, n, dest, opcEqStr) + of mEqStr: genBinaryABC(c, n, dest, opcEqStr) + of mEqCString: genBinaryABC(c, n, dest, opcEqCString) of mLeStr: genBinaryABC(c, n, dest, opcLeStr) of mLtStr: genBinaryABC(c, n, dest, opcLtStr) of mEqSet: genBinarySet(c, n, dest, opcEqSet) @@ -1877,10 +1878,10 @@ proc getNullValue(typ: PType, info: TLineInfo; conf: ConfigRef): PNode = result = newNodeIT(nkUIntLit, info, t) of tyFloat..tyFloat128: result = newNodeIT(nkFloatLit, info, t) - of tyCstring, tyString: + of tyString: result = newNodeIT(nkStrLit, info, t) result.strVal = "" - of tyVar, tyLent, tyPointer, tyPtr, tyUntyped, + of tyCstring, tyVar, tyLent, tyPointer, tyPtr, tyUntyped, tyTyped, tyTypeDesc, tyRef, tyNil: result = newNodeIT(nkNilLit, info, t) of tyProc: diff --git a/tests/vm/tvmmisc.nim b/tests/vm/tvmmisc.nim index da8208f73..5760422a1 100644 --- a/tests/vm/tvmmisc.nim +++ b/tests/vm/tvmmisc.nim @@ -735,3 +735,34 @@ block: # bug #22190 tab = mkOpTable(Berlin) doAssert not tab + +block: # issue #22524 + const cnst = cstring(nil) + doAssert cnst.isNil + doAssert cnst == nil + let b = cnst + doAssert b.isNil + doAssert b == nil + + let a = static: cstring(nil) + doAssert a.isNil + + static: + var x: cstring + doAssert x.isNil + doAssert x == nil + doAssert x != "" + +block: # issue #15730 + const s: cstring = "" + doAssert s != nil + + static: + let s: cstring = "" + doAssert not s.isNil + doAssert s != nil + doAssert s == "" + +static: # more nil cstring issues + let x = cstring(nil) + doAssert x.len == 0 |