@@ -14,7 +14,7 @@ public class Process {
1414
1515 private static long process_id = 0L ;
1616
17- private ArrayList <GeneratedLibrary > libraries = new ArrayList <GeneratedLibrary >();
17+ private ArrayList <HookedLibrary > libraries = new ArrayList <HookedLibrary >();
1818 private ArrayList <Output > output = new ArrayList <Output >(1 );
1919 private ArrayList <Variable > variables = new ArrayList <Variable >(5 );
2020 private ApplicationListener listener ;
@@ -33,7 +33,7 @@ public class Process {
3333
3434 public long maxRuntime = 0 ; //Runtime in ms. If < 0, runtime is infinite
3535 private long currentChar = 0 ;
36- public final String version = "1.9.1 " ;
36+ public final String version = "1.9.6 " ;
3737
3838 /**The file, the script is executed from. May be null. Just useful for some Native commands*/
3939 public File file = null ;
@@ -46,11 +46,14 @@ public class Process {
4646// public volatile int execution_time = 0;
4747// public volatile float average_commands_per_sec = 0;
4848
49- public class GeneratedLibrary {
49+ public class HookedLibrary {
50+
5051 public final Command [] commands ;
5152 public final String name ;
53+ public final Library lib ;
5254
53- public GeneratedLibrary (Library library ) {
55+ public HookedLibrary (Library library ) {
56+ this .lib = library ;
5457 this .commands = library .createLib ();
5558 this .name = library .getName ();
5659 }
@@ -94,9 +97,20 @@ boolean setValue(Object value, boolean ignoreCheck) {
9497 * If you don't want these native commands, call {@link Process#clearLibraries()} before adding your custom ones*/
9598 public Process (boolean useCache ) {
9699 includeLibrary (new NativeLibrary ());
100+
101+ Runtime .getRuntime ().addShutdownHook (new Thread (new Runnable () {
102+ @ Override
103+ public void run () {
104+ //Cant execute onexit function. Just execute the library listener
105+ if (isRunning ())
106+ kill (main , "JVM killed" );
107+ }
108+ }));
97109 }
98110
99111 public Thread execute (String script , boolean newThread ) {
112+ finalizing = false ;
113+
100114 if (main != null ) {
101115 if (main .alive ) {
102116 warning ("Java Environment was trying to start a new process, while its already running" );
@@ -259,16 +273,8 @@ private void start(Block block) {
259273// }
260274
261275 //Searches for a variable called onexit with the type BLOCK
262-
263-
264-
265- if (block .equals (main ) && listener != null ) {
266- Object exitFunction = getVariable ("onexit" , null );
267-
268- if (exitFunction != null )
269- executeBlock (((Block ) exitFunction ), true );
270-
271- listener .done (main .exitCode );
276+ if (main == block ) {
277+ finalizeExit (0 , "finished" );
272278 }
273279 block .alive = false ;
274280 aliveBlocks .remove (block );
@@ -349,7 +355,7 @@ else if(!block.cached.isEmpty()) {
349355 addToBlockCache = true ;
350356 }
351357
352- for (GeneratedLibrary lib : libraries ) {
358+ for (HookedLibrary lib : libraries ) {
353359 for (Command c : lib .commands ) {
354360 if (c .commandNameOffset >= args .size ()) continue ;
355361
@@ -648,9 +654,10 @@ public void setVariable(String name, Object value, boolean FINAL, boolean perman
648654 if (stack1 <= stack2 ) {
649655 if (!v .FINAL ) {// || v.permanent) {
650656 if (!v .setValue (value , getMain () == null )) kill (block , "Failed to assign type " + value + " to existing variable " + v .value );
651- } else if (getMain () != null ) {
652- kill (block ,"Tried to modyfy a constant: " + name );
653657 }
658+ //} else if(v.FINAL && getMain() != null) {
659+ // kill(block,"Tried to modyfy a constant: " + name);
660+ //}
654661 return ;
655662 }
656663 }
@@ -679,7 +686,12 @@ public Object getVariable(String name, Block block) {
679686 }
680687
681688 public void includeLibrary (Library lib ) {
682- libraries .add (new GeneratedLibrary (lib ));
689+ if (lib .bound != null ) {
690+ if (lib .bound != this ) {
691+ throw new IllegalAccessError ("This Library instance is already part of a different process. Try creating a new one: includeLibrary(new Library())" );
692+ }
693+ }
694+ libraries .add (new HookedLibrary (lib ));
683695 }
684696
685697 public void clearLibraries () {
@@ -719,12 +731,12 @@ public void warning(String message) {
719731 });
720732 }
721733
722- public ArrayList <GeneratedLibrary > getLibraries () {
734+ public ArrayList <HookedLibrary > getLibraries () {
723735 return libraries ;
724736 }
725737
726- public GeneratedLibrary getLibrary (String name ) {
727- for (GeneratedLibrary lib : libraries ) {
738+ public HookedLibrary getLibrary (String name ) {
739+ for (HookedLibrary lib : libraries ) {
728740 if (lib .name .equals (name )) return lib ;
729741 }
730742 return null ;
@@ -739,15 +751,19 @@ public synchronized void kill(Block block, String errorMessage) {
739751 block .currentCommand = block .currentCommand .subSequence (0 , 10 ) + " ... " + block .currentCommand .substring (block .currentCommand .length () - 10 , block .currentCommand .length ());
740752 }
741753 if (!errorMessage .isEmpty ()) error ("Error at [" + block .currentCommand + "]> " + errorMessage );
742-
743- for (Block b : aliveBlocks ) {
744- b .cached .clear ();
745- b .alive = false ;
746- b .interrupted = true ;
754+
755+ finalizeExit (1 , errorMessage );
756+
757+ for (int i = 0 ; i < aliveBlocks .size (); i ++) {
758+ aliveBlocks .get (i ).cached .clear ();
759+ aliveBlocks .get (i ).alive = false ;
760+ aliveBlocks .get (i ).interrupted = true ;
747761 }
748762 block .alive = false ;
749763 block .interrupted = true ;
750764 block .currentCommand = "" ;
765+
766+ //System.out.println("Cleaning stack ...");
751767 }
752768
753769 block .exitCode = Block .ERROR ;
@@ -817,6 +833,7 @@ public String waitForInput() throws IOException {
817833 return inputReader .readLine ();
818834 }
819835
836+ /**You can use {@link ApplicationInput}*/
820837 public void setInput (InputStream input ) {
821838 if (input == null ) return ;
822839
@@ -890,4 +907,30 @@ public static String findMatching(String string, int start, int skip, char openC
890907 }
891908 return null ;
892909 }
910+
911+ boolean finalizing = false ;
912+
913+ private void finalizeExit (int exitCode , String errorMessage ) {
914+ if (!finalizing ) return ;
915+
916+ finalizing = true ;
917+
918+ Object exitFunction = getVariable ("onexit" , null );
919+
920+ if (exitFunction != null )
921+ executeBlock (((Block ) exitFunction ), true , exitCode , errorMessage );
922+
923+ for (HookedLibrary lib : libraries ) {
924+ lib .lib .scriptExit (this , exitCode , errorMessage );
925+ }
926+ }
927+
928+ @ Override
929+ protected void finalize () throws Throwable {
930+ finalizeExit (1 , "JVM Killed" );
931+
932+ if (listener != null ) {
933+ listener .done (main .exitCode );
934+ }
935+ }
893936}
0 commit comments