If I have a program I?d like to compile with polyc that looks like
fun main () = let val _ = PolyML.SaveState.loadState (hd (CommandLine.arguments())) in ? end
what, if anything can I put in the ? and have it work?
All I really want is what is effectively a sequence of calls to ?use? in that slot, but there seem to be many ways of generating executables that silently crash.
Michael
How exactly are you saving the state you want to load? The problem is that you can only load a saved state into the same executable as you used to save it. The ultimate reason for this restriction is that the saved state does not save any heap cells that are present in the executable but instead saves their (relative) addresses. loadState will raise an exception if the saved state does not match the executable.
By "silently crash" do you mean that it raises an exception that you are not handling or is this something else?
David
On 30/08/2017 13:10, Michael.Norrish at data61.csiro.au wrote:
If I have a program I?d like to compile with polyc that looks like
fun main () = let val _ = PolyML.SaveState.loadState (hd (CommandLine.arguments())) in ? end
what, if anything can I put in the ? and have it work?
All I really want is what is effectively a sequence of calls to ?use? in that slot, but there seem to be many ways of generating executables that silently crash.
Michael
polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
The state is being saved from ?bare? poly, and being reloaded into the same environment (no complicated chains of states in my example). ?Silently crash? means exits without any output, even though the ? section of my code includes calls to print.
Here is a simple example:
First:
$ echo "val x = ref 10; PolyML.SaveState.saveState "foo";" | poly
generating my state file ?foo?.
Then I write bar.ML:
```` fun die s = (TextIO.output(TextIO.stdErr, s ^ "\n"); OS.Process.exit OS.Process.failure)
fun write_to_file f = let val ostrm = TextIO.openOut f in TextIO.output(ostrm, "(* this is a file *)\n"); TextIO.closeOut ostrm end
fun main() = let val (s,file) = case CommandLine.arguments() of [s,file] => (s,file) | _ => die ("Usage:\n "^CommandLine.name() ^ " state file") in PolyML.SaveState.loadState s; print "Switched state successfully\n"; write_to_file file; PolyML.use file end ````
Then I compile with polyc:
$ polyc bar.ML
Then I try running a.out
$ ./a.out foo usefile
I get no output, an exit code of 1 and usefile hasn?t been created.
This is on macos (uname says ?Darwin Kernel Version 16.7.0?), and with Poly/ML 5.6 Release.
Michael
On 30/8/17, 22:33, "David Matthews" <David.Matthews at prolingua.co.uk> wrote:
How exactly are you saving the state you want to load? The problem is that you can only load a saved state into the same executable as you used to save it. The ultimate reason for this restriction is that the saved state does not save any heap cells that are present in the executable but instead saves their (relative) addresses. loadState will raise an exception if the saved state does not match the executable.
By "silently crash" do you mean that it raises an exception that you are not handling or is this something else?
David
On 30/08/2017 13:10, Michael.Norrish at data61.csiro.au wrote: > If I have a program I?d like to compile with polyc that looks like > > > fun main () = > let > val _ = PolyML.SaveState.loadState (hd (CommandLine.arguments())) > in > ? > end > > what, if anything can I put in the ? and have it work? > > All I really want is what is effectively a sequence of calls to ?use? in that slot, but there seem to be many ways of generating executables that silently crash. > > Michael > > _______________________________________________ > polyml mailing list > polyml at inf.ed.ac.uk > http://lists.inf.ed.ac.uk/mailman/listinfo/polyml >
You are loading the state into the new executable a.out which is not the same as the executable poly used to save the state. If you save the state from a.out, you should be ok, e.g
bar.ML ```` fun die s = (TextIO.output(TextIO.stdErr, s ^ "\n"); OS.Process.exit OS.Process.failure)
datatype cmd = Save | Load
fun main() = let val (cmd, s,file) = case CommandLine.arguments() of ["save",s,file] => (Save,s,file) | ["load",s,file] => (Load,s,file) | _ => die ("Usage:\n "^CommandLine.name() ^ " [save|load] state file") in case cmd of Save => ( PolyML.use file; PolyML.SaveState.saveState s; print "Saved state successfully\n" ) | Load => ( PolyML.SaveState.loadState s; print "Loaded state successfully\n"; PolyML.use file ) end ````
$ polyc bar.ML $ echo "val x = ref 10;" > file1.sml $ echo 'print ("!x = " ^ Int.toString (!x) ^ "\n");' > file2.sml $ ./a.out save foo file1.sml $ ./a.out load foo file2.sml
Phil On 31/08/17 00:32, Michael.Norrish at data61.csiro.au wrote:
The state is being saved from ?bare? poly, and being reloaded into the same environment (no complicated chains of states in my example). ?Silently crash? means exits without any output, even though the ? section of my code includes calls to print.
Here is a simple example:
First:
$ echo "val x = ref 10; PolyML.SaveState.saveState \"foo\";" | poly
generating my state file ?foo?.
Then I write bar.ML:
fun die s = (TextIO.output(TextIO.stdErr, s ^ "\n"); OS.Process.exit OS.Process.failure) fun write_to_file f = let val ostrm = TextIO.openOut f in TextIO.output(ostrm, "(* this is a file *)\n"); TextIO.closeOut ostrm end fun main() = let val (s,file) = case CommandLine.arguments() of [s,file] => (s,file) | _ => die ("Usage:\n "^CommandLine.name() ^ " state file") in PolyML.SaveState.loadState s; print "Switched state successfully\n"; write_to_file file; PolyML.use file end
Then I compile with polyc:
$ polyc bar.ML
Then I try running a.out
$ ./a.out foo usefile
I get no output, an exit code of 1 and usefile hasn?t been created.
This is on macos (uname says ?Darwin Kernel Version 16.7.0?), and with Poly/ML 5.6 Release.
Michael
On 30/8/17, 22:33, "David Matthews" <David.Matthews at prolingua.co.uk> wrote:
How exactly are you saving the state you want to load? The problem is that you can only load a saved state into the same executable as you used to save it. The ultimate reason for this restriction is that the saved state does not save any heap cells that are present in the executable but instead saves their (relative) addresses. loadState will raise an exception if the saved state does not match the executable. By "silently crash" do you mean that it raises an exception that you are not handling or is this something else? David On 30/08/2017 13:10, Michael.Norrish at data61.csiro.au wrote: > If I have a program I?d like to compile with polyc that looks like > > > fun main () = > let > val _ = PolyML.SaveState.loadState (hd (CommandLine.arguments())) > in > ? > end > > what, if anything can I put in the ? and have it work? > > All I really want is what is effectively a sequence of calls to ?use? in that slot, but there seem to be many ways of generating executables that silently crash. > > Michael > > _______________________________________________ > polyml mailing list > polyml at inf.ed.ac.uk > http://lists.inf.ed.ac.uk/mailman/listinfo/polyml >
polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
Right. That makes sense. Unfortunate and inconvenient sense in my case, but sense nonetheless.
Thanks, Michael
On 31/8/17, 10:39, "polyml-bounces at inf.ed.ac.uk on behalf of Phil Clayton" <polyml-bounces at inf.ed.ac.uk on behalf of phil.clayton at veonix.com> wrote:
You are loading the state into the new executable a.out which is not the same as the executable poly used to save the state. If you save the state from a.out, you should be ok, e.g
bar.ML ```` fun die s = (TextIO.output(TextIO.stdErr, s ^ "\n"); OS.Process.exit OS.Process.failure)
datatype cmd = Save | Load
fun main() = let val (cmd, s,file) = case CommandLine.arguments() of ["save",s,file] => (Save,s,file) | ["load",s,file] => (Load,s,file) | _ => die ("Usage:\n "^CommandLine.name() ^ " [save|load] state file") in case cmd of Save => ( PolyML.use file; PolyML.SaveState.saveState s; print "Saved state successfully\n" ) | Load => ( PolyML.SaveState.loadState s; print "Loaded state successfully\n"; PolyML.use file ) end ````
$ polyc bar.ML $ echo "val x = ref 10;" > file1.sml $ echo 'print ("!x = " ^ Int.toString (!x) ^ "\n");' > file2.sml $ ./a.out save foo file1.sml $ ./a.out load foo file2.sml
Phil On 31/08/17 00:32, Michael.Norrish at data61.csiro.au wrote: > The state is being saved from ?bare? poly, and being reloaded into the same environment (no complicated chains of states in my example). ?Silently crash? means exits without any output, even though the ? section of my code includes calls to print. > > Here is a simple example: > > First: > > $ echo "val x = ref 10; PolyML.SaveState.saveState "foo";" | poly > > generating my state file ?foo?. > > Then I write bar.ML: > > ```` > fun die s = (TextIO.output(TextIO.stdErr, s ^ "\n"); > OS.Process.exit OS.Process.failure) > > fun write_to_file f = > let > val ostrm = TextIO.openOut f > in > TextIO.output(ostrm, "(* this is a file *)\n"); > TextIO.closeOut ostrm > end > > fun main() = > let > val (s,file) = case CommandLine.arguments() of > [s,file] => (s,file) > | _ => die ("Usage:\n "^CommandLine.name() ^ > " state file") > in > PolyML.SaveState.loadState s; > print "Switched state successfully\n"; > write_to_file file; > PolyML.use file > end > ```` > > Then I compile with polyc: > > $ polyc bar.ML > > Then I try running a.out > > $ ./a.out foo usefile > > I get no output, an exit code of 1 and usefile hasn?t been created. > > This is on macos (uname says ?Darwin Kernel Version 16.7.0?), and with Poly/ML 5.6 Release. > > Michael > > > On 30/8/17, 22:33, "David Matthews" <David.Matthews at prolingua.co.uk> wrote: > > How exactly are you saving the state you want to load? The problem is > that you can only load a saved state into the same executable as you > used to save it. The ultimate reason for this restriction is that the > saved state does not save any heap cells that are present in the > executable but instead saves their (relative) addresses. loadState will > raise an exception if the saved state does not match the executable. > > By "silently crash" do you mean that it raises an exception that you are > not handling or is this something else? > > David > > On 30/08/2017 13:10, Michael.Norrish at data61.csiro.au wrote: > > If I have a program I?d like to compile with polyc that looks like > > > > > > fun main () = > > let > > val _ = PolyML.SaveState.loadState (hd (CommandLine.arguments())) > > in > > ? > > end > > > > what, if anything can I put in the ? and have it work? > > > > All I really want is what is effectively a sequence of calls to ?use? in that slot, but there seem to be many ways of generating executables that silently crash. > > > > Michael > > > > _______________________________________________ > > polyml mailing list > > polyml at inf.ed.ac.uk > > http://lists.inf.ed.ac.uk/mailman/listinfo/polyml > > > > > _______________________________________________ > polyml mailing list > polyml at inf.ed.ac.uk > http://lists.inf.ed.ac.uk/mailman/listinfo/polyml > _______________________________________________ polyml mailing list polyml at inf.ed.ac.uk http://lists.inf.ed.ac.uk/mailman/listinfo/polyml
A program compiled with polyc exits if there is an uncaught exception. In this case PolyML.SaveState.loadState is raising an exception. Adding a handler such as PolyML.SaveState.loadState s handle exn => (print(exnMessage exn); raise exn); produces a message similar to: Fail "Saved state was exported from a different executable or the executable has changed"
It would be nice to be able to import a saved state into a different executable but it would only be possible if the saved state had no pointers to data in the exporting executable.
David
On 31/08/2017 00:32, Michael.Norrish at data61.csiro.au wrote:
The state is being saved from ?bare? poly, and being reloaded into the same environment (no complicated chains of states in my example). ?Silently crash? means exits without any output, even though the ? section of my code includes calls to print.
Here is a simple example:
First:
$ echo "val x = ref 10; PolyML.SaveState.saveState \"foo\";" | poly
generating my state file ?foo?.
Then I write bar.ML:
fun die s = (TextIO.output(TextIO.stdErr, s ^ "\n"); OS.Process.exit OS.Process.failure) fun write_to_file f = let val ostrm = TextIO.openOut f in TextIO.output(ostrm, "(* this is a file *)\n"); TextIO.closeOut ostrm end fun main() = let val (s,file) = case CommandLine.arguments() of [s,file] => (s,file) | _ => die ("Usage:\n "^CommandLine.name() ^ " state file") in PolyML.SaveState.loadState s; print "Switched state successfully\n"; write_to_file file; PolyML.use file end
Then I compile with polyc:
$ polyc bar.ML
Then I try running a.out
$ ./a.out foo usefile
I get no output, an exit code of 1 and usefile hasn?t been created.
This is on macos (uname says ?Darwin Kernel Version 16.7.0?), and with Poly/ML 5.6 Release.
Michael