Exemple #1
0
/*
    Set the length. TODO - what does this do?
    public override function set length(value: int): void
 */
static EjsObj *setLength(Ejs *ejs, EjsXML *xml, int argc, EjsObj **argv)
{
    int         length;

    assert(ejsIsXML(ejs, xml));

    if (argc != 1) {
        ejsThrowArgError(ejs, "usage: obj.length = value");
        return 0;
    }
    length = ejsVarToInteger(ejs, argv[0]);

    if (length < ap->length) {
        for (i = length; i < ap->length; i++) {
            if (ejsSetProperty(ejs, ap, i, ESV(undefined)) < 0) {
                //  TODO - DIAG
                return 0;
            }
        }

    } else if (length > ap->length) {
        if (ejsSetProperty(ejs, ap, length - 1, ESV(undefined)) < 0) {
            //  TODO - DIAG
            return 0;
        }
    }

    ap->length = length;
    return 0;
}
Exemple #2
0
PUBLIC void ejsConfigureAppType(Ejs *ejs)
{
    EjsType     *type;

    if ((type = ejsFinalizeScriptType(ejs, N("ejs", "App"), 0, 0, 0)) == 0) {
        return;
    }
    ejsSetProperty(ejs, type, ES_App__inputStream, ejsCreateFileFromFd(ejs, 0, "stdin", O_RDONLY));
    ejsSetProperty(ejs, type, ES_App__outputStream, ejsCreateFileFromFd(ejs, 1, "stdout", O_WRONLY));
    ejsSetProperty(ejs, type, ES_App__errorStream, ejsCreateFileFromFd(ejs, 2, "stderr", O_WRONLY));

    ejsBindMethod(ejs, type, ES_App_args, app_args);
    ejsBindMethod(ejs, type, ES_App_createSearch, app_createSearch);
    ejsBindMethod(ejs, type, ES_App_dir, app_dir);
    ejsBindMethod(ejs, type, ES_App_chdir, app_chdir);
    ejsBindMethod(ejs, type, ES_App_exeDir, app_exeDir);
    ejsBindMethod(ejs, type, ES_App_exePath, app_exePath);
    ejsBindMethod(ejs, type, ES_App_env, app_env);
    ejsBindMethod(ejs, type, ES_App_exit, app_exit);
    ejsBindMethod(ejs, type, ES_App_getenv, app_getenv);
    ejsBindMethod(ejs, type, ES_App_gid, app_gid);
    ejsBindMethod(ejs, type, ES_App_putenv, app_putenv);
    ejsBindMethod(ejs, type, ES_App_pid, app_pid);
    ejsBindMethod(ejs, type, ES_App_run, app_run);
    ejsBindAccess(ejs, type, ES_App_search, app_search, app_set_search);
    ejsBindMethod(ejs, type, ES_App_sleep, app_sleep);
    ejsBindMethod(ejs, type, ES_App_uid, app_uid);
    ejsBindMethod(ejs, type, ES_App_getpass, app_getpass);
}
Exemple #3
0
/*
 *  Set a property given a name.
 */
int ejsSetPropertyByName(Ejs *ejs, EjsVar *vp, EjsName *qname, EjsVar *value)
{
    int     slotNum;

    mprAssert(ejs);
    mprAssert(vp);
    mprAssert(qname);

    if (vp->type->helpers->setPropertyByName) {
        ejsSetReference(ejs, vp, value);
        return (vp->type->helpers->setPropertyByName)(ejs, vp, qname, value);
    }

    /*
     *  Fall back and use a two-step lookup and get
     */
    slotNum = ejsLookupProperty(ejs, vp, qname);
    if (slotNum < 0) {
        slotNum = ejsSetProperty(ejs, vp, -1, value);
        if (slotNum < 0) {
            return EJS_ERR;
        }
        if (ejsSetPropertyName(ejs, vp, slotNum, qname) < 0) {
            return EJS_ERR;
        }
        return slotNum;
    }
    ejsSetReference(ejs, vp, value);
    return ejsSetProperty(ejs, vp, slotNum, value);
}
Exemple #4
0
/*
 *  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;
}
Exemple #5
0
/*
    Error Constructor and constructor for all the core error classes.

    public function Error(message: String = null)
 */
