compiler API: final cleanups; improve security by diabling 'gorge' and friends
This commit is contained in:
parent
a5701d6b71
commit
688c54d8f1
9 changed files with 55 additions and 28 deletions
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
# implements the command dispatcher and several commands
|
# implements the command dispatcher and several commands
|
||||||
|
|
||||||
|
when not defined(nimcore):
|
||||||
|
{.error: "nimcore MUST be defined for Nim's core tooling".}
|
||||||
|
|
||||||
import
|
import
|
||||||
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
|
llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
|
||||||
os, condsyms, rodread, rodwrite, times,
|
os, condsyms, rodread, rodwrite, times,
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ path:"llvm"
|
||||||
path:"$projectPath/.."
|
path:"$projectPath/.."
|
||||||
|
|
||||||
define:booting
|
define:booting
|
||||||
|
define:nimcore
|
||||||
#import:"$projectpath/testability"
|
#import:"$projectpath/testability"
|
||||||
|
|
||||||
@if windows:
|
@if windows:
|
||||||
|
|
@ -13,6 +14,5 @@ define:booting
|
||||||
|
|
||||||
define:useStdoutAsStdmsg
|
define:useStdoutAsStdmsg
|
||||||
|
|
||||||
cs:partial
|
|
||||||
#define:useNodeIds
|
#define:useNodeIds
|
||||||
#gc:markAndSweep
|
#gc:markAndSweep
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ iterator exportedSymbols*(i: Interpreter): PSym =
|
||||||
s = nextIter(it, i.mainModule.tab)
|
s = nextIter(it, i.mainModule.tab)
|
||||||
|
|
||||||
proc selectUniqueSymbol*(i: Interpreter; name: string;
|
proc selectUniqueSymbol*(i: Interpreter; name: string;
|
||||||
symKinds: set[TSymKind]): PSym =
|
symKinds: set[TSymKind] = {skLet, skVar}): PSym =
|
||||||
## Can be used to access a unique symbol of ``name`` and
|
## Can be used to access a unique symbol of ``name`` and
|
||||||
## the given ``symKinds`` filter.
|
## the given ``symKinds`` filter.
|
||||||
assert i != nil
|
assert i != nil
|
||||||
|
|
@ -55,8 +55,11 @@ proc callRoutine*(i: Interpreter; routine: PSym; args: openArray[PNode]): PNode
|
||||||
assert i != nil
|
assert i != nil
|
||||||
result = vm.execProc(PCtx i.graph.vm, routine, args)
|
result = vm.execProc(PCtx i.graph.vm, routine, args)
|
||||||
|
|
||||||
proc declareRoutine*(i: Interpreter; pkg, module, name: string;
|
proc getGlobalValue*(i: Interpreter; letOrVar: PSym): PNode =
|
||||||
impl: proc (a: VmArgs) {.closure, gcsafe.}) =
|
result = vm.getGlobalValue(PCtx i.graph.vm, letOrVar)
|
||||||
|
|
||||||
|
proc implementRoutine*(i: Interpreter; pkg, module, name: string;
|
||||||
|
impl: proc (a: VmArgs) {.closure, gcsafe.}) =
|
||||||
assert i != nil
|
assert i != nil
|
||||||
let vm = PCtx(i.graph.vm)
|
let vm = PCtx(i.graph.vm)
|
||||||
vm.registerCallback(pkg & "." & module & "." & name, impl)
|
vm.registerCallback(pkg & "." & module & "." & name, impl)
|
||||||
|
|
|
||||||
|
|
@ -972,7 +972,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
when hasFFI:
|
when hasFFI:
|
||||||
let prcValue = c.globals.sons[prc.position-1]
|
let prcValue = c.globals.sons[prc.position-1]
|
||||||
if prcValue.kind == nkEmpty:
|
if prcValue.kind == nkEmpty:
|
||||||
globalError(c.config, c.debug[pc], "canot run " & prc.name.s)
|
globalError(c.config, c.debug[pc], "cannot run " & prc.name.s)
|
||||||
let newValue = callForeignFunction(prcValue, prc.typ, tos.slots,
|
let newValue = callForeignFunction(prcValue, prc.typ, tos.slots,
|
||||||
rb+1, rc-1, c.debug[pc])
|
rb+1, rc-1, c.debug[pc])
|
||||||
if newValue.kind != nkEmpty:
|
if newValue.kind != nkEmpty:
|
||||||
|
|
@ -1336,14 +1336,17 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
|
||||||
regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc],
|
regs[ra].node.strVal = opSlurp(regs[rb].node.strVal, c.debug[pc],
|
||||||
c.module, c.config)
|
c.module, c.config)
|
||||||
of opcGorge:
|
of opcGorge:
|
||||||
decodeBC(rkNode)
|
when defined(nimcore):
|
||||||
inc pc
|
decodeBC(rkNode)
|
||||||
let rd = c.code[pc].regA
|
inc pc
|
||||||
|
let rd = c.code[pc].regA
|
||||||
|
|
||||||
createStr regs[ra]
|
createStr regs[ra]
|
||||||
regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
|
regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
|
||||||
regs[rc].node.strVal, regs[rd].node.strVal,
|
regs[rc].node.strVal, regs[rd].node.strVal,
|
||||||
c.debug[pc], c.config)[0]
|
c.debug[pc], c.config)[0]
|
||||||
|
else:
|
||||||
|
globalError(c.config, c.debug[pc], "VM is not built with 'gorge' support")
|
||||||
of opcNError:
|
of opcNError:
|
||||||
decodeB(rkNode)
|
decodeB(rkNode)
|
||||||
let a = regs[ra].node
|
let a = regs[ra].node
|
||||||
|
|
|
||||||
|
|
@ -107,15 +107,16 @@ proc registerAdditionalOps*(c: PCtx) =
|
||||||
wrap1f_math(ceil)
|
wrap1f_math(ceil)
|
||||||
wrap2f_math(fmod)
|
wrap2f_math(fmod)
|
||||||
|
|
||||||
wrap2s(getEnv, ospathsop)
|
when defined(nimcore):
|
||||||
wrap1s(existsEnv, ospathsop)
|
wrap2s(getEnv, ospathsop)
|
||||||
wrap2svoid(putEnv, ospathsop)
|
wrap1s(existsEnv, ospathsop)
|
||||||
wrap1s(dirExists, osop)
|
wrap2svoid(putEnv, ospathsop)
|
||||||
wrap1s(fileExists, osop)
|
wrap1s(dirExists, osop)
|
||||||
wrap2svoid(writeFile, systemop)
|
wrap1s(fileExists, osop)
|
||||||
wrap1s(readFile, systemop)
|
wrap2svoid(writeFile, systemop)
|
||||||
systemop getCurrentExceptionMsg
|
wrap1s(readFile, systemop)
|
||||||
registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
|
systemop getCurrentExceptionMsg
|
||||||
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
|
registerCallback c, "stdlib.*.staticWalkDir", proc (a: VmArgs) {.nimcall.} =
|
||||||
systemop gorgeEx
|
setResult(a, staticWalkDirImpl(getString(a, 0), getBool(a, 1)))
|
||||||
|
systemop gorgeEx
|
||||||
macrosop getProjectPath
|
macrosop getProjectPath
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
## Nimsuggest is a tool that helps to give editors IDE like capabilities.
|
## Nimsuggest is a tool that helps to give editors IDE like capabilities.
|
||||||
|
|
||||||
|
when not defined(nimcore):
|
||||||
|
{.error: "nimcore MUST be defined for Nim's core tooling".}
|
||||||
|
|
||||||
import strutils, os, parseopt, parseutils, sequtils, net, rdstdin, sexp
|
import strutils, os, parseopt, parseutils, sequtils, net, rdstdin, sexp
|
||||||
# Do NOT import suggest. It will lead to wierd bugs with
|
# Do NOT import suggest. It will lead to wierd bugs with
|
||||||
# suggestionResultHook, because suggest.nim is included by sigmatch.
|
# suggestionResultHook, because suggest.nim is included by sigmatch.
|
||||||
|
|
@ -486,9 +489,9 @@ var
|
||||||
|
|
||||||
proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
|
proc mainCommand(graph: ModuleGraph; cache: IdentCache) =
|
||||||
let conf = graph.config
|
let conf = graph.config
|
||||||
clearPasses()
|
clearPasses(graph)
|
||||||
registerPass verbosePass
|
registerPass graph, verbosePass
|
||||||
registerPass semPass
|
registerPass graph, semPass
|
||||||
conf.cmd = cmdIdeTools
|
conf.cmd = cmdIdeTools
|
||||||
incl conf.globalOptions, optCaasEnabled
|
incl conf.globalOptions, optCaasEnabled
|
||||||
wantMainModule(conf)
|
wantMainModule(conf)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ path:"$lib/packages/docutils"
|
||||||
|
|
||||||
define:useStdoutAsStdmsg
|
define:useStdoutAsStdmsg
|
||||||
define:nimsuggest
|
define:nimsuggest
|
||||||
|
define:nimcore
|
||||||
|
|
||||||
# die when nimsuggest uses more than 4GB:
|
# die when nimsuggest uses more than 4GB:
|
||||||
@if cpu32:
|
@if cpu32:
|
||||||
define:"nimMaxHeap=2000"
|
define:"nimMaxHeap=2000"
|
||||||
|
|
@ -15,7 +17,6 @@ define:nimsuggest
|
||||||
define:"nimMaxHeap=4000"
|
define:"nimMaxHeap=4000"
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#cs:partial
|
|
||||||
#define:useNodeIds
|
#define:useNodeIds
|
||||||
#define:booting
|
#define:booting
|
||||||
#define:noDocgen
|
#define:noDocgen
|
||||||
|
|
|
||||||
|
|
@ -5,3 +5,5 @@ echo "top level statements are executed!"
|
||||||
|
|
||||||
proc hostProgramRunsThis*(a, b: float): float =
|
proc hostProgramRunsThis*(a, b: float): float =
|
||||||
result = addFloats(a, b, 1.0)
|
result = addFloats(a, b, 1.0)
|
||||||
|
|
||||||
|
let hostProgramWantsThis* = "my secret"
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''top level statements are executed!
|
output: '''top level statements are executed!
|
||||||
2.0
|
2.0
|
||||||
|
my secret
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -16,7 +17,7 @@ proc main() =
|
||||||
quit "cannot find Nim's standard library"
|
quit "cannot find Nim's standard library"
|
||||||
|
|
||||||
var intr = createInterpreter("myscript.nim", [std, getAppDir()])
|
var intr = createInterpreter("myscript.nim", [std, getAppDir()])
|
||||||
intr.declareRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
|
intr.implementRoutine("*", "exposed", "addFloats", proc (a: VmArgs) =
|
||||||
setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2))
|
setResult(a, getFloat(a, 0) + getFloat(a, 1) + getFloat(a, 2))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -31,6 +32,16 @@ proc main() =
|
||||||
echo res.floatVal
|
echo res.floatVal
|
||||||
else:
|
else:
|
||||||
echo "bug!"
|
echo "bug!"
|
||||||
|
|
||||||
|
let foreignValue = selectUniqueSymbol(intr, "hostProgramWantsThis")
|
||||||
|
if foreignValue == nil:
|
||||||
|
quit "script does not export a global of the name: hostProgramWantsThis"
|
||||||
|
let val = intr.getGlobalValue(foreignValue)
|
||||||
|
if val.kind in {nkStrLit..nkTripleStrLit}:
|
||||||
|
echo val.strVal
|
||||||
|
else:
|
||||||
|
echo "bug!"
|
||||||
|
|
||||||
destroyInterpreter(intr)
|
destroyInterpreter(intr)
|
||||||
|
|
||||||
main()
|
main()
|
||||||
Loading…
Add table
Add a link
Reference in a new issue