コード例 #1
0
ファイル: ejsWorker.c プロジェクト: embedthis/ejs-1
/*
 *  Post a message to this worker. Note: the worker is the destination worker which may be the parent.
 *
 *  function postMessage(data: Object, ports: Array = null): Void
 */
static EjsVar *workerPostMessage(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    EjsVar          *data;
    EjsWorker       *target;
    MprDispatcher   *dispatcher;
    Message         *msg;

    if (worker->state >= EJS_WORKER_CLOSED) {
        ejsThrowStateError(ejs, "Worker has completed");
        return 0;
    }

    /*
     *  Create the event with serialized data in the originating interpreter. It owns the data.
     */
    if ((data = ejsSerialize(ejs, argv[0], -1, 0, 0)) == 0) {
        ejsThrowArgError(ejs, "Can't serialize message data");
        return 0;
    }
    if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    target = worker->pair;
    msg->data = mprStrdup(target->ejs, ejsGetString(data));
    msg->worker = target;
    msg->callback = "onmessage";
    msg->callbackSlot = ES_ejs_sys_Worker_onmessage;

    dispatcher = target->ejs->dispatcher;
    mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0);
    mprSignalCond(dispatcher->cond);
    return 0;
}
コード例 #2
0
ファイル: simpleEjs.c プロジェクト: varphone/appweb-4
static EjsVar *myEjs(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
{
    int     i;

    /*
        Write this data back to the client
     */
    ejsWrite(ejs, "<h1>Hello World</h1><p>Args: ");

    mprAssert(argv);
    for (i = 0; i < argc; ) {
        if (ejsIsNumber(argv[i])) {
            ejsWrite(ejs, "%d", ejsGetInt(argv[i]));
        } else {
            ejsWrite(ejs, ejsGetString(argv[i]));
        }
        if (++i < argc) {
            ejsWrite(ejs, " ");
        }
    }
    ejsWrite(ejs, "</p>");

    /*
     *  Functions can return a result
     */
    return (EjsVar*) ejsCreateString(ejs, "sunny day");
    return 0;
}
コード例 #3
0
ファイル: ejsApp.c プロジェクト: embedthis/ejs-1
/*
 *  Put an environment var
 *
 *  function putenv(key: String, value: String): void
 */
static EjsVar *putEnvVar(Ejs *ejs, EjsObject *app, int argc, EjsVar **argv)
{

#if !WINCE
#if BLD_UNIX_LIKE
    char    *key, *value;

    key = mprStrdup(ejs, ejsGetString(argv[0]));
    value = mprStrdup(ejs, ejsGetString(argv[1]));
    setenv(key, value, 1);
#else
    char   *cmd;

    cmd = mprStrcat(app, -1, ejsGetString(argv[0]), "=", ejsGetString(argv[1]), NULL);
    putenv(cmd);
#endif
#endif
    return 0;
}
コード例 #4
0
ファイル: ejsApp.c プロジェクト: embedthis/ejs-1
/*
 *  Get an environment var
 *
 *  function getenv(key: String): String
 */
static EjsVar *getEnvVar(Ejs *ejs, EjsObject *app, int argc, EjsVar **argv)
{
    cchar   *value;

    value = getenv(ejsGetString(argv[0]));
    if (value == 0) {
        return (EjsVar*) ejs->nullValue;
    }
    return (EjsVar*) ejsCreateString(ejs, value);
}
コード例 #5
0
ファイル: ejsWorker.c プロジェクト: embedthis/ejs-1
/*
 *  function eval(script: String, timeout: Boolean = -1): String
 */
static EjsVar *workerEval(Ejs *ejs, EjsWorker *worker, int argc, EjsVar **argv)
{
    int     timeout;

    mprAssert(ejsIsString(argv[0]));

    worker->scriptLiteral = mprStrdup(worker, ejsGetString(argv[0]));
    timeout = argc == 2 ? ejsGetInt(argv[1]): MAXINT;
    return startWorker(ejs, worker, timeout);
}
コード例 #6
0
ファイル: ejsDb.c プロジェクト: jsjohnst/ejscript
/*
 *  DB Constructor and also used for constructor for sub classes.
 *
 *  function DB(connectionString: String)
 */
static EjsVar *dbConstructor(Ejs *ejs, EjsDb *db, int argc, EjsVar **argv)
{
    sqlite3     *sdb;
    EjsDb       **dbp;
    char        *path;

    path = ejsGetString(argv[0]);    
    
    /*
     *  Create a memory context for use by sqlite. This is a virtual paged memory region.
     *  TODO - this is not ideal for long running applications.
     */
    db->arena = mprAllocArena(ejs, "sqlite", EJS_MAX_DB_MEM, 0, 0);
    if (db->arena == 0) {
        return 0;
    }
    
    /*
     *  Create a destructor object so we can cleanup and close the database. Must create after the arena so it will be
     *  invoked before the arena is freed. 
     */
    if ((dbp = mprAllocObject(ejs, 1, (MprDestructor) dbDestructor)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    *dbp = db;
    
    db->tls = mprCreateThreadLocal(db->arena);
    if (db->tls == 0) {
        return 0;
    }
    ejsSetDbMemoryContext(db->tls, db->arena);

    sdb = 0;
    if (sqlite3_open(path, &sdb /* TODO remove , SQLITE_OPEN_READWRITE, 0 */) != SQLITE_OK) {
        ejsThrowIOError(ejs, "Can't open database %s", path);
        return 0;
    }
    db->sdb = sdb;

    sqlite3_busy_timeout(sdb, 15000);

    /*
     *  Query or change the count-changes flag. Normally, when the count-changes flag is not set, INSERT, UPDATE and
     *  DELETE statements return no data. When count-changes is set, each of these commands returns a single row of
     *  data consisting of one integer value - the number of rows inserted, modified or deleted by the command. The
     *  returned change count does not include any insertions, modifications or deletions performed by triggers.
     */
//  sqlite3_exec(sdb, "PRAGMA count_changes = OFF", NULL, NULL, NULL);

    ejsSetProperty(ejs, (EjsVar*) db, ES_ejs_db_Database__connection, (EjsVar*) ejsCreateString(ejs, path));
    ejsSetProperty(ejs, (EjsVar*) db, ES_ejs_db_Database__name, (EjsVar*) ejsCreateString(ejs, mprGetBaseName(path)));
    
    return 0;
}
コード例 #7
0
ファイル: ejsError.c プロジェクト: embedthis/ejs-1
/*
 *  Error Constructor and constructor for all the core error classes.
 *
 *  public function Error(message: String = null)
 */
static EjsVar *errorConstructor(Ejs *ejs, EjsError *error, int argc,  EjsVar **argv)
{
    mprFree(error->message);
    if (argc == 0) {
        error->message = mprStrdup(error, "");
    } else {
        error->message = mprStrdup(error, ejsGetString(argv[0]));
    }
    mprFree(error->stack);
    ejsFormatStack(ejs, error);
    return (EjsVar*) error;
}
コード例 #8
0
ファイル: ejsWorker.c プロジェクト: embedthis/ejs-1
/*
 *  WARNING: the inside interpreter owns the exception object. Must fully extract all fields
 */
static void handleError(Ejs *ejs, EjsWorker *worker, EjsVar *exception)
{
    EjsError        *error;
    MprDispatcher   *dispatcher;
    Message         *msg;

    mprAssert(!worker->inside);
    mprAssert(exception);
    mprAssert(ejs == worker->ejs);

    if ((msg = mprAllocObjZeroed(ejs, Message)) == 0) {
        ejsThrowMemoryError(ejs);
        return;
    }
    msg->worker = worker;
    msg->callback = "onerror";
    msg->callbackSlot = ES_ejs_sys_Worker_onerror;
    
    /*
     *  Inside interpreter owns the exception object, so must fully extract all exception. 
     *  Allocate into the outside worker's interpreter.
     */
    if (ejsIsError(exception)) {
        error = (EjsError*) exception;
        msg->message = mprStrdup(ejs, error->message);
        msg->filename = mprStrdup(ejs, error->filename ? error->filename : "script");
        msg->lineNumber = error->lineNumber;
        msg->stack = mprStrdup(ejs, error->stack);

    } else if (ejsIsString(exception)) {
        msg->message = mprStrdup(ejs, ejsGetString(exception));

    } else {
        msg->message = mprStrdup(ejs, ejsGetString(ejsToString(ejs, exception)));
    }
    dispatcher = ejs->dispatcher;
    mprCreateEvent(dispatcher, (MprEventProc) doMessage, 0, MPR_NORMAL_PRIORITY, msg, 0);
    mprSignalCond(dispatcher->cond);
}
コード例 #9
0
ファイル: ejsDebugger.c プロジェクト: embedthis/ejscript
/*
    DB Constructor and also used for constructor for sub classes.

    function Debugger(connectionString: String)
 */
static EjsVar *debuggerConstructor(Ejs *ejs, EjsDebugger *db, int argc, EjsVar **argv)
{
    debugger3         *sdb;
    cchar           *path;

    path = ejsGetString(ejs, argv[0]);    
    db->ejs = ejs;
    
    /*
     *  Create a memory context for use by debugger. This is a virtual paged memory region.
     *  TODO OPT - Could do better for running applications.
     */
#if MAP_ALLOC
    db->arena = mprAllocArena(ejs, "debugger", EJS_MAX_SQLITE_MEM, !USE_TLS, 0);
    if (db->arena == 0) {
        return 0;
    }
    SET_CTX(db->arena);
#else
    db->arena = mprAllocHeap(ejs, "debugger", EJS_MAX_SQLITE_MEM, 1, 0);
    if (db->arena == 0) {
        return 0;
    }
    SET_CTX(db->arena);
#endif
    
#if UNUSED
    EjsDebugger       **dbp;
    /*
     *  Create a destructor object so we can cleanup and close the database. Must create after the arena so it will be
     *  invoked before the arena is freed. 
     */
    if ((dbp = mprAllocWithDestructor(ejs, sizeof(void*), (MprDestructor) sqldbDestructor)) == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    *dbp = db;
#endif

    sdb = 0;
    if (debugger3_open(path, &sdb) != SQLITE_OK) {
        ejsThrowIOError(ejs, "Cannot open database %s", path);
        return 0;
    }
    db->sdb = sdb;
    debugger3_busy_timeout(sdb, ME_MAX_SQLITE_DURATION);
    debugger3_soft_heap_limit(ME_MAX_SQLITE_MEM);
    return 0;
}
コード例 #10
0
ファイル: ejsWorker.c プロジェクト: embedthis/ejs-1
/*
 *  static function lookup(name: String): Worker
 */
static EjsVar *workerLookup(Ejs *ejs, EjsVar *unused, int argc, EjsVar **argv)
{
    EjsWorker   *worker;
    cchar       *name;
    int         next;

    name = ejsGetString(argv[0]);
    lock(ejs);
    for (next = 0; (worker = mprGetNextItem(ejs->workers, &next)) != NULL; ) {
        if (worker->name && strcmp(name, worker->name) == 0) {
            unlock(ejs);
            return (EjsVar*) worker;
        }
    }
    unlock(ejs);
    return ejs->nullValue;
}
コード例 #11
0
ファイル: ejsApp.c プロジェクト: embedthis/ejs-1
/*
 *  Set the current working directory
 *
 *  function chdir(value: String|Path): void
 */
static EjsVar *changeCurrentDir(Ejs *ejs, EjsVar *unused, int argc, EjsVar **argv)
{
    char    *path;

    mprAssert(argc == 1);

    if (ejsIsPath(argv[0])) {
        path = ((EjsPath*) argv[0])->path;
    } else if (ejsIsString(argv[0])) {
        path = ejsGetString(argv[0]);
    } else {
        ejsThrowIOError(ejs, "Bad path");
        return NULL;
    }

    if (chdir(path) < 0) {
        ejsThrowIOError(ejs, "Can't change the current directory");
    }
    return 0;
}
コード例 #12
0
ファイル: ejsDb.c プロジェクト: jsjohnst/ejscript
/*
 *  function sql(cmd: String): Array
 *
 *  Will support multiple sql cmds but will only return one result table.
 */
static EjsVar *sql(Ejs *ejs, EjsDb *db, int argc, EjsVar **argv)
{
    sqlite3         *sdb;
    sqlite3_stmt    *stmt;
    EjsArray        *result;
    EjsVar          *row, *svalue;
    EjsName         qname;
    cchar           *tail, *colName, *cmd, *value;
    int             i, ncol, rc, retries, rowNum;

    mprAssert(ejs);
    mprAssert(db);

    cmd = ejsGetString(argv[0]);
    
    ejsSetDbMemoryContext(db->tls, db->arena);

    rc = SQLITE_OK;
    retries = 0;
    sdb = db->sdb;

    if (sdb == 0) {
        ejsThrowIOError(ejs, "Database is closed");
        return 0;
    }
    mprAssert(sdb);

    result = ejsCreateArray(ejs, 0);
    if (result == 0) {
        return 0;
    }

    while (cmd && *cmd && (rc == SQLITE_OK || (rc == SQLITE_SCHEMA && ++retries < 2))) {

        stmt = 0;
        rc = sqlite3_prepare_v2(sdb, cmd, -1, &stmt, &tail);
        if (rc != SQLITE_OK) {
            continue;
        }
        if (stmt == 0) {
            /* Comment or white space */
            cmd = tail;
            continue;
        }

        ncol = sqlite3_column_count(stmt);

        for (rowNum = 0; ; rowNum++) {

            rc = sqlite3_step(stmt);

            if (rc == SQLITE_ROW) {

                row = (EjsVar*) ejsCreateSimpleObject(ejs);
                if (row == 0) {
                    sqlite3_finalize(stmt);
                    return 0;
                }
                if (ejsSetProperty(ejs, (EjsVar*) result, rowNum, row) < 0) {
                    /* TODO rc */
                }
                for (i = 0; i < ncol; i++) {
                    colName = sqlite3_column_name(stmt, i);
                    value = (cchar*) sqlite3_column_text(stmt, i);
                    ejsName(&qname, EJS_EMPTY_NAMESPACE, mprStrdup(row, colName));
                    if (ejsLookupProperty(ejs, row, &qname) < 0) {
                        svalue = (EjsVar*) ejsCreateString(ejs, mprStrdup(row, value));
                        if (ejsSetPropertyByName(ejs, row, &qname, svalue) < 0) {
                            /* TODO */
                        }
                    }
                }
            } else {
                rc = sqlite3_finalize(stmt);
                stmt = 0;

                if (rc != SQLITE_SCHEMA) {
                    //  TODO - what is this?
                    retries = 0;
                    for (cmd = tail; isspace(*cmd); cmd++) {
                        ;
                    }
                }
                break;
            }
#if UNUSED
            /* TODO -- should we be doing this */
            cmd = tail;
#endif
        }
    }

    if (stmt) {
        rc = sqlite3_finalize(stmt);
    }

    if (rc != SQLITE_OK) {
        if (rc == sqlite3_errcode(sdb)) {
            ejsThrowIOError(ejs, "SQL error: %s", sqlite3_errmsg(sdb));
        } else {
            ejsThrowIOError(ejs, "Unspecified SQL error");
        }
        return 0;
    }

    return (EjsVar*) result;
}
コード例 #13
0
ファイル: ejsApp.c プロジェクト: embedthis/ejs-1
/*
 *  Set the ejs module search path (EJSPATH). Does not actually update the environment.
 *
 *  function set searchPath(path: String): Void
 */
static EjsVar *setSearchPath(Ejs *ejs, EjsObject *app, int argc, EjsVar **argv)
{
    ejsSetSearchPath(ejs, ejsGetString(argv[0]));
    return 0;
}
コード例 #14
0
ファイル: ejsWorker.c プロジェクト: embedthis/ejs-1
/*
 *  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;
}