static EjsError *errorConstructor(Ejs *ejs, EjsError *error, int argc, EjsObj **argv)
{
    if (argc > 0) {
        ejsSetProperty(ejs, error, ES_Error_message, ejsToString(ejs, argv[0]));
    }
    if (ESV(Date)) {
        ejsSetProperty(ejs, error, ES_Error_timestamp, ejsCreateDate(ejs, mprGetTime()));
        ejsSetProperty(ejs, error, ES_Error_stack, ejsCaptureStack(ejs, 0));
    }
    return error;
}
Exemple #6
0
PUBLIC EjsError *ejsCreateError(Ejs *ejs, EjsType *type, EjsObj *msg) 
{
    EjsError    *error;

    error = ejsCreatePot(ejs, type, 0);
    if (error) {
        ejsSetProperty(ejs, error, ES_Error_message, msg);
        ejsSetProperty(ejs, error, ES_Error_timestamp, ejsCreateDate(ejs, mprGetTime()));
        ejsSetProperty(ejs, error, ES_Error_stack, ejsCaptureStack(ejs, 0));
    }
    return error;
}
Exemple #7
0
static void defineBooleanConstants(Ejs *ejs)
{
    EjsType     *type;

    type = ejs->booleanType;

    if (ejs->flags & EJS_FLAG_EMPTY) {
        return;
    }

    ejsSetProperty(ejs, ejs->global, ES_boolean, (EjsVar*) type);
    ejsSetProperty(ejs, ejs->global, ES_true, (EjsVar*) ejs->trueValue);
    ejsSetProperty(ejs, ejs->global, ES_false, (EjsVar*) ejs->falseValue);
}
Exemple #8
0
EjsArray *ejsCaptureStack(Ejs *ejs, int uplevels)
{
    EjsFrame        *fp;
    EjsState        *state;
    EjsArray        *stack;
    wchar           *source;
    EjsObj          *frame;
    char            *filename;
    int             index, lineNumber;

    assert(ejs);

    stack = ejsCreateArray(ejs, 0);
    index = 0;
    for (state = ejs->state; state; state = state->prev) {
        for (fp = state->fp; fp; fp = fp->caller) {
            if (uplevels-- <= 0) {
                frame = ejsCreateEmptyPot(ejs);
                if (ejsGetDebugInfo(ejs, (EjsFunction*) fp, fp->pc, &filename, &lineNumber, &source) >= 0) {
                    ejsSetPropertyByName(ejs, frame, EN("filename"), ejsCreatePathFromAsc(ejs, filename));
                    ejsSetPropertyByName(ejs, frame, EN("lineno"), ejsCreateNumber(ejs, lineNumber));
                    ejsSetPropertyByName(ejs, frame, EN("code"), ejsCreateString(ejs, source, wlen(source)));
                } else {
                    ejsSetPropertyByName(ejs, frame, EN("filename"), EST(undefined));
                }
                ejsSetPropertyByName(ejs, frame, EN("func"), fp->function.name);
                ejsSetProperty(ejs, stack, index++, frame);
            }
        }
    }
    return stack;
}
Exemple #9
0
/*
 *  Return an array of table names in the database.
 *  function get tables(): Array
 */
