mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
fixes #376
This commit is contained in:
@@ -56,7 +56,7 @@ type
|
||||
TProc{.final.} = object
|
||||
procDef: PNode
|
||||
prc: PSym
|
||||
data: PRope
|
||||
locals: PRope
|
||||
options: TOptions
|
||||
module: BModule
|
||||
g: PGlobals
|
||||
@@ -955,8 +955,8 @@ proc genSym(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
elif not p.g.generatedSyms.containsOrIncl(s.id):
|
||||
var r2: TCompRes
|
||||
genProc(p, s, r2)
|
||||
#app(p.g.code, mergeStmt(r2))
|
||||
app(r.com, mergeStmt(r2))
|
||||
app(p.locals, mergeStmt(r2))
|
||||
#app(r.com, mergeStmt(r2))
|
||||
else:
|
||||
if s.loc.r == nil:
|
||||
InternalError(n.info, "symbol has no generated name: " & s.name.s)
|
||||
@@ -1454,16 +1454,17 @@ proc genProc(oldProc: var TProc, prc: PSym, r: var TCompRes) =
|
||||
resultAsgn = nil
|
||||
name = mangleName(prc)
|
||||
header = generateHeader(p, prc.typ)
|
||||
if (prc.typ.sons[0] != nil) and sfPure notin prc.flags:
|
||||
if prc.typ.sons[0] != nil and sfPure notin prc.flags:
|
||||
resultSym = prc.ast.sons[resultPos].sym
|
||||
resultAsgn = ropef("var $1 = $2;$n", [mangleName(resultSym),
|
||||
resultAsgn = ropef("var $# = $#;$n", [mangleName(resultSym),
|
||||
createVar(p, resultSym.typ, isIndirect(resultSym))])
|
||||
gen(p, prc.ast.sons[resultPos], a)
|
||||
if a.com != nil: appf(returnStmt, "$1;$n", [a.com])
|
||||
returnStmt = ropef("return $1;$n", [a.res])
|
||||
returnStmt = ropef("return $#;$n", [a.res])
|
||||
genStmt(p, prc.getBody, r)
|
||||
r.com = ropef("function $1($2) {$n$3$4$5}$n",
|
||||
[name, header, resultAsgn, genProcBody(p, prc, r), returnStmt])
|
||||
r.com = ropef("function $#($#) {$n$#$#$#$#}$n",
|
||||
[name, header, p.locals, resultAsgn,
|
||||
genProcBody(p, prc, r), returnStmt])
|
||||
r.res = nil
|
||||
#if gVerbosity >= 3:
|
||||
# echo "END generated code for: " & prc.name.s
|
||||
@@ -1515,9 +1516,10 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) =
|
||||
nkFromStmt, nkTemplateDef, nkMacroDef, nkPragma: nil
|
||||
of nkProcDef, nkMethodDef, nkConverterDef:
|
||||
var s = n.sons[namePos].sym
|
||||
if {sfExportc, sfCompilerProc} * s.flags == {sfExportc}:
|
||||
var r2: TCompRes
|
||||
genSym(p, n.sons[namePos], r2)
|
||||
if {sfExportc, sfCompilerProc} * s.flags == {sfExportc}:
|
||||
#var r2: TCompRes
|
||||
genSym(p, n.sons[namePos], r)
|
||||
r.res = nil
|
||||
of nkGotoState, nkState:
|
||||
internalError(n.info, "first class iterators not implemented")
|
||||
else:
|
||||
@@ -1630,7 +1632,7 @@ proc myProcess(b: PPassContext, n: PNode): PNode =
|
||||
if m.module == nil: InternalError(n.info, "myProcess")
|
||||
initProc(p, globals, m, nil, m.module.options)
|
||||
genModule(p, n, r)
|
||||
app(p.g.code, p.data)
|
||||
app(p.g.code, p.locals)
|
||||
app(p.g.code, mergeStmt(r))
|
||||
|
||||
proc myClose(b: PPassContext, n: PNode): PNode =
|
||||
|
||||
33
tests/gc/closureleak.nim
Normal file
33
tests/gc/closureleak.nim
Normal file
@@ -0,0 +1,33 @@
|
||||
discard """
|
||||
outputsub: "true"
|
||||
"""
|
||||
|
||||
from strutils import join
|
||||
|
||||
type
|
||||
TFoo * = object
|
||||
id: int
|
||||
func: proc(){.closure.}
|
||||
var foo_counter = 0
|
||||
var alive_foos = newseq[int](0)
|
||||
|
||||
proc free*(some: ref TFoo) =
|
||||
#echo "Tfoo #", some.id, " freed"
|
||||
alive_foos.del alive_foos.find(some.id)
|
||||
proc newFoo*(): ref TFoo =
|
||||
new result, free
|
||||
|
||||
result.id = foo_counter
|
||||
alive_foos.add result.id
|
||||
inc foo_counter
|
||||
|
||||
for i in 0 .. <10:
|
||||
discard newFoo()
|
||||
|
||||
for i in 0 .. <10:
|
||||
let f = newFoo()
|
||||
f.func = proc =
|
||||
echo f.id
|
||||
|
||||
gc_fullcollect()
|
||||
echo alive_foos.len <= 2
|
||||
23
tests/js/test2.nim
Normal file
23
tests/js/test2.nim
Normal file
@@ -0,0 +1,23 @@
|
||||
discard """
|
||||
cmd: "nimrod js --hints:on -r $# $#"
|
||||
output: '''foo
|
||||
js 3.14'''
|
||||
"""
|
||||
|
||||
# This file tests the JavaScript generator
|
||||
|
||||
# #335
|
||||
proc foo() =
|
||||
var bar = "foo"
|
||||
proc baz() =
|
||||
echo bar
|
||||
baz()
|
||||
foo()
|
||||
|
||||
# #376
|
||||
when not defined(JS):
|
||||
proc foo(val: float): string = "no js " & $val
|
||||
else:
|
||||
proc foo(val: float): string = "js " & $val
|
||||
|
||||
echo foo(3.14)
|
||||
@@ -131,6 +131,7 @@ proc runGcTests(r: var TResults, options: string) =
|
||||
test "gcleak3"
|
||||
test "weakrefs"
|
||||
test "cycleleak"
|
||||
test "closureleak"
|
||||
|
||||
# ------------------------- threading tests -----------------------------------
|
||||
|
||||
|
||||
1
todo.txt
1
todo.txt
@@ -75,6 +75,7 @@ Concurrency
|
||||
an ``injectLoop`` pragma
|
||||
- 'writes: []' effect; track reads/writes for shared types
|
||||
- use the effect system for static deadlock prevention and race detection
|
||||
- ``~`` operator for effects
|
||||
- introduce 'noaddr' pragma to prevent taking the address of a location; this
|
||||
is very handy to prevent aliasing of global data
|
||||
|
||||
|
||||
Reference in New Issue
Block a user