MAIN(ejscMain, int argc, char **argv) #endif { Mpr *mpr; Ejs *ejs; EcCompiler *cp; EjsService *vmService; MprList *useModules; char *argp, *searchPath, *outputFile, *certFile, *name, *tok, *modules, *spec; int nextArg, err, ejsFlags, ecFlags, bind, debug, doc, empty, merge; int warnLevel, noout, parseOnly, tabWidth, optimizeLevel, compilerMode, lang; /* * Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler */ mpr = mprCreate(argc, argv, ejsMemoryFailure); mprSetAppName(mpr, argv[0], 0, 0); if (mprStart(mpr, 0) < 0) { mprError(mpr, "Can't start mpr services"); return EJS_ERR; } err = 0; searchPath = 0; compilerMode = PRAGMA_MODE_STANDARD; certFile = 0; ecFlags = 0; bind = 0; debug = 0; doc = 0; empty = 0; merge = 0; noout = 0; parseOnly = 0; tabWidth = 4; warnLevel = 1; outputFile = 0; optimizeLevel = 9; lang = BLD_FEATURE_EJS_LANG; useModules = mprCreateList(mpr); for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "--bind") == 0) { bind = 1; } else if (strcmp(argp, "--debug") == 0) { debug = 1; } else if (strcmp(argp, "--doc") == 0) { doc = 1; } else if (strcmp(argp, "--lang") == 0) { if (nextArg >= argc) { err++; } else { spec = argv[++nextArg]; if (mprStrcmpAnyCase(spec, "ecma") == 0) { lang = EJS_SPEC_ECMA; } else if (mprStrcmpAnyCase(spec, "plus") == 0) { lang = EJS_SPEC_PLUS; } else if (mprStrcmpAnyCase(spec, "fixed") == 0) { lang = EJS_SPEC_FIXED; } } } else if (strcmp(argp, "--empty") == 0) { empty = 1; } else if (strcmp(argp, "--log") == 0) { /* * Undocumented logging switch */ if (nextArg >= argc) { err++; } else { ejsStartLogging(mpr, argv[++nextArg]); } } else if (strcmp(argp, "--merge") == 0) { merge = 1; } else if (strcmp(argp, "--nobind") == 0) { bind = 0; } else if (strcmp(argp, "--noout") == 0) { noout = 1; } else if (strcmp(argp, "--standard") == 0) { compilerMode = PRAGMA_MODE_STANDARD; } else if (strcmp(argp, "--strict") == 0) { compilerMode = PRAGMA_MODE_STRICT; } else if (strcmp(argp, "--optimize") == 0) { if (nextArg >= argc) { err++; } else { optimizeLevel = atoi(argv[++nextArg]); } } else if (strcmp(argp, "--out") == 0) { /* * Create a single output module file containing all modules */ if (nextArg >= argc) { err++; } else { outputFile = argv[++nextArg]; } } else if (strcmp(argp, "--parse") == 0) { parseOnly = 1; } else if (strcmp(argp, "--search") == 0 || strcmp(argp, "--searchpath") == 0) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (strcmp(argp, "--sign") == 0) { if (nextArg >= argc) { err++; } else { certFile = argv[++nextArg]; } } else if (strcmp(argp, "--tabWidth") == 0) { if (nextArg >= argc) { err++; } else { tabWidth = atoi(argv[++nextArg]); } } else if (strcmp(argp, "--use") == 0) { if (nextArg >= argc) { err++; } else { modules = mprStrdup(mpr, argv[++nextArg]); name = mprStrTok(modules, " \t", &tok); while (name != NULL) { mprAddItem(useModules, name); name = mprStrTok(NULL, " \t", &tok); } } } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { mprPrintfError(mpr, "%s %s-%s\n", BLD_NAME, BLD_VERSION, BLD_VERSION); return 0; } else if (strcmp(argp, "--warn") == 0) { if (nextArg >= argc) { err++; } else { warnLevel = atoi(argv[++nextArg]); } #if BLD_FEATURE_EJS_WEB } else if (strcmp(argp, "--web") == 0) { #if BLD_FEATURE_EJS_DB mprAddItem(useModules, "ejs.db"); #endif mprAddItem(useModules, "ejs.web"); #endif } else { err++; break; } } if (noout || merge) { bind = 1; } if (outputFile && noout) { mprPrintfError(mpr, "Can't use --out and --noout\n"); err++; } if (argc == nextArg) { err++; } if (err) { /* * Usage Examples: * ejsc Person.es User.es Customer.es * ejsc --out group.mod Person.es User.es Customer.es * ejsc --out group.mod Person.es User.es Customer.es */ mprPrintfError(mpr, "Usage: %s [options] files...\n" " Ejscript compiler options:\n" " --bind # Bind global properties to slots. Requires --out.\n" " --debug # Include symbolic debugging information in output\n" " --doc # Include documentation strings in output\n" " --lang # Language compliance (ecma|plus|fixed)\n" " --empty # Create empty interpreter\n" " --merge # Merge dependent input modules into the output\n" " --noout # Do not generate any output\n" " --optimize level # Set optimization level (0-9)\n" " --out filename # Name a single output module (default: \"default.mod\")\n" " --parse # Just parse source. No output\n" " --search ejsPath # Module search path\n" " --standard # Default compilation mode to standard (default)\n" " --strict # Default compilation mode to strict\n" #if FUTURE " --sign certFile # Sign the module file (not implemented) \n" " --tabwidth # Tab width for '^' error reporting\n" #endif " --use 'module, ...' # List of modules to pre-load\n" " --version # Emit the compiler version information\n" " --warn level # Set the warning message level (0-9)\n\n", mpr->name); return -1; } /* * Need an interpreter when compiling */ vmService = ejsCreateService(mpr); if (vmService == 0) { return MPR_ERR_NO_MEMORY; } ejsFlags = EJS_FLAG_NO_EXE; if (empty) { ejsFlags |= EJS_FLAG_EMPTY; } if (doc) { ejsFlags |= EJS_FLAG_DOC; } ejs = ejsCreate(vmService, NULL, searchPath, ejsFlags); if (ejs == 0) { return MPR_ERR_NO_MEMORY; } ecFlags = 0; ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0; ecFlags |= (empty) ? EC_FLAGS_EMPTY: 0; ecFlags |= (merge) ? EC_FLAGS_MERGE: 0; ecFlags |= (bind) ? EC_FLAGS_BIND: 0; ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0; ecFlags |= (parseOnly) ? EC_FLAGS_PARSE_ONLY: 0; cp = ecCreateCompiler(ejs, ecFlags, lang); if (cp == 0) { return MPR_ERR_NO_MEMORY; } ecSetOptimizeLevel(cp, optimizeLevel); ecSetWarnLevel(cp, warnLevel); ecSetDefaultMode(cp, compilerMode); ecSetTabWidth(cp, tabWidth); ecSetOutputFile(cp, outputFile); ecSetCertFile(cp, certFile); if (preloadModules(cp, useModules) < 0) { return EJS_ERR; } if (nextArg < argc) { /* * Compile the source files supplied on the command line. This will compile in-memory and * optionally also save to module files. */ if (ecCompile(cp, argc - nextArg, &argv[nextArg], 0) < 0) { err++; } } if (cp->errorCount > 0) { err++; } #if VXWORKS mprFree(cp); mprFree(ejs); if (mprStop(mpr)) { mprFree(mpr); } #endif return err; }
int main(int argc, char **argv) { Mpr *mpr; EcCompiler *cp; EjsService *vmService; Ejs *ejs; MprList *useModules, *files; cchar *cmd, *className, *methodName; char *argp, *searchPath, *modules, *name, *tok, *extraFiles, *spec; int nextArg, err, ejsFlags, ecFlags, stats, run, merge, bind, noout, debug, optimizeLevel, nobind, warnLevel; int compilerMode, lang; /* * Create the Embedthis Portable Runtime (MPR) and setup a memory failure handler */ mpr = mprCreate(argc, argv, ejsMemoryFailure); mprSetAppName(mpr, argv[0], 0, 0); if (mprStart(mpr, 0) < 0) { mprError(mpr, "Can't start mpr services"); return EJS_ERR; } err = 0; className = 0; cmd = 0; methodName = 0; searchPath = 0; stats = 0; run = 1; merge = 0; bind = 1; nobind = 0; noout = 1; debug = 1; warnLevel = 1; optimizeLevel = 9; compilerMode = PRAGMA_MODE_STANDARD; lang = BLD_FEATURE_EJS_LANG; useModules = mprCreateList(mpr); files = mprCreateList(mpr); ejsFlags = EJS_FLAG_COMPILER; for (nextArg = 1; nextArg < argc; nextArg++) { argp = argv[nextArg]; if (*argp != '-') { break; } if (strcmp(argp, "--bind") == 0) { /* Ignore. Not required and only here for compatibility with ec */ } else if (strcmp(argp, "--class") == 0) { if (nextArg >= argc) { err++; } else { className = argv[++nextArg]; } } else if (strcmp(argp, "--cmd") == 0 || strcmp(argp, "-c") == 0) { if (nextArg >= argc) { err++; } else { cmd = argv[++nextArg]; } } else if (strcmp(argp, "--debug") == 0) { debug = 1; } else if (strcmp(argp, "--lang") == 0) { if (nextArg >= argc) { err++; } else { spec = argv[++nextArg]; if (mprStrcmpAnyCase(spec, "ecma") == 0) { lang = EJS_SPEC_ECMA; } else if (mprStrcmpAnyCase(spec, "plus") == 0) { lang = EJS_SPEC_PLUS; } else if (mprStrcmpAnyCase(spec, "fixed") == 0) { lang = EJS_SPEC_FIXED; } } } else if (strcmp(argp, "--files") == 0 || strcmp(argp, "-f") == 0) { if (nextArg >= argc) { err++; } else { extraFiles = mprStrdup(mpr, argv[++nextArg]); name = mprStrTok(extraFiles, " \t", &tok); while (name != NULL) { mprAddItem(files, name); name = mprStrTok(NULL, " \t", &tok); } } } else if (strcmp(argp, "--log") == 0) { if (nextArg >= argc) { err++; } else { ejsStartLogging(mpr, argv[++nextArg]); } } else if (strcmp(argp, "--method") == 0) { if (nextArg >= argc) { err++; } else { methodName = argv[++nextArg]; } } else if (strcmp(argp, "--nobind") == 0) { /* * This is a hidden switch just for the compiler developers */ nobind = 1; bind = 0; } else if (strcmp(argp, "--nodebug") == 0) { debug = 0; } else if (strcmp(argp, "--optimize") == 0) { if (nextArg >= argc) { err++; } else { optimizeLevel = atoi(argv[++nextArg]); } } else if (strcmp(argp, "--searchpath") == 0) { if (nextArg >= argc) { err++; } else { searchPath = argv[++nextArg]; } } else if (strcmp(argp, "--standard") == 0) { compilerMode = PRAGMA_MODE_STANDARD; } else if (strcmp(argp, "--stats") == 0) { stats = 1; } else if (strcmp(argp, "--strict") == 0) { compilerMode = PRAGMA_MODE_STRICT; } else if (strcmp(argp, "--use") == 0) { if (nextArg >= argc) { err++; } else { modules = mprStrdup(mpr, argv[++nextArg]); name = mprStrTok(modules, " \t", &tok); while (name != NULL) { mprAddItem(useModules, name); name = mprStrTok(NULL, " \t", &tok); } } } else if (strcmp(argp, "--version") == 0 || strcmp(argp, "-V") == 0) { mprErrorPrintf(mpr, "%s %s\n" "Copyright (C) Embedthis Software 2003-2009\n" "Copyright (C) Michael O'Brien 2003-2009\n", BLD_NAME, BLD_VERSION); exit(0); } else if (strcmp(argp, "--warn") == 0) { if (nextArg >= argc) { err++; } else { warnLevel = atoi(argv[++nextArg]); } } else { err++; break; } } if (err) { /* * If --method or --class is specified, then the named class.method will be run (method defaults to "main", class * defaults to first class with a "main"). * * Examples: * ejs * ejs script.es arg1 arg2 arg3 * ejs --class "Customer" --method "start" --files "script1.es script2.es" main.es */ mprErrorPrintf(mpr, "Usage: %s [options] script.es [arguments] ...\n" " Ejscript shell program options:\n" " --class className # Name of class containing method to run\n" " --cmd ejscriptCode # Literal ejscript statements to execute\n" " --debug # Include symbolic debugging information in output\n" " --lang # Language compliance (ecma|plus|fixed)\n" " --files \"files..\" # Extra source to compile\n" " --log logSpec # Internal compiler diagnostics logging\n" " --method methodName # Name of method to run. Defaults to main\n" " --nodebug # Omit symbolic debugging information in output\n" " --optimize level # Set the optimization level (0-9 default is 9)\n" " --searchpath ejsPath # Module search path\n" " --standard # Default compilation mode to standard (default)\n" " --stats # Print stats on exit\n" " --strict # Default compilation mode to strict\n" " --use 'module, ...' # List of modules to pre-load\n" " --version # Emit the compiler version information\n" " --warn level # Set the warning message level (0-9 default is 0)\n\n", mpr->name); return -1; } vmService = ejsCreateService(mpr); if (vmService == 0) { return MPR_ERR_NO_MEMORY; } if (searchPath) { ejsSetSearchPath(vmService, searchPath); } ejs = ejsCreate(vmService, 0, ejsFlags); if (ejs == 0) { return MPR_ERR_NO_MEMORY; } ecFlags = 0; ecFlags |= (run) ? EC_FLAGS_RUN: 0; ecFlags |= (merge) ? EC_FLAGS_MERGE: 0; ecFlags |= (bind) ? EC_FLAGS_BIND_GLOBALS: 0; ecFlags |= (nobind) ? EC_FLAGS_NO_BIND: 0; ecFlags |= (noout) ? EC_FLAGS_NO_OUT: 0; ecFlags |= (debug) ? EC_FLAGS_DEBUG: 0; cp = ecCreateCompiler(ejs, ecFlags, lang); if (cp == 0) { return MPR_ERR_NO_MEMORY; } ecSetOptimizeLevel(cp, optimizeLevel); ecSetWarnLevel(cp, warnLevel); ecSetDefaultMode(cp, compilerMode); if (preloadModules(cp, useModules) < 0) { return EJS_ERR; } if (cmd) { if (interpretCommands(cp, cmd) < 0) { err++; } } else if (nextArg < argc) { name = argv[nextArg]; mprAddItem(files, argv[nextArg]); if (interpretFiles(cp, files, argc - nextArg, &argv[nextArg], className, methodName) < 0) { err++; } } else { /* * No args - run as an interactive shell */ if (interpretCommands(cp, NULL) < 0) { err++; } } #if BLD_DEBUG if (stats) { mprSetLogLevel(ejs, 1); ejsPrintAllocReport(ejs); } #endif mprFree(mpr); return err; }
/* * function Worker(script: String = null, options: Object = null) * * Script is optional. If supplied, the script is run immediately by a worker thread. This call * does not block. Options are: search and name. */ static EjsVar *workerConstructor(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv) { Ejs *wejs; EjsVar *options, *value; EjsName qname; EjsWorker *self; cchar *search, *name; worker->ejs = ejs; worker->state = EJS_WORKER_BEGIN; options = (argc == 2) ? (EjsVar*) argv[1]: NULL; name = 0; search = ejs->ejsPath; if (options) { value = ejsGetPropertyByName(ejs, options, ejsName(&qname, "", "search")); if (ejsIsString(value)) { search = ejsGetString(value); } value = ejsGetPropertyByName(ejs, options, ejsName(&qname, "", "name")); if (ejsIsString(value)) { name = ejsGetString(value); } } if (name) { worker->name = mprStrdup(worker, name); } else { worker->name = mprAsprintf(worker, -1, "worker-%d", mprGetListCount(ejs->workers)); } /* * Create a new interpreter and an "inside" worker object and pair it with the current "outside" worker. */ wejs = ejsCreate(ejs->service, NULL, search, 0); if (wejs == 0) { ejsThrowMemoryError(ejs); return 0; } worker->pair = self = ejsCreateWorker(wejs); self->state = EJS_WORKER_BEGIN; self->ejs = wejs; self->inside = 1; self->pair = worker; self->name = mprStrcat(self, -1, "inside-", worker->name, NULL); ejsSetProperty(ejs, (EjsVar*) worker, ES_ejs_sys_Worker_name, (EjsVar*) ejsCreateString(ejs, self->name)); ejsSetProperty(wejs, (EjsVar*) self, ES_ejs_sys_Worker_name, (EjsVar*) ejsCreateString(wejs, self->name)); ejsSetProperty(wejs, wejs->global, ES_ejs_sys_worker_self, (EjsVar*) self); /* * Workers have a dedicated namespace to enable viewing of the worker globals (self, onmessage, postMessage...) */ ejsDefineReservedNamespace(wejs, wejs->globalBlock, 0, EJS_WORKER_NAMESPACE); /* * Make the inside worker permanent so we don't need to worry about whether worker->pair->ejs is valid */ self->obj.var.permanent = 1; if (argc > 0 && ejsIsPath(argv[0])) { addWorker(ejs, worker); worker->scriptFile = mprStrdup(worker, ((EjsPath*) argv[0])->path); worker->state = EJS_WORKER_STARTED; worker->obj.var.permanent = 1; if (mprStartWorker(ejs, (MprWorkerProc) workerMain, (void*) worker, MPR_NORMAL_PRIORITY) < 0) { ejsThrowStateError(ejs, "Can't start worker"); worker->obj.var.permanent = 0; return 0; } } return (EjsVar*) worker; }