static EjsVar *tables(Ejs *ejs, EjsDb *db, int argc, EjsVar **argv)
{
    EjsArray    *ap;
    char        **data, *error;
    int         rc, rowCount, i;

    ejsSetDbMemoryContext(db->tls, db->arena);

    ap = ejsCreateArray(ejs, 0);

    rc = sqlite3_get_table(db->sdb,
      "SELECT name FROM sqlite_master "
      "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%'"
      "UNION ALL "
      "SELECT name FROM sqlite_temp_master "
      "WHERE type IN ('table','view') "
      "ORDER BY 1",
      &data, &rowCount, 0, &error);

    if (error) {
        ejsThrowIOError(ejs, "%s", error);
        sqlite3_free(error);
    }
    if (rc == SQLITE_OK){
        for (i = 1; i <= rowCount; i++) {
            ejsSetProperty(ejs, (EjsVar*) ap, i - 1, (EjsVar*) ejsCreateString(ejs, data[i]));
        }
    }
    sqlite3_free_table(data);
    return (EjsVar*) ap;
}
Exemple #10
0
void ejsCreateVoidType(Ejs *ejs)
{
    EjsType     *type;
    EjsName     qname;

    type = ejsCreateCoreType(ejs, ejsName(&qname, EJS_INTRINSIC_NAMESPACE, "Void"), ejs->objectType, sizeof(EjsVoid),
        ES_Void, ES_Void_NUM_CLASS_PROP, ES_Void_NUM_INSTANCE_PROP, EJS_ATTR_NATIVE);
    ejs->voidType = type;

    /*
     *  Define the helper functions.
     */
    type->helpers->castVar = (EjsCastVarHelper) castVoid;
    type->helpers->invokeOperator = (EjsInvokeOperatorHelper) invokeVoidOperator;

    ejs->undefinedValue = ejsCreateVar(ejs, type, 0);
    ejsSetDebugName(ejs->undefinedValue, "undefined");

    if (!(ejs->flags & EJS_FLAG_EMPTY)) {
        /*
         *  Define the "undefined" value
         */
        ejsSetProperty(ejs, ejs->global, ES_undefined, ejs->undefinedValue);
    }
}
Exemple #11
0
static EjsAny *createException(Ejs *ejs, EjsType *type, cchar* fmt, va_list fmtArgs)
{
    EjsError    *error;
    EjsAny      *argv[1];
    char        *msg;

    assert(type);
    
#if ME_DEBUG
    /* Breakpoint opportunity */
    if (!ejs->empty) {
        mprNop(0);
    }
#endif
    msg = sfmtv(fmt, fmtArgs);
    argv[0] = ejsCreateStringFromAsc(ejs, msg);
    if (argv[0] == 0) {
        assert(argv[0]);
        return 0;
    }
    if (EST(Error)->constructor.body.proc) {
        error = (EjsError*) ejsCreateInstance(ejs, type, 1, argv);
    } else {
        error = ejsCreatePot(ejs, type, 0);
        ejsSetProperty(ejs, error, ES_Error_message, ejsCreateStringFromAsc(ejs, msg));
    }
    return error;
}
Exemple #12
0
void ejsConfigureVoidType(Ejs *ejs)
{
    EjsType     *type;

    type = ejs->voidType;

    ejsSetProperty(ejs, ejs->global, ES_undefined, ejs->undefinedValue);

    ejsBindMethod(ejs, type, ES_Object_get, getVoidIterator);
    ejsBindMethod(ejs, type, ES_Object_getValues, getVoidIterator);
}
Exemple #13
0
PUBLIC int ejsAppendArray(Ejs *ejs, EjsArray *dest, EjsArray *src)
{
    int     next;

    for (next = 0; next < src->length; next++) {
        if (ejsSetProperty(ejs, dest, dest->length, src->data[next]) < 0) {
            return MPR_ERR_MEMORY;
        }
    }
    return 0;
}
Exemple #14
0
/*  
    Get the application command line arguments
    static function get args(): Array
 */
static EjsArray *app_args(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsArray    *args;
    int         i;

    args = ejsCreateArray(ejs, ejs->argc);
    for (i = 0; i < ejs->argc; i++) {
        ejsSetProperty(ejs, args, i, ejsCreateStringFromAsc(ejs, ejs->argv[i]));
    }
    return args;
}
Exemple #15
0
/*
 *  Get the application command line arguments
 *
 *  static function get args(): String
 */
static EjsVar *getArgs(Ejs *ejs, EjsObject *unused, int argc, EjsVar **argv)
{
    EjsArray    *args;
    int         i;

    args = ejsCreateArray(ejs, ejs->argc);
    for (i = 0; i < ejs->argc; i++) {
        ejsSetProperty(ejs, (EjsVar*) args, i, (EjsVar*) ejsCreateString(ejs, ejs->argv[i]));
    }
    return (EjsVar*) args;
}
Exemple #16
0
/*
    function get providers(): Array
 */
