Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

system refactorings #10559

Merged
merged 5 commits into from Feb 6, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
324 changes: 40 additions & 284 deletions lib/system.nim

Large diffs are not rendered by default.

21 changes: 13 additions & 8 deletions lib/system/ansi_c.nim
Expand Up @@ -111,22 +111,27 @@ type c_sighandler_t = proc (a: cint) {.noconv.}
proc c_signal(sign: cint, handler: proc (a: cint) {.noconv.}): c_sighandler_t {.
importc: "signal", header: "<signal.h>", discardable.}

proc c_fprintf(f: File, frmt: cstring): cint {.
type
CFile {.importc: "FILE", header: "<stdio.h>",
incompletestruct.} = object
CFileStar* = ptr CFile ## The type representing a file handle.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not s/CFileStar/CFilePtr ? seems more readable and it follows the existing nim convention

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, will change it.


var
cstderr* {.importc: "stderr", header: "<stdio.h>".}: CFileStar
cstdout* {.importc: "stdout", header: "<stdio.h>".}: CFileStar

proc c_fprintf(f: CFileStar, frmt: cstring): cint {.
importc: "fprintf", header: "<stdio.h>", varargs, discardable.}
proc c_printf(frmt: cstring): cint {.
importc: "printf", header: "<stdio.h>", varargs, discardable.}

proc c_fputs(c: cstring, f: CFileStar): cint {.
importc: "fputs", header: "<stdio.h>", discardable.}

proc c_sprintf(buf, frmt: cstring): cint {.
importc: "sprintf", header: "<stdio.h>", varargs, noSideEffect.}
# we use it only in a way that cannot lead to security issues

when defined(windows):
proc c_fileno(f: File): cint {.
importc: "_fileno", header: "<stdio.h>".}
else:
proc c_fileno(f: File): cint {.
importc: "fileno", header: "<fcntl.h>".}

proc c_malloc(size: csize): pointer {.
importc: "malloc", header: "<stdlib.h>".}
proc c_free(p: pointer) {.
Expand Down
32 changes: 16 additions & 16 deletions lib/system/dyncalls.nim
Expand Up @@ -19,11 +19,11 @@ const

proc nimLoadLibraryError(path: string) =
# carefully written to avoid memory allocation:
stderr.rawWrite("could not load: ")
stderr.rawWrite(path)
stderr.rawWrite("\n")
cstderr.rawWrite("could not load: ")
cstderr.rawWrite(path)
cstderr.rawWrite("\n")
when not defined(nimDebugDlOpen) and not defined(windows):
stderr.rawWrite("compile with -d:nimDebugDlOpen for more information\n")
cstderr.rawWrite("compile with -d:nimDebugDlOpen for more information\n")
when defined(windows) and defined(guiapp):
# Because console output is not shown in GUI apps, display error as message box:
const prefix = "could not load: "
Expand All @@ -35,9 +35,9 @@ proc nimLoadLibraryError(path: string) =

proc procAddrError(name: cstring) {.noinline.} =
# carefully written to avoid memory allocation:
stderr.rawWrite("could not import: ")
stderr.rawWrite(name)
stderr.rawWrite("\n")
cstderr.rawWrite("could not import: ")
cstderr.rawWrite(name)
cstderr.rawWrite("\n")
quit(1)

# this code was inspired from Lua's source code:
Expand Down Expand Up @@ -79,8 +79,8 @@ when defined(posix):
when defined(nimDebugDlOpen):
let error = dlerror()
if error != nil:
stderr.rawWrite(error)
stderr.rawWrite("\n")
cstderr.rawWrite(error)
cstderr.rawWrite("\n")

proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
result = dlsym(lib, name)
Expand Down Expand Up @@ -162,20 +162,20 @@ elif defined(genode):

elif defined(nintendoswitch):
proc nimUnloadLibrary(lib: LibHandle) =
stderr.rawWrite("nimUnLoadLibrary not implemented")
stderr.rawWrite("\n")
cstderr.rawWrite("nimUnLoadLibrary not implemented")
cstderr.rawWrite("\n")
quit(1)

proc nimLoadLibrary(path: string): LibHandle =
stderr.rawWrite("nimLoadLibrary not implemented")
stderr.rawWrite("\n")
cstderr.rawWrite("nimLoadLibrary not implemented")
cstderr.rawWrite("\n")
quit(1)


proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
stderr.rawWrite("nimGetProAddr not implemented")
stderr.rawWrite(name)
stderr.rawWrite("\n")
cstderr.rawWrite("nimGetProAddr not implemented")
cstderr.rawWrite(name)
cstderr.rawWrite("\n")
quit(1)

else:
Expand Down
153 changes: 88 additions & 65 deletions lib/system/endb.nim
Expand Up @@ -76,29 +76,52 @@ proc `==`(a, b: StaticStr): bool =
proc `==`(a: StaticStr, b: cstring): bool =
result = c_strcmp(unsafeAddr a.data, b) == 0

proc write(f: File, s: StaticStr) =
proc write(f: CFileStar, s: cstring) = c_fputs(s, f)
proc writeLine(f: CFileStar, s: cstring) =
c_fputs(s, f)
c_fputs("\n", f)

proc write(f: CFileStar, s: StaticStr) =
write(f, cstring(unsafeAddr s.data))

proc write(f: CFileStar, i: int) =
when sizeof(int) == 8:
discard c_fprintf(f, "%lld", i)
else:
discard c_fprintf(f, "%ld", i)

proc close(f: CFileStar): cint {.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • why not follow existing convention, ie c_fclose (which was previous name in sysio.nim)
  • like you said yourself, discardable is evil; it also makes errors silently accepted

for reference here was the previous definition:

proc c_fclose(f: File): cint {.
  importc: "fclose", header: "<stdio.h>".}
  • same with other procs that gained a discardable in this PR, eg c_fputs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's ENDB, I hacked it together.

importc: "fclose", header: "<stdio.h>", discardable.}

proc c_fgetc(stream: CFileStar): cint {.
importc: "fgetc", header: "<stdio.h>".}
proc c_ungetc(c: cint, f: CFileStar): cint {.
importc: "ungetc", header: "<stdio.h>", discardable.}

var
cstdin* {.importc: "stdin", header: "<stdio.h>".}: CFileStar

proc listBreakPoints() =
write(stdout, EndbBeg)
write(stdout, "| Breakpoints:\n")
write(cstdout, EndbBeg)
write(cstdout, "| Breakpoints:\n")
for b in listBreakpoints():
write(stdout, abs(b.low))
write(cstdout, abs(b.low))
if b.high != b.low:
write(stdout, "..")
write(stdout, abs(b.high))
write(stdout, " ")
write(stdout, b.filename)
write(cstdout, "..")
write(cstdout, abs(b.high))
write(cstdout, " ")
write(cstdout, b.filename)
if b.isActive:
write(stdout, " [disabled]\n")
write(cstdout, " [disabled]\n")
else:
write(stdout, "\n")
write(stdout, EndbEnd)
write(cstdout, "\n")
write(cstdout, EndbEnd)

proc openAppend(filename: cstring): CFileStar =
proc fopen(filename, mode: cstring): CFileStar {.importc: "fopen", header: "<stdio.h>".}

proc openAppend(filename: cstring): File =
var p: pointer = fopen(filename, "ab")
if p != nil:
result = cast[File](p)
result = fopen(filename, "ab")
if result != nil:
write(result, "----------------------------------------\n")

proc dbgRepr(p: pointer, typ: PNimType): string =
Expand All @@ -112,12 +135,12 @@ proc dbgRepr(p: pointer, typ: PNimType): string =
# dec(recGcLock)
deinitReprClosure(cl)

proc writeVariable(stream: File, slot: VarSlot) =
proc writeVariable(stream: CFileStar, slot: VarSlot) =
write(stream, slot.name)
write(stream, " = ")
writeLine(stream, dbgRepr(slot.address, slot.typ))

proc listFrame(stream: File, f: PFrame) =
proc listFrame(stream: CFileStar, f: PFrame) =
write(stream, EndbBeg)
write(stream, "| Frame (")
write(stream, f.len)
Expand All @@ -126,7 +149,7 @@ proc listFrame(stream: File, f: PFrame) =
writeLine(stream, getLocal(f, i).name)
write(stream, EndbEnd)

proc listLocals(stream: File, f: PFrame) =
proc listLocals(stream: CFileStar, f: PFrame) =
write(stream, EndbBeg)
write(stream, "| Frame (")
write(stream, f.len)
Expand All @@ -135,7 +158,7 @@ proc listLocals(stream: File, f: PFrame) =
writeVariable(stream, getLocal(f, i))
write(stream, EndbEnd)

proc listGlobals(stream: File) =
proc listGlobals(stream: CFileStar) =
write(stream, EndbBeg)
write(stream, "| Globals:\n")
for i in 0 .. getGlobalLen()-1:
Expand All @@ -145,10 +168,10 @@ proc listGlobals(stream: File) =
proc debugOut(msg: cstring) =
# the *** *** markers are for easy recognition of debugger
# output for external frontends.
write(stdout, EndbBeg)
write(stdout, "| ")
write(stdout, msg)
write(stdout, EndbEnd)
write(cstdout, EndbBeg)
write(cstdout, "| ")
write(cstdout, msg)
write(cstdout, EndbEnd)

proc dbgFatal(msg: cstring) =
debugOut(msg)
Expand All @@ -157,20 +180,20 @@ proc dbgFatal(msg: cstring) =

proc dbgShowCurrentProc(dbgFramePointer: PFrame) =
if dbgFramePointer != nil:
write(stdout, "*** endb| now in proc: ")
write(stdout, dbgFramePointer.procname)
write(stdout, " ***\n")
write(cstdout, "*** endb| now in proc: ")
write(cstdout, dbgFramePointer.procname)
write(cstdout, " ***\n")
else:
write(stdout, "*** endb| (proc name not available) ***\n")
write(cstdout, "*** endb| (proc name not available) ***\n")

proc dbgShowExecutionPoint() =
write(stdout, "*** endb| ")
write(stdout, framePtr.filename)
write(stdout, "(")
write(stdout, framePtr.line)
write(stdout, ") ")
write(stdout, framePtr.procname)
write(stdout, " ***\n")
write(cstdout, "*** endb| ")
write(cstdout, framePtr.filename)
write(cstdout, "(")
write(cstdout, framePtr.line)
write(cstdout, ") ")
write(cstdout, framePtr.procname)
write(cstdout, " ***\n")

proc scanAndAppendWord(src: cstring, a: var StaticStr, start: int): int =
result = start
Expand Down Expand Up @@ -279,7 +302,7 @@ proc breakpointToggle(s: cstring, start: int) =
if not b.isNil: b.flip
else: debugOut("[Warning] unknown breakpoint ")

proc dbgEvaluate(stream: File, s: cstring, start: int, f: PFrame) =
proc dbgEvaluate(stream: CFileStar, s: cstring, start: int, f: PFrame) =
var dbgTemp: StaticStr
var i = scanWord(s, dbgTemp, start)
while s[i] in {' ', '\t'}: inc(i)
Expand Down Expand Up @@ -315,8 +338,8 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) =
var dbgTemp: StaticStr
var i = scanFilename(s, dbgTemp, start)
if dbgTemp.len == 0:
# just write it to stdout:
listFrame(stdout, currFrame)
# just write it to cstdout:
listFrame(cstdout, currFrame)
else:
var stream = openAppend(addr dbgTemp.data)
if stream == nil:
Expand All @@ -325,7 +348,7 @@ proc dbgStackFrame(s: cstring, start: int, currFrame: PFrame) =
listFrame(stream, currFrame)
close(stream)

proc readLine(f: File, line: var StaticStr): bool =
proc readLine(f: CFileStar, line: var StaticStr): bool =
while true:
var c = c_fgetc(f)
if c < 0'i32:
Expand All @@ -340,16 +363,16 @@ proc readLine(f: File, line: var StaticStr): bool =
result = true

proc listFilenames() =
write(stdout, EndbBeg)
write(stdout, "| Files:\n")
write(cstdout, EndbBeg)
write(cstdout, "| Files:\n")
var i = 0
while true:
let x = dbgFilenames[i]
if x.isNil: break
write(stdout, x)
write(stdout, "\n")
write(cstdout, x)
write(cstdout, "\n")
inc i
write(stdout, EndbEnd)
write(cstdout, EndbEnd)

proc dbgWriteStackTrace(f: PFrame)
proc commandPrompt() =
Expand All @@ -361,10 +384,10 @@ proc commandPrompt() =
dbgTemp: StaticStr

while again:
write(stdout, "*** endb| >>")
write(cstdout, "*** endb| >>")
let oldLen = dbgUser.len
dbgUser.len = 0
if not readLine(stdin, dbgUser): break
if not readLine(cstdin, dbgUser): break
if dbgUser.len == 0: dbgUser.len = oldLen
# now look what we have to do:
var i = scanWord(addr dbgUser.data, dbgTemp, 0)
Expand Down Expand Up @@ -398,7 +421,7 @@ proc commandPrompt() =
prevState = dbgState
prevSkipFrame = dbgSkipToFrame
dbgState = dbSkipCurrent
dbgEvaluate(stdout, addr dbgUser.data, i, dbgFramePtr)
dbgEvaluate(cstdout, addr dbgUser.data, i, dbgFramePtr)
dbgState = prevState
dbgSkipToFrame = prevSkipFrame
elif ?"o" or ?"out":
Expand All @@ -412,15 +435,15 @@ proc commandPrompt() =
prevState = dbgState
prevSkipFrame = dbgSkipToFrame
dbgState = dbSkipCurrent
listLocals(stdout, dbgFramePtr)
listLocals(cstdout, dbgFramePtr)
dbgState = prevState
dbgSkipToFrame = prevSkipFrame
elif ?"g" or ?"globals":
var
prevState = dbgState
prevSkipFrame = dbgSkipToFrame
dbgState = dbSkipCurrent
listGlobals(stdout)
listGlobals(cstdout)
dbgState = prevState
dbgSkipToFrame = prevSkipFrame
elif ?"u" or ?"up":
Expand Down Expand Up @@ -501,29 +524,29 @@ proc dbgWriteStackTrace(f: PFrame) =
b = b.prev
for j in countdown(i-1, 0):
if tempFrames[j] == nil:
write(stdout, "(")
write(stdout, skipped)
write(stdout, " calls omitted) ...")
write(cstdout, "(")
write(cstdout, skipped)
write(cstdout, " calls omitted) ...")
else:
write(stdout, tempFrames[j].filename)
write(cstdout, tempFrames[j].filename)
if tempFrames[j].line > 0:
write(stdout, '(')
write(stdout, tempFrames[j].line)
write(stdout, ')')
write(stdout, ' ')
write(stdout, tempFrames[j].procname)
write(stdout, "\n")
write(cstdout, "(")
write(cstdout, tempFrames[j].line)
write(cstdout, ")")
write(cstdout, " ")
write(cstdout, tempFrames[j].procname)
write(cstdout, "\n")

proc checkForBreakpoint =
let b = checkBreakpoints(framePtr.filename, framePtr.line)
if b != nil:
write(stdout, "*** endb| reached ")
write(stdout, framePtr.filename)
write(stdout, "(")
write(stdout, framePtr.line)
write(stdout, ") ")
write(stdout, framePtr.procname)
write(stdout, " ***\n")
write(cstdout, "*** endb| reached ")
write(cstdout, framePtr.filename)
write(cstdout, "(")
write(cstdout, framePtr.line)
write(cstdout, ") ")
write(cstdout, framePtr.procname)
write(cstdout, " ***\n")
commandPrompt()

proc lineHookImpl() {.nimcall.} =
Expand Down