Merge branch 'bigbreak' of https://github.com/Araq/Nimrod into bigbreak

This commit is contained in:
Araq 2014-10-21 22:41:32 +02:00
commit ca4d7b1ea8
11 changed files with 158 additions and 91 deletions

View file

@ -1126,6 +1126,7 @@ proc checkCanEval(c: PCtx; n: PNode) =
# we need to ensure that we don't evaluate 'x' here: # we need to ensure that we don't evaluate 'x' here:
# proc foo() = var x ... # proc foo() = var x ...
let s = n.sym let s = n.sym
if {sfCompileTime, sfGlobal} <= s.flags: return
if s.kind in {skVar, skTemp, skLet, skParam, skResult} and if s.kind in {skVar, skTemp, skLet, skParam, skResult} and
not s.isOwnedBy(c.prc.sym) and s.owner != c.module: not s.isOwnedBy(c.prc.sym) and s.owner != c.module:
cannotEval(n) cannotEval(n)

1
csources Submodule

@ -0,0 +1 @@
Subproject commit b0bcf88e26730b23d22e2663adf1babb05bd5a71

View file

@ -332,7 +332,7 @@ proc temp(args: string) =
proc showHelp() = proc showHelp() =
quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)), quit(HelpText % [NimVersion & repeatChar(44-len(NimVersion)),
CompileDate, CompileTime]) CompileDate, CompileTime], QuitSuccess)
var op = initOptParser() var op = initOptParser()
op.next() op.next()

View file

@ -2382,7 +2382,7 @@ proc hstrerror*(herrnum: cint): cstring {.importc, header: "<netdb.h>".}
proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "<sys/select.h>".} proc FD_CLR*(a1: cint, a2: var TFdSet) {.importc, header: "<sys/select.h>".}
proc FD_ISSET*(a1: cint | SocketHandle, a2: var TFdSet): cint {. proc FD_ISSET*(a1: cint | SocketHandle, a2: var TFdSet): cint {.
importc, header: "<sys/select.h>".} importc, header: "<sys/select.h>".}
proc fdSet*(a1: cint | SocketHandle, a2: var TFdSet) {. proc FD_SET*(a1: cint | SocketHandle, a2: var TFdSet) {.
importc: "FD_SET", header: "<sys/select.h>".} importc: "FD_SET", header: "<sys/select.h>".}
proc FD_ZERO*(a1: var TFdSet) {.importc, header: "<sys/select.h>".} proc FD_ZERO*(a1: var TFdSet) {.importc, header: "<sys/select.h>".}

View file

@ -91,11 +91,11 @@ import sockets, os
## getSocket(s).accept(client) ## getSocket(s).accept(client)
when defined(windows): when defined(windows):
from winlean import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet, from winlean import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet,
fdSet, FD_ISSET, select FD_ISSET, select
else: else:
from posix import TimeVal, SocketHandle, fdSet, FD_ZERO, TFdSet, from posix import TimeVal, SocketHandle, FD_SET, FD_ZERO, TFdSet,
fdSet, FD_ISSET, select FD_ISSET, select
type type
DelegateObj* = object DelegateObj* = object
@ -556,7 +556,7 @@ proc createFdSet(fd: var TFdSet, s: seq[Delegate], m: var int) =
FD_ZERO(fd) FD_ZERO(fd)
for i in items(s): for i in items(s):
m = max(m, int(i.fd)) m = max(m, int(i.fd))
fdSet(i.fd, fd) FD_SET(i.fd, fd)
proc pruneSocketSet(s: var seq[Delegate], fd: var TFdSet) = proc pruneSocketSet(s: var seq[Delegate], fd: var TFdSet) =
var i = 0 var i = 0

View file

@ -887,7 +887,7 @@ elif not defined(useNimRtl):
FD_ZERO(fd) FD_ZERO(fd)
for i in items(s): for i in items(s):
m = max(m, int(i.outHandle)) m = max(m, int(i.outHandle))
fdSet(cint(i.outHandle), fd) FD_SET(cint(i.outHandle), fd)
proc pruneProcessSet(s: var seq[Process], fd: var TFdSet) = proc pruneProcessSet(s: var seq[Process], fd: var TFdSet) =
var i = 0 var i = 0

View file

@ -372,7 +372,7 @@ proc createFdSet(fd: var TFdSet, s: seq[SocketHandle], m: var int) =
FD_ZERO(fd) FD_ZERO(fd)
for i in items(s): for i in items(s):
m = max(m, int(i)) m = max(m, int(i))
fdSet(i, fd) FD_SET(i, fd)
proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) = proc pruneSocketSet(s: var seq[SocketHandle], fd: var TFdSet) =
var i = 0 var i = 0

View file