static EjsArray *http_providers(Ejs *ejs, EjsHttp *hp, int argc, EjsObj **argv)
{
    EjsArray    *result;
    int         i;

    result = ejsCreateArray(ejs, 0);
    i = 0;
#if BIT_PACK_EST
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "est"));
#endif
#if BIT_PACK_OPENSSL
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "openssl"));
#endif
#if BIT_PACK_MATRIXSSL
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "matrixssl"));
#endif
#if BIT_PACK_MOCANA
    ejsSetProperty(ejs, result, i++, ejsCreateStringFromAsc(ejs, "mocana"));
#endif
    return result;
}
Exemple #17
0
/*
    Delete a property and update the length. Return the index where the property was deleted.
 */
static int deleteArrayProperty(Ejs *ejs, EjsArray *ap, int slot)
{
    if (slot >= ap->length) {
        assert(0);
        return EJS_ERR;
    }
    if (ejsSetProperty(ejs, ap, slot, ESV(undefined)) < 0) {
        return EJS_ERR;
    }
    if ((slot + 1) == ap->length) {
        ap->length--;
    }
    return slot;
}
Exemple #18
0
/*
 *  Delete a property and update the length
 */
static int deleteArrayProperty(Ejs *ejs, EjsArray *ap, int slot)
{
    if (slot >= ap->length) {
        mprAssert(0);
        return EJS_ERR;
    }
    if (ejsSetProperty(ejs, (EjsVar*) ap, slot, (EjsVar*) ejs->undefinedValue) < 0) {
        return EJS_ERR;
    }
    if ((slot + 1) == ap->length) {
        ap->length--;
    }
    return 0;
}
Exemple #19
0
/*
 *  A header object from a given hash table
 */  
static EjsVar *createHeaderObject(Ejs *ejs, MprHashTable *table)
{
    MprHash     *hp;
    EjsVar      *headers, *header;
    EjsName     qname;
    int         index;
    
    headers = (EjsVar*) ejsCreateArray(ejs, mprGetHashCount(table));
    for (index = 0, hp = 0; (hp = mprGetNextHash(table, hp)) != 0; ) {
        header = (EjsVar*) ejsCreateSimpleObject(ejs);
        ejsSetPropertyByName(ejs, header, ejsName(&qname, "", hp->key), (EjsVar*) ejsCreateString(ejs, hp->data));
        ejsSetProperty(ejs, headers, index++, header);
    }
    return headers;
}
Exemple #20
0
static int mixinMethod(Ejs *ep, EjsVar *thisObj, int argc, EjsVar **argv)
{
	EjsProperty	*pp;
	char		*buf;
	int			fid, i, rc;

	mprAssert(argv);

	/*
	 *	Create a variable scope block set to the current object
	 */
	rc = 0;
	fid = ejsSetBlock(ep, thisObj);

	for (i = 0; i < argc; i++) {

		if (ejsVarIsString(argv[i])) {
			rc = ejsEvalScript(ep, argv[i]->string, 0);

		}  else if (ejsVarIsObject(argv[i])) {

			/*	MOB -- OPT. When we have proper scope chains, we should just
			 	refer to the module and not copy */
			pp = ejsGetFirstProperty(argv[i], EJS_ENUM_ALL);
			while (pp) {
				ejsSetProperty(ep, thisObj, pp->name, ejsGetVarPtr(pp));
				pp = ejsGetNextProperty(pp, EJS_ENUM_ALL);
			}

		} else {
			/* MOB - rc */
			buf = ejsVarToString(ep, argv[i]);
			rc = ejsEvalScript(ep, buf, 0);

		}
		if (rc < 0) {
			ejsCloseBlock(ep, fid);
			return -1;
		}
	} 
	ejsCloseBlock(ep, fid);
	return 0;
}
Exemple #21
0
/*
    function exec(str: String, start: Number = 0): Array
 */
