1 /*!
  2  * 
  3  * Copyright (c) 2009 - 2011, javalikescript@free.fr (SPYL). All rights reserved.
  4  * JLS is licensed under LGPL, see the license.txt file that accompanied this code.
  5  * 
  6  */
  7 /**
  8  * jls Base framework.
  9  * All the framework objects are created under the jls namespace.
 10  * The default objects are extended using prototype like behaviors.
 11  * 
 12  * @namespace
 13  * @see jls.lang
 14  */
 15 var jls = {};
 16 
 17 /**
 18  * @namespace Provides base classes for the jls language.
 19  * @see jls.lang.Exception
 20  * @see jls.lang.Logger
 21  * @see jls.lang.ClassLoader
 22  */
 23 jls.lang = {};
 24 
 25 // Load prototype light
 26 _native.core.evalScript('plight.js');
 27 
 28 // Load base classes
 29 _native.core.evalScript('jls/lang/Exception.js');
 30 _native.core.evalScript('jls/lang/Logger.js');
 31 
 32 /**
 33  * Logger.
 34  * 
 35  * @type jls.lang.Logger
 36  * @memberOf jls
 37  */
 38 jls.logger = new jls.lang.Logger(jls.lang.Logger.WARN);
 39 
 40 if ('jls.logger.logLevel' in _native.core.properties) {
 41     jls.logger.setLogLevel(_native.core.properties['jls.logger.logLevel']);
 42 }
 43 
 44 _native.core.evalScript('jls/lang/ClassLoader.js');
 45 
 46 /**
 47  * ClassLoader.
 48  * 
 49  * @type jls.lang.ClassLoader
 50  * @memberOf jls
 51  */
 52 jls.loader = new jls.lang.ClassLoader();
 53 
 54 // Register base classes
 55 jls.loader.provide('jls.lang.Exception', true);
 56 jls.loader.provide('jls.lang.Logger', true);
 57 jls.loader.provide('jls.lang.ClassLoader', true);
 58 
 59 /*
 60  * Provide all lang classes
 61  */
 62 jls.loader.require('jls.lang.Buffer');
 63 jls.loader.require('jls.lang.Process');
 64 jls.loader.require('jls.lang.Runtime');
 65 jls.loader.require('jls.lang.System');
 66 
 67 if (! ('gui.toolkit' in _native.core.properties)) {
 68 	_native.core.properties['gui.toolkit'] = _native.core.properties['os.sysname'] == 'Windows_NT' ? 'win32' : 'gui';
 69 }
 70 
 71 jls.lang.System._initialize();
 72 
 73 jls.loader.require('jls.lang.Thread');
 74 jls.loader.require('jls.lang.Signal');
 75 jls.loader.require('jls.lang.Lock');
 76 jls.loader.require('jls.lang.Monitor');
 77 //jls.loader.require('jls.lang.ProcessBuilder');
 78 jls.loader.require('jls.lang.Struct');
 79 //jls.loader.require('jls.lang.AssertionError');
 80 
 81 if ('jls.disableDefaultExceptionHandler' in _native.core.properties) {
 82     jls.logger.info('Default exception handler disabled');
 83 } else {
 84     /*
 85      * Override exception handler
 86      */
 87     _native.core.exceptionHandler = function(e) {
 88         jls.lang.Exception.wrap(e).printStackTrace(jls.lang.System.err);
 89     }
 90 }
 91 
 92 if ('jls.disableDefaultSignalHandler' in _native.core.properties) {
 93     jls.logger.info('Default signal handlers disabled');
 94 } else {
 95     /*
 96      * Register default signal handlers.
 97      */
 98     jls.lang.Signal.handle(jls.lang.Signal.SIGINT, function() {
 99         jls.lang.Runtime.exit(0);
100     });
101     /*
102      * Don't know how to dump javascript thread stacktraces
103      */
104     /*jls.lang.Signal.handle(jls.lang.Signal.SIGBREAK, function() {
105         //jls.lang.System.out.println('... Dump stack trace ...');
106         //new jls.lang.Exception().printStackTrace(jls.lang.System.out);
107         var name = 'jlsdump.' + new Date().getTime() + '.log';
108         jls.lang.System.out.println('... Dump head to ' + name + '...');
109         _native.core.dumpHead(name); // Not available in release build
110     });*/
111 }
112 
113 if ('jls.gcDelay' in _native.core.properties) {
114     _native.core._gcThread = new jls.lang.Thread(true); // Daemon
115     _native.core._gcThread.run = function() {
116         var gcDelay = parseInt(_native.core.properties['jls.gcDelay'], 10);
117         if (gcDelay <= 0) {
118             jls.logger.warn('Invalid garbage collection delay (' + gcDelay + ')');
119             return;
120         }
121         if (gcDelay < 5000) {
122             jls.logger.warn('Aggressive garbage collection delay (' + gcDelay + ')');
123         }
124         for (;;) {
125             jls.lang.Thread.sleep(gcDelay);
126             jls.logger.info('start gc...');
127             jls.lang.System.gc();
128             jls.logger.info('...gc done');
129         }
130     };
131     _native.core._gcThread.start();
132 } else {
133     jls.logger.info('Garbage collection disabled');
134 }
135 
136 if ('jls.enableCommonJSModule' in _native.core.properties) {
137     jls.loader.require('jls.lang.ModuleLoader');
138     require = jls.lang.ModuleLoader.getInstance().require.bind(jls.lang.ModuleLoader.getInstance());
139 }
140 
141 if (_native.core.arguments.length > 0) {
142     var args = Array.from(_native.core.arguments);
143     var arg = args.shift();
144     
145     if ((arg == null) || (arg == '-help')) {
146         _native.core.boot = function() {
147             var lines = [
148                 'Usage: jls [options] classname [args...]',
149                 'where options include:',
150                 '\t-bs <bootstrap script file name>',
151                 '\t\tThe file name of the script to use for bootstrap.',
152                 '\t-ep <extension path>',
153                 '\t\tA directory to search for native library files,',
154                 '\t\tscript ZIP files and directories.',
155                 '\t-lp <library search path of directories>',
156                 '\t\tA ; separated list of directories to search for native library files.',
157                 '\t-sp <script search path of directories and ZIP files>',
158                 '\t\tA ; separated list of directories and ZIP archives',
159                 '\t\tto search for script files.',
160                 '\t-D<name>=<value>',
161                 '\t\tSet a system property.',
162                 '\t-logLevel <level>',
163                 '\t\tSet the native log level.',
164                 '\t--',
165                 '\t\tStop the jls options parsing.',
166                 'where system properties include:',
167                 '\t-Djls.logger.logLevel=<level>',
168                 '\t\tSet the log level.',
169                 '\t-Djls.gcDelay=<delay in ms>',
170                 '\t\tSet the garbage collection delay, default is disabled.',
171                 '\t-Djls.disableDefaultExceptionHandler',
172                 '\t\tDisable uncaught exception default handler.',
173                 '\t-Djls.disableDefaultSignalHandler',
174                 '\t\tDisable default signal handlers.',
175                 '\t-Djls.keep',
176                 '\t\tWaits Ctrl-C if an exception occurs at boot phase.',
177                 '\t-Djls.interactive',
178                 '\t\tEnables interactive boot mode.',
179                 'See http://javalikescript.free.fr/ for more details.'
180             ];
181             for (var i = 0; i < lines.length; i++) {
182                 jls.lang.System.out.println(lines[i]);
183             }
184         }
185     } else if (! arg.endsWith('.js')) {
186         /*
187          * Override boot function
188          */
189         _native.core.boot = function() {
190             jls.loader.require(arg);
191             var mainclass = eval(arg);
192             if (! ('main' in mainclass)) {
193                 throw new jls.lang.Exception('The class ' + arg + ' does not have a main method.');
194             }
195             mainclass['main'](args);
196         };
197     }
198 } else {
199     if ('jls.interactive' in _native.core.properties) {
200         // TODO
201     }
202 }
203 
204 if ('jls.keep' in _native.core.properties) {
205     var previousBoot = _native.core.boot;
206     _native.core.boot = function() {
207         try {
208             previousBoot.apply(this, arguments);
209         } catch (e) {
210             jls.lang.System.err.println('Error during boot, hit ctrl-c to end.');
211             jls.lang.Exception.wrap(e).printStackTrace(jls.lang.System.err);
212             // Start an infinite non daemon thread
213             var thread = new jls.lang.Thread();
214             thread.run = function() {
215                 while (true) {
216                     jls.lang.Thread.sleep(500);
217                 }
218             };
219             thread.start();
220         }
221     };
222 }
223