@ -936,7 +936,7 @@ proc createFdSet(fd: var TFdSet, s: seq[Socket], m: var int) =
FD_ZERO(fd) FD_ZERO(fd)
for i in items(s): for i in items(s):
m = max(m, int(i.fd)) m = max(m, int(i.fd))
fdSet(i.fd, fd) FD_SET(i.fd, fd)
proc pruneSocketSet(s: var seq[Socket], fd: var TFdSet) = proc pruneSocketSet(s: var seq[Socket], fd: var TFdSet) =
var i = 0 var i = 0

View file

@ -536,7 +536,7 @@ proc WSAFDIsSet(s: SocketHandle, set: var TFdSet): bool {.
proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint = proc FD_ISSET*(socket: SocketHandle, set: var TFdSet): cint =
result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32 result = if WSAFDIsSet(socket, set): 1'i32 else: 0'i32
proc fdSet*(socket: SocketHandle, s: var TFdSet) = proc FD_SET*(socket: SocketHandle, s: var TFdSet) =
if s.fd_count < FD_SETSIZE: if s.fd_count < FD_SETSIZE:
s.fd_array[int(s.fd_count)] = socket s.fd_array[int(s.fd_count)] = socket
inc(s.fd_count) inc(s.fd_count)

18
tools/fakedeps.nim Normal file
View file

@ -0,0 +1,18 @@
import strutils, os, pegs, strtabs, math, threadpool, times
proc fakeCppDep(x: ptr float) {.importcpp: "fakeCppDep", header: "<vector>".}
proc fakeTimeDep() = echo(times.getDateStr())
proc fakedeps() =
var x = 0.4
{.emit: "#if 0\n".}
fakeCppDep(addr x)
{.emit: "#endif\n".}
# this is not true:
if math.sin(x) > 0.6:
spawn(fakeTimeDep())
proc main =
fakedeps()
when isMainModule:
main()

View file

@ -2,33 +2,16 @@
import strutils, os, pegs, strtabs, math, threadpool, times import strutils, os, pegs, strtabs, math, threadpool, times
proc fakeCppDep(x: ptr float) {.importcpp: "fakeCppDep", header: "<vector>".}
const const
Essential = """gcc.exe g++.exe gdb.exe ld.exe as.exe c++.exe cpp.exe cc1.exe Essential = """gcc.exe g++.exe gdb.exe ld.exe as.exe c++.exe cpp.exe cc1.exe
crtbegin.o crtend.o crt2.o dllcrt2.o crtbegin.o crtend.o crt2.o dllcrt2.o libgcc_s_dw2-1.dll libgcc_s_sjlj-1.dll
libexpat-1.dll libwinpthread-1.dll libgcc_s_seh-1.dll libexpat-1.dll libwinpthread-1.dll aio.h dlfcn.h fcntl.h
fenv.h fmtmsg.h fnmatch.h ftw.h errno.h glob.h gtmath.h if.h in.h ipc.h
aio.h langinfo.h locale.h math.h mman.h netdb.h nl_types.h poll.h pthread.h pwd.h
dlfcn.h sched.h select.h semaphore.h signal.h socket.h spawn.h stat.h statvfs.h stdio.h
fcntl.h fenv.h fmtmsg.h fnmatch.h ftw.h stdlib.h string.h strings.h tcp.h time.h types.h ucontext.h uio.h utsname.h
errno.h unistd.h wait.h varargs.h windows.h zlib.h
glob.h gtmath.h
if.h in.h ipc.h
langinfo.h locale.h
math.h mman.h
netdb.h nl_types.h
poll.h pthread.h pwd.h
sched.h select.h semaphore.h signal.h
socket.h spawn.h stat.h statvfs.h stdio.h stdlib.h string.h strings.h
tcp.h time.h types.h
ucontext.h uio.h utsname.h unistd.h
wait.h
varargs.h
windows.h
zlib.h
""".split """.split
BucketSize = 40
proc includes(headerpath, headerfile: string, whitelist: StringTableRef) = proc includes(headerpath, headerfile: string, whitelist: StringTableRef) =
whitelist[headerfile] = "processed" whitelist[headerfile] = "processed"
@ -61,8 +44,26 @@ proc gatherFiles(dir: string, whitelist: StringTableRef, result: var seq[string]
let name = extractFilename(path) let name = extractFilename(path)
if not whitelist.hasKey(name): if not whitelist.hasKey(name):
result.add(path) result.add(path)
of pcDir: gatherFiles(path, whitelist, result) of pcDir:
else: discard gatherFiles(path, whitelist, result)
else:
discard
proc gatherEmptyFolders(dir: string, whitelist: StringTableRef, result: var seq[string]) =
var empty = true
for kind, path in walkDir(dir):
case kind
of pcFile:
empty = false
of pcDir:
let (none, name) = splitPath(path)
if not whitelist.hasKey(name):
gatherEmptyFolders(path, whitelist, result)
empty = false
else:
discard
if empty:
result.add(dir)
proc newName(f: string): string = proc newName(f: string): string =
let (dir, name, ext) = splitFile(f) let (dir, name, ext) = splitFile(f)
@ -70,58 +71,104 @@ proc newName(f: string): string =
proc ccStillWorks(): bool = proc ccStillWorks(): bool =
const const
c1 = r"nim c --force_build koch" c1 = r"nim c --verbosity:0 --force_build koch"
c2 = r"nim c --force_build --threads:on --out:temp.exe tools/trimcc" c2 = r"nim c --verbosity:0 --force_build --threads:on --out:tempOne.exe trimcc"
result = execShellCmd(c1) == 0 and execShellCmd(c2) == 0 c3 = r"nim c --verbosity:0 --force_build --threads:on --out:tempTwo.exe fakeDeps"
c4 = r".\koch.exe"
c5 = r".\tempOne.exe"
c6 = r".\tempTwo.exe"
result = execShellCmd(c1) == 0 and execShellCmd(c2) == 0 and
execShellCmd(c3) == 0 and execShellCmd(c4) == 0 and
execShellCmd(c5) == 0 and execShellCmd(c6) == 0
proc trialDeletion(files: seq[string], a, b: int) = proc trialDeletion(files: seq[string], a, b: int, whitelist: StringTableRef): bool =
for i in a .. min(b, files.high): result = true
let path = files[i] var single = (a == min(b, files.high))
moveFile(dest=newName(path), source=path) for path in files[a .. min(b, files.high)]:
try:
moveFile(dest=newName(path), source=path)
except OSError:
return false
# Test if compilation still works, even with the moved files.
if ccStillWorks(): if ccStillWorks():
for i in a .. min(b, files.high): for path in files[a .. min(b, files.high)]:
let path = files[i] try:
echo "Optional: ", path removeFile(newName(path))
removeFile(newName(path)) echo "Optional: ", path
else: for i in a .. min(b, files.high): except OSError:
let path = files[i] echo "Warning, couldn't move ", path
moveFile(dest=path, source=newName(path))
return false
else:
for path in files[a .. min(b, files.high)]:
echo "Required: ", path echo "Required: ", path
# copy back:
moveFile(dest=path, source=newName(path)) moveFile(dest=path, source=newName(path))
if single:
whitelist[path] = "found"
result = false
proc main(dir: string) = proc main(dir: string) =
# Construct a whitelist of files to not remove
var whitelist = newStringTable(modeCaseInsensitive) var whitelist = newStringTable(modeCaseInsensitive)
for e in Essential: for e in Essential:
whitelist[e] = "found" whitelist[e] = "found"
while true: while true:
let oldLen = whitelist.len let oldLen = whitelist.len
processIncludes(dir, whitelist) processIncludes(dir, whitelist)
if oldLen == whitelist.len: break if oldLen == whitelist.len:
var allFiles: seq[string] = @[] break
gatherFiles(dir, whitelist, allFiles)
when true: # Remove batches of files
var nearlyDone = false
while true:
# Gather files to test
var allFiles = newSeq[string]()
gatherFiles(dir, whitelist, allFiles)
# Determine the initial size of groups to check
var
maxBucketSize = len(allFiles)
bucketSize = 1
# Loop through the list of files, deleting batches
var i = 0 var i = 0
while i < allFiles.len: while i < allFiles.len:
trialDeletion(allFiles, i, i+BucketSize-1) var success = trialDeletion(allFiles, i, i+bucketSize-1, whitelist)
inc i, BucketSize inc i, bucketSize
else:
for x in allFiles: echo x
proc fakeTimeDep() = echo(times.getDateStr()) # If we aren't on the last pass, adjust the batch size based on success
if not nearlyDone:
if success:
bucketSize = min(bucketSize * 2, maxBucketSize)
else:
bucketSize = max(bucketSize div 2, 1)
echo "Bucket size is now ", bucketSize
proc fakedeps() = # After looping through all the files, check if we need to break.
var x = 0.4 if nearlyDone:
{.emit: "#if 0\n".} break
fakeCppDep(addr x) if bucketSize == 1:
{.emit: "#endif\n".} nearlyDone = true
# this is not true: while true:
if math.sin(x) > 0.6: var
spawn(fakeTimeDep()) emptyFolders = newSeq[string]()
changed = false
gatherEmptyFolders(dir, whitelist, emptyFolders)
for path in emptyFolders:
removeDir(path)
if not ccStillWorks():
createDir(path)
whitelist[path] = "found"
else:
changed = true
if not changed:
break
if paramCount() == 1: if paramCount() == 1:
doAssert ccStillWorks() doAssert ccStillWorks()
fakedeps()
main(paramStr(1)) main(paramStr(1))
else: else:
quit "Usage: trimcc c_compiler_directory" quit "Usage: trimcc c_compiler_directory", QuitSuccess