static EjsArray *regex_exec(Ejs *ejs, EjsRegExp *rp, int argc, EjsObj **argv)
{
    EjsArray    *results;
    EjsString   *match, *str;
    int         matches[BIT_MAX_REGEX_MATCHES * 3];
    int         count, start, len, i, index;

    str = (EjsString*) argv[0];
    if (argc == 2) {
        start = (int) ejsGetNumber(ejs, argv[1]);
    } else {
        start = rp->endLastMatch;
    }
    rp->matched = 0;
    assert(rp->compiled);
    count = pcre_exec(rp->compiled, NULL, str->value, (int) str->length, start, 0, matches, sizeof(matches) / sizeof(int));
    if (count < 0) {
        rp->endLastMatch = 0;
        return ESV(null);
    }
    results = ejsCreateArray(ejs, count);
    for (index = 0, i = 0; i < count; i++, index += 2) {
        len = matches[index + 1] - matches[index];
        match = ejsCreateString(ejs, &str->value[matches[index]], len);
        ejsSetProperty(ejs, results, i, match);
        if (index == 0) {
            rp->matched = match;
        }
    }
    if (rp->global) {
        /* Only save if global flag used as per spec */
        rp->startLastMatch = matches[0];
        rp->endLastMatch = matches[1];
    }
    return results;
}
Exemple #22
0
/*
 *  Process a message sent from postMessage. This may run inside the worker or outside in the parent depending on the
 *  direction of the message. But it ALWAYS runs in the appropriate thread for the interpreter.
 */
