# Copyright 2005-2007 Kevin Reid, under the terms of the MIT X license # found at http://www.opensource.org/licenses/mit-license.html ................ pragma.syntax("0.9") pragma.enable("exporter") pragma.enable("importer") def makeLazySlot :DeepFrozen := def makeScope :DeepFrozen := def makePathLoader :DeepFrozen := def Scope :DeepFrozen := makeScope.asType() def traceln1 :DeepFrozen := traceln # workaround for lack of guard attached to traceln # XXX document what keys in vatPrivScope and exits are used def makeIOScope implements DeepFrozen, ExitViaHere { to run(fqnPrefix :String, vatPrivScope :Scope, exits) :Scope { # --- Setting up --- def ioScope # Bindings to be added to the underlying scope. var ioAdd := ["privilegedScope" => ioScope] def addLazy(name, thun) :void { ioAdd with= ("&" + name, makeLazySlot(thun)) } # --- Adding entries --- # Things which are simply copied into the scope # (Note that names starting with & are special in ioAdd) for copyName ? exits.maps(copyName) in ["timer", "file__uriGetter", "stdin", "stdout", "stderr", "interp", "lisp", "getSocketPeerRef", "getSocketLocalRef", "makePipe", "entropy"] { ioAdd with= ("&" + copyName, exits.getSlot(copyName)) } def props := exits["props"] # XXX throw out defaultInterp once all uses of IOScopes supply their own if (!(ioAdd.maps("interp") || ioAdd.maps("&interp"))) { def gc := ioAdd with= ("interp", def defaultInterp { to waitAtTop(_) :void { throw("waitAtTop not defined in this context") } to exitAtTop(_) :void { throw("exitAtTop not defined in this context") } to blockAtTop() :void { throw("blockAtTop not defined in this context") } to continueAtTop() :void { throw("continueAtTop not defined in this context") } # we don't have getResult yet, but don't forget to clear its list then to gc() :void { gc() } to getProps() :any { # XXX this has no tests return props } }) } if (exits =~ [=> stdout] | _) { ioAdd with= ("print", {def print { match [=="run", args] { stdout.printAll(args) }}}) ioAdd with= ("println", {def println { match [=="run", args] { stdout.printAll(args) stdout.println() }}}) } def ioAdd with= ("unsafe__uriGetter", ) # XXX make this accept lack of std* etc. addLazy("rune", fn{ def [=> stdout, => stderr] | _ := exits #def runeAuthor := def runeAuthor := runeAuthor(["metaout" => stdout, "metaerr" => stderr, "defaultProps" => ioScope["interp"].getProps() ] | runeAuthor.defaultAuths()) }) # --- Unsafe imports and --- var unsafeImports := makeScope.fromState([ "org.cubik.cle.boot.privilegedScope" => ioScope, "java.lang.System" => {def system { /** stub for now */ to getProperties() :any { return def fakeProperties { } } }}, "org.erights.e.elang.interp.ScopeSetup" => { /** semi-stub for now */ def makeScopeSetup { to privileged(fqnPrefix :String, altout :TextWriter, alterr :TextWriter, props :Map[String, String], interpVow :vow, optVat) { # XXX this isn't actually tested, just referenced by JE-rune # XXX optVat guard # XXX we need more exits corresponding to ones that are implicit in the java version interface # XXX handle props, interpVow, optVat return ( fqnPrefix, vatPrivScope, makeScope.fromState([ "stdout" => altout, "stderr" => alterr, "interp" => interpVow, "makeVat" => exits["makeVat"], => props], "_")) } } }, "org.erights.e.elib.vat.Vat" => exits["makeVat"] ], "__unsafeImportScope$") if (exits =~ [=> &stdin, => &stdout, => &stderr] | _) { unsafeImports withSlot= ("org.erights.e.develop.exception.PrintStreamWriter", makeLazySlot(fn{ (stdin, stdout, stderr) })) } if (exits =~ [=> makeWeakRef] | _) { unsafeImports with= ("org.erights.e.elib.vat.makeWeakRef", makeWeakRef) unsafeImports with= ("org.erights.e.elib.vat.WeakPtr", makeWeakRef) } if (exits =~ [=> spawn] | _) { unsafeImports with= ("org.cubik.cle.spawn", spawn) } else if (exits =~ [=> unsafeNearSpawn] | _) { def makePseudoFarRef := unsafeImports with= ("org.cubik.cle.spawn", makePseudoFarRef(unsafeNearSpawn)) } if (exits =~ [=> ] | _) { unsafeImports with= ("org.erights.e.meta.java.io.FileGetter", /** Java-E compatibility - just provides file__uriGetter access. */ def makeFileGetterMetaCompat { to getTHE_ONE() :any { return } }) } bind := makePathLoader(, "unsafe", [ unsafeImports, def unsafeInheritLoader { to fetch(fqn :String, absentThunk) :any { def result := .fetch(fqn, absentThunk) traceln1(`warning: loading safe ${E.toQuote(fqn)} via unsafe loader`) return result } }, ]) return bind ioScope := (makeScope.fromState(ioAdd, fqnPrefix) | vatPrivScope).nestOuter() } }