diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 74f8f90cdc..926f30985b 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -2315,6 +2315,15 @@ proc genConstExpr(p: BProc, n: PNode): Rope = var t = skipTypes(n.typ, abstractInst) if t.kind == tySequence: result = genConstSeq(p, n, n.typ) + elif t.kind == tyProc and t.callConv == ccClosure and not n.sons.isNil and + n.sons[0].kind == nkNilLit and n.sons[1].kind == nkNilLit: + # this hack fixes issue that nkNilLit is expanded to {NIM_NIL,NIM_NIL} + # this behaviour is needed since closure_var = nil must be + # expanded to {NIM_NIL,NIM_NIL} + # in VM closures are initialized with nkPar(nkNilLit, nkNilLit) + # leading to duplicate code like this: + # "{NIM_NIL,NIM_NIL}, {NIM_NIL,NIM_NIL}" + result = ~"{NIM_NIL,NIM_NIL}" else: result = genConstSimpleList(p, n) of nkObjConstr: diff --git a/compiler/vm.nim b/compiler/vm.nim index 2dd6d6a9c8..93cf66c050 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -409,6 +409,28 @@ proc recSetFlagIsRef(arg: PNode) = for i in 0 ..< arg.safeLen: arg.sons[i].recSetFlagIsRef +proc setLenSeq(c: PCtx; node: PNode; newLen: int; info: TLineInfo) = + # FIXME: this doesn't attempt to solve incomplete + # support of tyPtr, tyRef in VM. + let typ = node.typ.skipTypes(abstractInst+{tyRange}-{tyTypeDesc}) + let typeEntry = typ.sons[0].skipTypes(abstractInst+{tyRange}-{tyTypeDesc}) + let typeKind = case typeEntry.kind + of tyUInt..tyUInt64: nkUIntLit + of tyRange, tyEnum, tyBool, tyChar, tyInt..tyInt64: nkIntLit + of tyFloat..tyFloat128: nkFloatLit + of tyString: nkStrLit + of tyObject: nkObjConstr + of tySequence: nkNilLit + of tyProc, tyTuple: nkPar + else: nkEmpty + + let oldLen = node.len + setLen(node.sons, newLen) + if oldLen < newLen: + # TODO: This is still not correct for tyPtr, tyRef default value + for i in oldLen ..