static void doMessage(Message *msg, MprEvent *mprEvent)
{
    Ejs         *ejs;
    EjsVar      *event;
    EjsWorker   *worker;
    EjsFunction *callback;
    EjsVar      *argv[1];

    worker = msg->worker;
    ejs = worker->ejs;

    callback = (EjsFunction*) ejsGetProperty(ejs, (EjsVar*) worker, msg->callbackSlot);

    switch (msg->callbackSlot) {
    case ES_ejs_sys_Worker_onclose:
        event = ejsCreateVar(ejs, ejs->eventType, 0);
        break;
    case ES_ejs_sys_Worker_onerror:
        event = ejsCreateVar(ejs, ejs->errorEventType, 0);
        break;
    case ES_ejs_sys_Worker_onmessage:
        event = ejsCreateVar(ejs, ejs->eventType, 0);
        break;
    default:
        mprAssert(msg->callbackSlot == 0);
        mprFree(mprEvent);
        return;
    }
    if (msg->data) {
        ejsSetProperty(ejs, event, ES_ejs_events_Event_data, (EjsVar*) ejsCreateStringAndFree(ejs, msg->data));
    }
    if (msg->message) {
        ejsSetProperty(ejs, event, ES_ejs_events_ErrorEvent_message, (EjsVar*) ejsCreateStringAndFree(ejs, msg->message));
    }
    if (msg->filename) {
        ejsSetProperty(ejs, event, ES_ejs_events_ErrorEvent_filename, (EjsVar*) ejsCreateStringAndFree(ejs, msg->filename));
        ejsSetProperty(ejs, event, ES_ejs_events_ErrorEvent_lineno, (EjsVar*) ejsCreateNumber(ejs, msg->lineNumber));
    }
    if (msg->stack) {
        ejsSetProperty(ejs, event, ES_ejs_events_ErrorEvent_stack, (EjsVar*) ejsCreateStringAndFree(ejs, msg->stack));
    }

    if (callback == 0 || (EjsVar*) callback == ejs->nullValue) {
        if (msg->callbackSlot == ES_ejs_sys_Worker_onmessage) {
            mprLog(ejs, 1, "Discard message as no onmessage handler defined for worker");
            
        } else if (msg->callbackSlot == ES_ejs_sys_Worker_onerror) {
            ejsThrowError(ejs, "Exception in Worker: %s", ejsGetErrorMsg(worker->pair->ejs, 1));

        } else {
            /* Ignore onclose message */
        }

    } else if (!ejsIsFunction(callback)) {
        ejsThrowTypeError(ejs, "Worker callback %s is not a function", msg->callback);

    } else {
        argv[0] = event;
        ejsRunFunction(ejs, callback, (EjsVar*) worker, 1, argv);
    }

    if (msg->callbackSlot == ES_ejs_sys_Worker_onclose) {
        mprAssert(!worker->inside);
        worker->state = EJS_WORKER_COMPLETE;
        removeWorker(ejs, worker);
        /*
         *  Now that the inside worker is complete, the outside worker does not need to be protected from GC
         */
        worker->obj.var.permanent = 0;
    }
    mprFree(msg);
    mprFree(mprEvent);
}
Exemple #23
0
int ejsDefineObjectClass(Ejs *ep)
{
	EjsMethods	*methods;
	EjsProperty	*objectProp, *protoProp;
	EjsVar		*op, *globalClass;

	/*
	 *	Must specially hand-craft the object class as it is the base class
	 *	of all objects.
	 */
	op = ejsCreateObjVar(ep);
	if (op == 0) {
		return MPR_ERR_CANT_CREATE;
	}
	ejsSetClassName(ep, op, "Object");

	/*
	 *	Don't use a constructor for objects for speed
	 */
	ejsMakeClassNoConstructor(op);

	/*
	 *	MOB -- should mark properties as public / private and class or instance.
	 */
	ejsDefineCMethod(ep, op, "clone", cloneMethod, EJS_NO_LOCAL);
	ejsDefineCMethod(ep, op, "toString", toStringMethod, EJS_NO_LOCAL);
	ejsDefineCMethod(ep, op, "valueOf", valueOfMethod, EJS_NO_LOCAL);
	ejsDefineCMethod(ep, op, "mixin", mixinMethod, EJS_NO_LOCAL);

	ejsDefineCAccessors(ep, op, "hash", hashGetAccessor, 0, EJS_NO_LOCAL);
	ejsDefineCAccessors(ep, op, "baseClass", classGetAccessor, 0, EJS_NO_LOCAL);

	/*
	 *	MOB -- make this an accessor
	 */
	protoProp = ejsSetProperty(ep, op, "prototype", op);
	if (protoProp == 0) {
		ejsFreeVar(ep, op);
		return MPR_ERR_CANT_CREATE;
	}

	/*
	 *	Setup the internal methods. Most classes will never override these.
	 *	The XML class will. We rely on talloc to free internal. Use "ep" as
	 *	the parent as we need "methods" to live while the interpreter lives.
	 */
	methods = mprAllocTypeZeroed(ep, EjsMethods);
	op->objectState->methods = methods;

	methods->createProperty = createObjProperty;
	methods->deleteProperty = deleteObjProperty;
	methods->getProperty = getObjProperty;
	methods->setProperty = setObjProperty;

	objectProp = ejsSetPropertyAndFree(ep, ep->global, "Object", op);

	/*
	 *	Change the global class to use Object's methods 
	 */
	globalClass = ep->service->globalClass;
	globalClass->objectState->methods = methods;
	globalClass->objectState->baseClass = ejsGetVarPtr(protoProp);

	ep->objectClass = ejsGetVarPtr(objectProp);

	if (ejsObjHasErrors(ejsGetVarPtr(objectProp))) {
		ejsFreeVar(ep, op);
		return MPR_ERR_CANT_CREATE;
	}
	return 0;
}
Exemple #24
0
/*
    Parse an object literal string pointed to by js->next into the given buffer. Update js->next to point
    to the next input token in the object literal. Supports nested object literals.
 */
static EjsObj *parseLiteralInner(Ejs *ejs, MprBuf *buf, JsonState *js)
{
    EjsAny      *obj, *vp;
    MprBuf      *valueBuf;
    wchar       *token, *key, *value;
    int         tid, isArray;

    isArray = 0;

    tid = getNextJsonToken(buf, &token, js);
    if (tid == TOK_ERR || tid == TOK_EOF) {
        return 0;
    }
    if (tid == TOK_LBRACKET) {
        isArray = 1;
        obj = (EjsObj*) ejsCreateArray(ejs, 0);
    } else if (tid == TOK_LBRACE) {
        obj = ejsCreateEmptyPot(ejs);
    } else {
        return ejsParse(ejs, token, S_String);
    }
    if (obj == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }
    while (1) {
        vp = 0;
        tid = peekNextJsonToken(js);
        if (tid == TOK_ERR) {
            return 0;
        } else if (tid == TOK_EOF) {
            break;
        } else if (tid == TOK_RBRACE || tid == TOK_RBRACKET) {
            getNextJsonToken(buf, &key, js);
            break;
        }
        if (tid == TOK_LBRACKET) {
            /* For array values */
            vp = parseLiteral(ejs, js);
            assert(vp);
            
        } else if (tid == TOK_LBRACE) {
            /* For object values */
            vp = parseLiteral(ejs, js);
            assert(vp);
            
        } else if (isArray) {
            tid = getNextJsonToken(buf, &value, js);
            vp = ejsParse(ejs, value, (tid == TOK_QID) ? S_String: -1);
            assert(vp);
            
        } else {
            getNextJsonToken(buf, &key, js);
            tid = peekNextJsonToken(js);
            if (tid == TOK_ERR) {
                return 0;
            } else if (tid == TOK_EOF) {
                break;
            } else if (tid == TOK_LBRACE || tid == TOK_LBRACKET) {
                vp = parseLiteral(ejs, js);

            } else if (tid == TOK_ID || tid == TOK_QID) {
                valueBuf = mprCreateBuf(0, 0);
                getNextJsonToken(valueBuf, &value, js);
                if (tid == TOK_QID) {
                    vp = ejsCreateString(ejs, value, strlen(value));
                } else {
                    if (mcmp(value, "null") == 0) {
                        vp = ESV(null);
                    } else if (mcmp(value, "undefined") == 0) {
                        vp = ESV(undefined);
                    } else {
                        vp = ejsParse(ejs, value, -1);
                    }
                }
                assert(vp);
            } else {
                getNextJsonToken(buf, &value, js);
                js->error = js->next;
                return 0;
            }
        }
        if (vp == 0) {
            js->error = js->next;
            return 0;
        }
        if (isArray) {
            if (ejsSetProperty(ejs, obj, -1, vp) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
        } else {
            if (ejsSetPropertyByName(ejs, obj, WEN(key), vp) < 0) {
                ejsThrowMemoryError(ejs);
                return 0;
            }
        }
    }
    return obj;
}
Exemple #25
0
/*
    Process a message sent from postMessage. This may run inside the worker or outside in the parent depending on the
    direction of the message. But it ALWAYS runs in the appropriate thread for the interpreter.
 */
static int doMessage(Message *msg, MprEvent *mprEvent)
{
    Ejs         *ejs;
    EjsObj      *event, *frame;
    EjsWorker   *worker;
    EjsFunction *callback;
    EjsObj      *argv[1];

    worker = msg->worker;
    worker->gotMessage = 1;
    ejs = worker->ejs;
    assert(!ejs->exception);

    event = 0;
    ejsBlockGC(ejs);

    callback = ejsGetProperty(ejs, worker, msg->callbackSlot);

    switch (msg->callbackSlot) {
    case ES_Worker_onerror:
        event = ejsCreateObj(ejs, ESV(ErrorEvent), 0);
        break;
            
    case ES_Worker_onclose:
    case ES_Worker_onmessage:
        event = ejsCreateObj(ejs, ESV(Event), 0);
        break;
            
    default:
        assert(msg->callbackSlot == 0);
        return 0;
    }
    worker->event = event;
    if (msg->data) {
        ejsSetProperty(ejs, event, ES_Event_data, ejsCreateStringFromAsc(ejs, msg->data));
    }
    if (msg->message) {
        ejsSetProperty(ejs, event, ES_ErrorEvent_message, msg->message);
    }
    if (msg->stack) {
        ejsSetProperty(ejs, event, ES_ErrorEvent_stack, msg->stack);
        if ((frame = ejsGetProperty(ejs, msg->stack, 0)) != 0 && !ejsIs(ejs, frame, Void)) {
            ejsSetProperty(ejs, event, ES_ErrorEvent_filename, ejsGetPropertyByName(ejs, frame, EN("filename")));
            ejsSetProperty(ejs, event, ES_ErrorEvent_lineno, ejsGetPropertyByName(ejs, frame, EN("lineno")));
        }
    }
    assert(!ejs->exception);

    if (callback == 0 || ejsIs(ejs, callback, Null)) {
        if (msg->callbackSlot == ES_Worker_onmessage) {
            mprTrace(6, "Discard message as no onmessage handler defined for worker");
            
        } else if (msg->callbackSlot == ES_Worker_onerror) {
            if (ejsIs(ejs, msg->message, String)) {
                ejsThrowError(ejs, "Exception in Worker: %@", ejsToString(ejs, msg->message));
            } else {
                ejsThrowError(ejs, "Exception in Worker: %s", ejsGetErrorMsg(worker->pair->ejs, 1));
            }
        } else {
            /* Ignore onclose message */
        }

    } else if (!ejsIsFunction(ejs, callback)) {
        ejsThrowTypeError(ejs, "Worker callback %s is not a function", msg->callback);

    } else {
        assert(!ejs->exception);
        argv[0] = event;
        ejsRunFunction(ejs, callback, worker, 1, argv);
    }
    if (msg->callbackSlot == ES_Worker_onclose) {
        assert(!worker->inside);
        worker->state = EJS_WORKER_COMPLETE;
        mprTrace(5, "Worker.doMessage: complete");
        /* Worker and insider interpreter are now eligible for garbage collection */
        removeWorker(worker);
    }
    mprSignalDispatcher(ejs->dispatcher);
    worker->event = 0;
    return 0;
}
Exemple #26
0
static EjsWorker *initWorker(Ejs *ejs, EjsWorker *worker, Ejs *baseVM, cchar *name, EjsArray *search, cchar *scriptFile)
{
    Ejs             *wejs;
    EjsWorker       *self;
    EjsName         sname;
    static int      workerSeqno = 0;

    ejsBlockGC(ejs);
    if (worker == 0) {
        worker = ejsCreateWorker(ejs);
    }
    worker->ejs = ejs;
    worker->state = EJS_WORKER_BEGIN;

    if (name) {
        worker->name = sclone(name);
    } else {
        lock(ejs);
        worker->name = sfmt("worker-%d", workerSeqno++);
        unlock(ejs);
    }
    /*
        Create a new interpreter and an "inside" worker object and pair it with the current "outside" worker.
        The worker interpreter gets a new dispatcher
     */
    if (baseVM) {
        if ((wejs = ejsCloneVM(baseVM)) == 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
    } else {
        if ((wejs = ejsCreateVM(0, 0, ejs->flags)) == 0) {
            ejsThrowMemoryError(ejs);
            return 0;
        }
        if (ejsLoadModules(wejs, 0, 0) < 0) {
            return 0;
        }
    }
    worker->pair = self = ejsCreateWorker(wejs);
    self->state = EJS_WORKER_BEGIN;
    self->ejs = wejs;
    self->inside = 1;
    self->pair = worker;
    self->name = sjoin("inside-", worker->name, NULL);
#if MOB
    mprEnableDispatcher(wejs->dispatcher);
#endif
    if (search) {
        ejsSetSearchPath(ejs, (EjsArray*) search);
    }

    //  TODO - these should be don't delete
    ejsSetProperty(ejs, worker, ES_Worker_name, ejsCreateStringFromAsc(ejs, self->name));
    ejsSetProperty(wejs, self,  ES_Worker_name, ejsCreateStringFromAsc(wejs, self->name));

    sname = ejsName(wejs, EJS_WORKER_NAMESPACE, "self");
    ejsSetPropertyByName(wejs, wejs->global, sname, self);

    /*
        Workers have a dedicated namespace to enable viewing of the worker globals (self, onmessage, postMessage...)
     */
    ejsDefineReservedNamespace(wejs, wejs->global, NULL, EJS_WORKER_NAMESPACE);
    
    addWorker(ejs, worker);

    if (scriptFile) {
        worker->scriptFile = sclone(scriptFile);
        worker->state = EJS_WORKER_STARTED;
        if (mprCreateEvent(wejs->dispatcher, "workerMain", 0, (MprEventProc) workerMain, self, 0) < 0) {
            mprRemoveItem(ejs->workers, worker);
            ejsThrowStateError(ejs, "Cannot create worker event");
            return 0;
        }
    }
    return worker;
}
Exemple #27
0
/*
 *  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;
}
Exemple #28
0
/*
 *  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;
}