capturing of an iterator works better
This commit is contained in:
parent
f51a4ece6a
commit
e478374e0d
2 changed files with 24 additions and 11 deletions
|
|
@ -116,7 +116,8 @@ type
|
||||||
TDep = tuple[e: PEnv, field: PSym]
|
TDep = tuple[e: PEnv, field: PSym]
|
||||||
TEnv {.final.} = object of TObject
|
TEnv {.final.} = object of TObject
|
||||||
attachedNode: PNode
|
attachedNode: PNode
|
||||||
createdVar: PSym # if != nil it is a used environment
|
createdVar: PSym # if != nil it is a used environment
|
||||||
|
createdVarComesFromIter: bool
|
||||||
capturedVars: seq[PSym] # captured variables in this environment
|
capturedVars: seq[PSym] # captured variables in this environment
|
||||||
deps: seq[TDep] # dependencies
|
deps: seq[TDep] # dependencies
|
||||||
up: PEnv
|
up: PEnv
|
||||||
|
|
@ -571,7 +572,14 @@ proc rawClosureCreation(o: POuterContext, scope: PEnv; env: PSym): PNode =
|
||||||
# maybe later: (sfByCopy in local.flags)
|
# maybe later: (sfByCopy in local.flags)
|
||||||
# add ``env.param = param``
|
# add ``env.param = param``
|
||||||
result.add(newAsgnStmt(fieldAccess, newSymNode(local), env.info))
|
result.add(newAsgnStmt(fieldAccess, newSymNode(local), env.info))
|
||||||
idNodeTablePut(o.localsToAccess, local, fieldAccess)
|
# it can happen that we already captured 'local' in some other environment
|
||||||
|
# then we capture by copy for now. This is not entirely correct but better
|
||||||
|
# than nothing:
|
||||||
|
let existing = idNodeTableGet(o.localsToAccess, local)
|
||||||
|
if existing.isNil:
|
||||||
|
idNodeTablePut(o.localsToAccess, local, fieldAccess)
|
||||||
|
else:
|
||||||
|
result.add(newAsgnStmt(fieldAccess, existing, env.info))
|
||||||
# add support for 'up' references:
|
# add support for 'up' references:
|
||||||
for e, field in items(scope.deps):
|
for e, field in items(scope.deps):
|
||||||
# add ``env.up = env2``
|
# add ``env.up = env2``
|
||||||
|
|
@ -584,14 +592,19 @@ proc generateClosureCreation(o: POuterContext, scope: PEnv): PNode =
|
||||||
|
|
||||||
proc generateIterClosureCreation(o: POuterContext; env: PEnv;
|
proc generateIterClosureCreation(o: POuterContext; env: PEnv;
|
||||||
scope: PNode): PSym =
|
scope: PNode): PSym =
|
||||||
result = newClosureCreationVar(o, env)
|
if env.createdVarComesFromIter or env.createdVar.isNil:
|
||||||
let cc = rawClosureCreation(o, env, result)
|
# we have to create a new closure:
|
||||||
var insertPoint = scope.sons[0]
|
result = newClosureCreationVar(o, env)
|
||||||
if insertPoint.kind == nkEmpty: scope.sons[0] = cc
|
let cc = rawClosureCreation(o, env, result)
|
||||||
|
var insertPoint = scope.sons[0]
|
||||||
|
if insertPoint.kind == nkEmpty: scope.sons[0] = cc
|
||||||
|
else:
|
||||||
|
assert cc.kind == nkStmtList and insertPoint.kind == nkStmtList
|
||||||
|
for x in cc: insertPoint.add(x)
|
||||||
|
if env.createdVar == nil: env.createdVar = result
|
||||||
else:
|
else:
|
||||||
assert cc.kind == nkStmtList and insertPoint.kind == nkStmtList
|
result = env.createdVar
|
||||||
for x in cc: insertPoint.add(x)
|
env.createdVarComesFromIter = true
|
||||||
if env.createdVar == nil: env.createdVar = result
|
|
||||||
|
|
||||||
proc interestingIterVar(s: PSym): bool {.inline.} =
|
proc interestingIterVar(s: PSym): bool {.inline.} =
|
||||||
result = s.kind in {skVar, skLet, skTemp, skForVar} and sfGlobal notin s.flags
|
result = s.kind in {skVar, skLet, skTemp, skForVar} and sfGlobal notin s.flags
|
||||||
|
|
|
||||||
|
|
@ -689,8 +689,8 @@ var
|
||||||
WSAID_GETACCEPTEXSOCKADDRS*: TGUID = TGUID(D1: 0xb5367df2'i32, D2: 0xcbac'i16, D3: 0x11cf, D4: [
|
WSAID_GETACCEPTEXSOCKADDRS*: TGUID = TGUID(D1: 0xb5367df2'i32, D2: 0xcbac'i16, D3: 0x11cf, D4: [
|
||||||
0x95'i8, 0xca'i8, 0x00'i8, 0x80'i8, 0x5f'i8, 0x48'i8, 0xa1'i8, 0x92'i8])
|
0x95'i8, 0xca'i8, 0x00'i8, 0x80'i8, 0x5f'i8, 0x48'i8, 0xa1'i8, 0x92'i8])
|
||||||
|
|
||||||
proc WSAIoctl*(s: TSocketHandle, dwIoControlCode: dword, lpvInBuffer: pointer,
|
proc WSAIoctl*(s: TSocketHandle, dwIoControlCode: DWORD, lpvInBuffer: pointer,
|
||||||
cbInBuffer: dword, lpvOutBuffer: pointer, cbOutBuffer: dword,
|
cbInBuffer: DWORD, lpvOutBuffer: pointer, cbOutBuffer: DWORD,
|
||||||
lpcbBytesReturned: PDword, lpOverlapped: POVERLAPPED,
|
lpcbBytesReturned: PDword, lpOverlapped: POVERLAPPED,
|
||||||
lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint
|
lpCompletionRoutine: POVERLAPPED_COMPLETION_ROUTINE): cint
|
||||||
{.stdcall, importc: "WSAIoctl", dynlib: "Ws2_32.dll".}
|
{.stdcall, importc: "WSAIoctl", dynlib: "Ws2_32.dll".}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue