Beispiel #1
0
static EjsVar *coerceVoidOperands(Ejs *ejs, EjsVoid *lhs, int opcode, EjsVoid *rhs)
{
    switch (opcode) {

    case EJS_OP_ADD:
        if (!ejsIsNumber(rhs)) {
            return ejsInvokeOperator(ejs, (EjsVar*) ejsToString(ejs, lhs), opcode, rhs);
        }
        /* Fall through */

    case EJS_OP_AND: case EJS_OP_DIV: case EJS_OP_MUL: case EJS_OP_OR: case EJS_OP_REM:
    case EJS_OP_SHL: case EJS_OP_SHR: case EJS_OP_SUB: case EJS_OP_USHR: case EJS_OP_XOR:
        return ejsInvokeOperator(ejs, (EjsVar*) ejs->nanValue, opcode, rhs);

    /*
     *  Comparision
     */
    case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_LT:
    case EJS_OP_COMPARE_GE: case EJS_OP_COMPARE_GT:
        return (EjsVar*) ejs->falseValue;

    case EJS_OP_COMPARE_NE:
    case EJS_OP_COMPARE_STRICTLY_NE:
        if (ejsIsNull(rhs)) {
            return (EjsVar*) ejs->falseValue;
        }
        return (EjsVar*) ejs->trueValue;


    case EJS_OP_COMPARE_EQ:
    case EJS_OP_COMPARE_STRICTLY_EQ:
        if (ejsIsNull(rhs)) {
            return (EjsVar*) ejs->trueValue;
        }
        return (EjsVar*) ejs->falseValue;

    /*
     *  Unary operators
     */
    case EJS_OP_LOGICAL_NOT: case EJS_OP_NOT: case EJS_OP_NEG:
        return 0;

    case EJS_OP_COMPARE_UNDEFINED:
    case EJS_OP_COMPARE_NOT_ZERO:
    case EJS_OP_COMPARE_NULL:
        return (EjsVar*) ejs->trueValue;

    case EJS_OP_COMPARE_FALSE:
    case EJS_OP_COMPARE_TRUE:
    case EJS_OP_COMPARE_ZERO:
        return (EjsVar*) ejs->falseValue;

    default:
        ejsThrowTypeError(ejs, "Opcode %d not valid for type %s", opcode, lhs->type->qname.name);
        return ejs->undefinedValue;
    }
    return 0;
}
Beispiel #2
0
static void setupTrace(Ejs *ejs, HttpTrace *trace, int dir, EjsObj *options)
{
    EjsArray    *extensions;
    EjsObj      *ext;
    HttpTrace   *tp;
    int         i, level, *levels;

    tp = &trace[dir];
    levels = tp->levels;
    if ((level = getNumOption(ejs, options, "all")) >= 0) {
        for (i = 0; i < HTTP_TRACE_MAX_ITEM; i++) {
            levels[i] = level;
        }
    } else {
        levels[HTTP_TRACE_CONN] = getNumOption(ejs, options, "conn");
        levels[HTTP_TRACE_FIRST] = getNumOption(ejs, options, "first");
        levels[HTTP_TRACE_HEADER] = getNumOption(ejs, options, "headers");
        levels[HTTP_TRACE_BODY] = getNumOption(ejs, options, "body");
    }
    tp->size = getNumOption(ejs, options, "size");
    if ((extensions = (EjsArray*) ejsGetPropertyByName(ejs, options, EN("include"))) != 0) {
        if (!ejsIs(ejs, extensions, Array)) {
            ejsThrowArgError(ejs, "include is not an array");
            return;
        }
        tp->include = mprCreateHash(0, 0);
        for (i = 0; i < extensions->length; i++) {
            if ((ext = ejsGetProperty(ejs, extensions, i)) != 0) {
                mprAddKey(tp->include, ejsToMulti(ejs, ejsToString(ejs, ext)), "");
            }
        }
    }
    if ((extensions = (EjsArray*) ejsGetPropertyByName(ejs, options, EN("exclude"))) != 0) {
        if (!ejsIs(ejs, extensions, Array)) {
            ejsThrowArgError(ejs, "exclude is not an array");
            return;
        }
        tp->exclude = mprCreateHash(0, 0);
        for (i = 0; i < extensions->length; i++) {
            if ((ext = ejsGetProperty(ejs, extensions, i)) != 0) {
                mprAddKey(tp->exclude, ejsToMulti(ejs, ejsToString(ejs, ext)), MPR->emptyString);
            }
        }
    }
}
Beispiel #3
0
/*
 *  Interpret from the console or from a literal command
 */
static int interpretCommands(EcCompiler *cp, cchar *cmd)
{
    Ejs         *ejs;
    EjsString   *result;
    char        *tmpArgv[1];
    int         err;

    ejs = cp->ejs;

    if (ecOpenConsoleStream(cp->lexer, (cmd) ? commandGets: consoleGets) < 0) {
        mprError(cp, "Can't open input");
        return EJS_ERR;
    }
    if (cmd) {
        cp->lexer->input->stream->buf = mprStrdup(cp, cmd);
    } else {
        cp->interactive = 1;
    }
    cp->input = cp->lexer->input;
    cp->token = cp->lexer->input->token;

    ecResetInput(cp);
    tmpArgv[0] = EC_INPUT_STREAM;

    while (!cp->lexer->input->stream->eof) {
        err = 0;
        cp->uid = 0;
        if (ecCompile(cp, 1, tmpArgv, 0) < 0) {
            ejs->result = ejs->undefinedValue;
            err++;
        }
        if (cp->run && !err && cp->errorCount == 0) {
            if (ejsRun(ejs) < 0) {
                ejsReportError(ejs, "Error in script");
            }
        }
        if (!ejs->exception && ejs->result != ejs->undefinedValue) {
            if (ejs->result->primitive || ejsIsDate(ejs->result)) {
                if ((result = (EjsString*) ejsToString(ejs, ejs->result)) != 0) {
                    mprPrintf(cp, "%s\n", result->value);
                }
            } else {
                if ((result = (EjsString*) ejsToJson(ejs, ejs->result)) != 0) {
                    mprPrintf(cp, "%s\n", result->value);
                }
            }
        }
        ecResetInput(cp);
        cp->errorCount = 0;
        err = 0;
    }
    ecCloseStream(cp->lexer);

    return 0;
}
Beispiel #4
0
/*  
    Write data to the file
    function write(data: Object): Number
 */
PUBLIC EjsObj *writeFile(Ejs *ejs, EjsFile *fp, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *ap;
    EjsObj          *vp;
    EjsString       *str;
    cchar           *buf;
    ssize           len, written;
    int             i;

    assert(argc == 1 && ejsIs(ejs, argv[0], Array));

    args = (EjsArray*) argv[0];

    if (!(fp->mode & EJS_FILE_WRITE)) {
        ejsThrowStateError(ejs, "File not opened for writing");
        return 0;
    }
    written = 0;

    for (i = 0; i < args->length; i++) {
        vp = ejsGetProperty(ejs, (EjsObj*) args, i);
        assert(vp);
        switch (TYPE(vp)->sid) {
        case S_ByteArray:
            ap = (EjsByteArray*) vp;
            //  TODO UNICODE ENCODING
            buf = (cchar*) &ap->value[ap->readPosition];
            len = ap->writePosition - ap->readPosition;
            break;

        case S_String: // UNICODE
#if UNICODE && FUTURE
            buf = awtom(((EjsString*) vp)->value, &len);
#else
            buf = ((EjsString*) vp)->value;
            len = ((EjsString*) vp)->length;
#endif
            break;

        default:
            str = ejsToString(ejs, vp);
            buf = awtom(((EjsString*) str)->value, &len);
            break;
        }
        if (mprWriteFile(fp->file, buf, len) != len) {
            ejsThrowIOError(ejs, "Cannot write to %s", fp->path);
            return 0;
        }
        written += len;
        /* Use GC to free buf as it may not be allocated */
    }
    return (EjsObj*) ejsCreateNumber(ejs, (MprNumber) written);
}
Beispiel #5
0
static EjsRegExp *regex_Constructor(Ejs *ejs, EjsRegExp *rp, int argc, EjsObj **argv)
{
    cchar       *errMsg;
    int         column, errCode;

    rp->pattern = wclone(ejsToString(ejs, argv[0])->value);
    rp->options = PCRE_JAVASCRIPT_COMPAT;

    if (argc == 2) {
        rp->options |= parseFlags(rp, ejsToString(ejs, argv[1])->value);
    }
    if (rp->compiled) {
        free(rp->compiled);
    }
    if ((rp->compiled = pcre_compile2(rp->pattern, rp->options, &errCode, &errMsg, &column, NULL)) == 0) {
        ejsThrowArgError(ejs, "Cannot compile regular expression '%s'. Error %s at column %d", rp->pattern, errMsg, column);
        return 0;
    }
    return rp;
}
Beispiel #6
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;
}
Beispiel #7
0
static EjsString *joinArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsString       *sep, *sp;
    MprBuf          *buf;
    ssize           len;
    int             i, nonString;

    sep = (argc == 1) ? (EjsString*) argv[0] : NULL;
    if (sep == ESV(empty) && ap->length == 1 && ejsIs(ejs, ap->data[0], String)) {
        /* Optimized path for joining [string]. This happens frequently with fun(...args) */
        return (EjsString*) ap->data[0];
    }
    /*
        Get an estimate of the string length
     */
    len = 0;
    nonString = 0;
    for (i = 0; i < ap->length; i++) {
        sp = (EjsString*) ap->data[i];
        if (!ejsIs(ejs, sp, String)) {
            nonString = 1;
            continue;
        }
        len += sp->length;
    }
    if (sep) {
        len += (ap->length * sep->length);
    }
    if (nonString) {
        len += ME_MAX_BUFFER;
    }
    buf = mprCreateBuf(len + 1, -1);

    for (i = 0; i < ap->length; i++) {
        sp = (EjsString*) ap->data[i];
        if (!ejsIsDefined(ejs, sp)) {
            continue;
        }
        sp = ejsToString(ejs, sp);
        if (!ejsIsDefined(ejs, sp)) {
            continue;
        }
        if (i > 0 && sep) {
            mprPutBlockToBuf(buf, sep->value, sep->length);
        }
        mprPutBlockToBuf(buf, sp->value, sp->length);
    }
    mprAddNullToBuf(buf);
    return ejsCreateStringFromBytes(ejs, mprGetBufStart(buf), mprGetBufLength(buf));
}
Beispiel #8
0
/*
    function emit(level: Number, ...data): Number
 */
static EjsNumber *lf_emit(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    EjsArray        *args;
    EjsByteArray    *ap;
    EjsObj          *vp;
    EjsString       *str;
    char            *msg, *arg;
    ssize           len, written;
    int             i, level, paused;

    assure(argc >= 2 && ejsIs(ejs, argv[1], Array));

    level = ejsGetInt(ejs, argv[0]);
    args = (EjsArray*) argv[1];
    written = 0;
    msg = 0;
    paused = ejsBlockGC(ejs);

    for (i = 0; i < args->length; i++) {
        vp = ejsGetProperty(ejs, args, i);
        assure(vp);
        switch (TYPE(vp)->sid) {
        case S_ByteArray:
            ap = (EjsByteArray*) vp;
            //  TODO ENCODING
            arg = (char*) &ap->value[ap->readPosition];
            len = ap->writePosition - ap->readPosition;
            break;

        case S_String:
            //  MOB - use NULL instead of &len
            arg = awtom(((EjsString*) vp)->value, &len);
            break;

        default:
            str = ejsToString(ejs, vp);
            //  MOB - use NULL instead of &len
            arg = awtom(((EjsString*) str)->value, &len);
            break;
        }
        msg = srejoin(msg, arg, NULL);
    }
    if (msg) {
        mprRawLog(level, "%s", msg);
        written += slen(msg);
    }
    ejsUnblockGC(ejs, paused);
    return ejsCreateNumber(ejs, (MprNumber) slen(msg));
}
Beispiel #9
0
/*  
    Interpret from the console or from a literal command
 */
static int interpretCommands(EcCompiler *cp, cchar *cmd)
{
    Ejs         *ejs;
    EjsString   *result;
    char        *tmpArgv[1];
    int         err;

    ejs = cp->ejs;
    cp->interactive = 1;

    if (ecOpenConsoleStream(cp, (cmd) ? commandGets: consoleGets, cmd) < 0) {
        mprError("Cannot open input");
        return EJS_ERR;
    }
    tmpArgv[0] = EC_INPUT_STREAM;

    while (!cp->stream->eof && !mprIsStopping()) {
        err = 0;
        cp->uid = 0;
        ejs->result = ESV(undefined);
        if (ecCompile(cp, 1, tmpArgv) < 0) {
            mprRawLog(0, "%s", cp->errorMsg);
            ejs->result = ESV(undefined);
            err++;
        }
        if (!err && cp->errorCount == 0) {
            if (ejsRunProgram(ejs, NULL, NULL) < 0) {
                ejsReportError(ejs, "Error in script");
            }
        }
        if (!ejs->exception && ejs->result != ESV(undefined)) {
            if (ejsIs(ejs, ejs->result, Date) /* MOB || ejsIsType(ejs, ejs->result) */) {
                if ((result = (EjsString*) ejsToString(ejs, ejs->result)) != 0) {
                    mprPrintf("%@\n", result);
                }
            } else if (ejs->result != ESV(null)) {
                if ((result = (EjsString*) ejsSerialize(ejs, ejs->result, EJS_JSON_SHOW_PRETTY)) != 0) {
                    mprPrintf("%@\n", result);
                }
            }
        }
        ecResetInput(cp);
        cp->errorCount = 0;
        cp->fatalError = 0;
    }
    ecCloseStream(cp);
    return 0;
}
Beispiel #10
0
/*  
    Prepare form data as a series of key-value pairs. Data is formatted according to www-url-encoded specs by 
    mprSetHttpFormData. Objects are flattened into a one level key/value pairs. Keys can have embedded "." separators.
    E.g.  name=value&address=77%20Park%20Lane
 */
static void prepForm(Ejs *ejs, EjsHttp *hp, cchar *prefix, EjsObj *data)
{
    EjsName     qname;
    EjsObj      *vp;
    EjsString   *value;
    cchar       *key, *sep, *vstr;
    char        *encodedKey, *encodedValue, *newPrefix, *newKey;
    int         i, count;

    count = ejsGetLength(ejs, data);
    for (i = 0; i < count; i++) {
        if (ejsIs(ejs, data, Array)) {
            key = itos(i);
        } else {
            qname = ejsGetPropertyName(ejs, data, i);
            key = ejsToMulti(ejs, qname.name);
        }
        vp = ejsGetProperty(ejs, data, i);
        if (vp == 0) {
            continue;
        }
        if (ejsGetLength(ejs, vp) > 0) {
            if (prefix) {
                newPrefix = sfmt("%s.%s", prefix, key);
                prepForm(ejs, hp, newPrefix, vp);
            } else {
                prepForm(ejs, hp, key, vp);
            }
        } else {
            value = ejsToString(ejs, vp);
            sep = (mprGetBufLength(hp->requestContent) > 0) ? "&" : "";
            if (prefix) {
                newKey = sjoin(prefix, ".", key, NULL);
                encodedKey = mprUriEncode(newKey, MPR_ENCODE_URI_COMPONENT); 
            } else {
                encodedKey = mprUriEncode(key, MPR_ENCODE_URI_COMPONENT);
            }
            vstr = ejsToMulti(ejs, value);
            encodedValue = mprUriEncode(vstr, MPR_ENCODE_URI_COMPONENT);
            mprPutToBuf(hp->requestContent, "%s%s=%s", sep, encodedKey, encodedValue);
        }
    }
}
Beispiel #11
0
static cchar *getStrOption(Ejs *ejs, EjsObj *options, cchar *field, cchar *defaultValue, bool optional)
{
    EjsObj      *vp;
    EjsString   *str;

    vp = ejsGetPropertyByName(ejs, options, EN(field));
    if (vp == 0) {
        if (optional) {
            return sclone(defaultValue);
        }
        ejsThrowArgError(ejs, "Required option %s is missing", field);
        return 0;
    }
    str = ejsToString(ejs, vp);
    if (!ejsIs(ejs, str, String)) {
        ejsThrowArgError(ejs, "Bad option type for field \"%s\"", field);
        return 0;
    }
    return ejsToMulti(ejs, str);
}
Beispiel #12
0
/*  
    Exit the application
    static function exit(status: Number, how: String = "immediate"): void
    TODO - status is not implemented
 */
static EjsObj *app_exit(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv)
{
    MprTicks    timeout;
    cchar       *how;
    int         status, mode;

    if (ejs->dontExit) {
        ejsThrowStateError(ejs, "App.exit has been disabled");
        return 0;
    }
    status = argc >= 1 ? ejsGetInt(ejs, argv[0]) : 0;
    timeout = argc >= 2 ? ejsGetInt(ejs, argv[1]) : 0;
    how = ejsToMulti(ejs, argc >= 2 ? ejsToString(ejs, argv[1]): ESV(empty));

    if (scmp(how, "normal") == 0) {
        mode = 0;
    } else if (scmp(how, "abort") == 0) {
        mode = MPR_EXIT_ABORT;
    } else if (scmp(how, "safe") == 0) {
        mode = MPR_EXIT_SAFE;
    } else if (scmp(how, "restart") == 0) {
        mode = MPR_EXIT_RESTART;
#if DEPRECATED || 1
    } else if (scmp(how, "immediate") == 0) {
        mode = 0;
    } else if (scmp(how, "graceful") == 0) {
        mode = 0;
        if (argc <= 2) {
            timeout = 30 * 3000;
        }
    } else if (scmp(how, "default") == 0) {
        mode = 0;
#endif
    } else {
        mode = 0;
    }
    mprShutdown(mode, status, timeout);
    ejsAttention(ejs);
    return 0;
}
Beispiel #13
0
/*
    Convert to a JSON string

    override function toJSON(): String
 */
static EjsString *xmlToJson(Ejs *ejs, EjsObj *vp, int argc, EjsObj **argv)
{
    EjsString       *sp;
    MprBuf          *buf;
    cchar           *cp;

    /*
        Quote all quotes
     */
    sp = ejsToString(ejs, vp);
    buf = mprCreateBuf(-1, -1);
    mprPutCharToBuf(buf, '"');
    for (cp = ejsToMulti(ejs, sp); *cp; cp++) {
        if (*cp == '"') {
            mprPutCharToBuf(buf, '\\');
        }
        mprPutCharToBuf(buf, (uchar) *cp);
    }
    mprPutCharToBuf(buf, '"');
    mprAddNullToBuf(buf);
    return ejsCreateStringFromAsc(ejs, mprGetBufStart(buf));
}
Beispiel #14
0
/*
 *  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);
}
Beispiel #15
0
/* UNUSED */
static EjsString *joinArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsString       *result, *sep;
    EjsObj          *vp;
    int             i;

    sep = (argc == 1) ? (EjsString*) argv[0] : NULL;
    if (sep == ESV(empty) && ap->length == 1 && ejsIs(ejs, ap->data[0], String)) {
        /* Optimized path for joining [string]. This happens frequently with fun(...args) */
        return (EjsString*) ap->data[0];
    }
    result = ESV(empty);
    for (i = 0; i < ap->length; i++) {
        vp = ap->data[i];
        if (!ejsIsDefined(ejs, vp)) {
            continue;
        }
        if (i > 0 && sep) {
            result = ejsJoinString(ejs, result, sep);
        }
        result = ejsJoinString(ejs, result, ejsToString(ejs, vp));
    }
    return result;
}
Beispiel #16
0
/*
    Convert an arg to a URI. Can handle strings, paths, URIs and object hashes. Will cast all else to strings and then
    parse.
 */
static EjsUri *castToUri(Ejs *ejs, EjsObj *arg)
{
    EjsUri  *up;

    up = ejsCreateObj(ejs, ESV(Uri), 0);
    if (ejsIs(ejs, arg, String)) {
        up->uri = httpCreateUri(up, ejsToMulti(ejs, arg), 0);

    } else if (ejsIs(ejs, arg, Uri)) {
        up->uri = httpCloneUri(((EjsUri*) arg)->uri, 0);

    } else if (ejsIs(ejs, arg, Path)) {
        ustr = ((EjsPath*) arg)->path;
        up->uri = httpCreateUri(up, ustr, 0);

    } else if (ejsGetLength(ejs, arg) > 0) {
        up->uri = createHttpUriFromHash(ejs, up, arg, 0);

    } else {
        arg = (EjsObj) ejsToString(ejs, arg);
        up->uri = httpCreateUri(up, ejsToMulti(ejs, arg), 0);
    }
    return up;
}
Beispiel #17
0
/*
    function listen(endpoint): Void

    An endpoint can be either a "port" or "ip:port", or null. If hosted, this call does little -- just add to the
    ejs->httpServers list.
 */
static EjsVoid *hs_listen(Ejs *ejs, EjsHttpServer *sp, int argc, EjsObj **argv)
{
    HttpEndpoint    *endpoint;
    HttpHost        *host;
    HttpRoute       *route;
    EjsString       *address;
    EjsObj          *loc;
    EjsPath         *documents;

    if (!sp->hosted) {
        loc = (argc >= 1) ? argv[0] : ESV(null);
        if (loc != ESV(null)) {
            address = ejsToString(ejs, loc);
            //  TODO should permit https://IP:PORT
            mprParseSocketAddress(address->value, &sp->ip, &sp->port, NULL, 0);
        } else {
            address = 0;
        }
        if (address == 0) {
            ejsThrowArgError(ejs, "Missing listen endpoint");
            return 0;
        }
        if (sp->endpoint) {
            httpDestroyEndpoint(sp->endpoint);
            sp->endpoint = 0;
        }
        /*
            The endpoint uses the ejsDispatcher. This is VERY important. All connections will inherit this also.
            This serializes all activity on one dispatcher.
         */
        if ((endpoint = httpCreateEndpoint(sp->ip, sp->port, ejs->dispatcher)) == 0) {
            ejsThrowIOError(ejs, "Cannot create Http endpoint object");
            return 0;
        }
        sp->endpoint = endpoint;
        host = httpCreateHost(NULL);
        httpSetHostName(host, sfmt("%s:%d", sp->ip, sp->port));
        route = httpCreateConfiguredRoute(host, 1);

        httpAddRouteMethods(route, "DELETE, HEAD, OPTIONS, PUT");
        httpAddRouteHandler(route, "ejsHandler", "");
        httpSetRouteTarget(route, "run", 0);
        httpFinalizeRoute(route);

        httpSetHostDefaultRoute(host, route);
        httpAddHostToEndpoint(endpoint, host);

        if (sp->limits) {
            ejsSetHttpLimits(ejs, endpoint->limits, sp->limits, 1);
        }
        if (sp->incomingStages || sp->outgoingStages || sp->connector) {
            setHttpPipeline(ejs, sp);
        }
        if (sp->ssl) {
            httpSecureEndpoint(endpoint, sp->ssl);
        }
        if (sp->name) {
            httpSetHostName(host, sp->name);
        }
        httpSetSoftware(EJS_HTTPSERVER_NAME);
        httpSetEndpointAsync(endpoint, sp->async);
        httpSetEndpointContext(endpoint, sp);
        httpSetEndpointNotifier(endpoint, stateChangeNotifier);

        /*
            This is only required when http is using non-ejs handlers and/or filters
         */
        documents = ejsGetProperty(ejs, sp, ES_ejs_web_HttpServer_documents);
        if (ejsIs(ejs, documents, Path)) {
            httpSetRouteDocuments(route, documents->value);
        }
#if KEEP
        //  TODO -- what to do with home?
        //  TODO - if removed, then the "home" property should be removed?
        home = ejsGetProperty(ejs, sp, ES_ejs_web_HttpServer_home);
        if (ejsIs(ejs, home, Path)) {
            httpSetRoutDir(host, home->value);
        }
#endif
        if (httpStartEndpoint(endpoint) < 0) {
            httpDestroyEndpoint(sp->endpoint);
            sp->endpoint = 0;
            ejsThrowIOError(ejs, "Cannot listen on %s", address->value);
        }
    }
    if (ejs->httpServers == 0) {
        ejs->httpServers = mprCreateList(-1, MPR_LIST_STATIC_VALUES);
    }
    /* Remove to make sure old listening() registrations are removed */
    mprRemoveItem(ejs->httpServers, sp);
    mprAddItem(ejs->httpServers, sp);
    return 0;
}
Beispiel #18
0
static EjsString *serialize(Ejs *ejs, EjsAny *vp, Json *json)
{
    EjsName     qname;
    EjsFunction *fn;
    EjsString   *result, *sv;
    EjsTrait    *trait;
    EjsObj      *pp, *obj, *replacerArgs[2];
    wchar       *cp;
    cchar       *key;
    int         c, isArray, i, count, slotNum, quotes;

    /*
        The main code below can handle Arrays, Objects, objects derrived from Object and also native classes with properties.
        All others just use toString.
     */
    count = ejsIsPot(ejs, vp) ? ejsGetLength(ejs, vp) : 0;
    if (count == 0 && TYPE(vp) != ESV(Object) && TYPE(vp) != ESV(Array)) {
        //  OPT - need some flag for this test.
        if (!ejsIsDefined(ejs, vp) || ejsIs(ejs, vp, Boolean) || ejsIs(ejs, vp, Number)) {
            return ejsToString(ejs, vp);
        } else if (json->regexp) {
            return ejsToString(ejs, vp);
        } else {
            return ejsToLiteralString(ejs, vp);
        }
    }
    obj = vp;
    json->nest++;
    if (json->buf == 0) {
        json->buf = mprCreateBuf(0, 0);
        mprAddRoot(json->buf);
    }
    isArray = ejsIs(ejs, vp, Array);
    mprPutCharToWideBuf(json->buf, isArray ? '[' : '{');
    if (json->pretty) {
        mprPutCharToWideBuf(json->buf, '\n');
    }
    if (++ejs->serializeDepth <= json->depth && !VISITED(obj)) {
        SET_VISITED(obj, 1);
        for (slotNum = 0; slotNum < count && !ejs->exception; slotNum++) {
            trait = ejsGetPropertyTraits(ejs, obj, slotNum);
            if (trait && (trait->attributes & (EJS_TRAIT_HIDDEN | EJS_TRAIT_DELETED | EJS_FUN_INITIALIZER | 
                    EJS_FUN_MODULE_INITIALIZER)) && !json->hidden) {
                continue;
            }
            pp = ejsGetProperty(ejs, obj, slotNum);
            if (ejs->exception) {
                SET_VISITED(obj, 0);
                json->nest--;
                return 0;
            }
            if (pp == 0) {
                continue;
            }
            if (isArray) {
                key = itos(slotNum);
                qname.name = ejsCreateStringFromAsc(ejs, key);
                qname.space = ESV(empty);
            } else {
                qname = ejsGetPropertyName(ejs, vp, slotNum);
            }

            quotes = json->quotes;
            if (!quotes) {
                //  UNICODE
                for (cp = qname.name->value; cp < &qname.name->value[qname.name->length]; cp++) {
                    if (!isalnum((uchar) *cp) && *cp != '_') {
                        quotes = 1;
                        break;
                    }
                }
            }
            if (json->pretty) {
                for (i = 0; i < ejs->serializeDepth; i++) {
                    mprPutStringToWideBuf(json->buf, json->indent);
                }
            }
            if (!isArray) {
                if (json->namespaces) {
                    if (qname.space != ESV(empty)) {
                        mprPutToBuf(json->buf, "\"%@\"::", qname.space);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                for (cp = qname.name->value; cp && *cp; cp++) {
                    c = *cp;
                    if (c == '"' || c == '\\') {
                        mprPutCharToWideBuf(json->buf, '\\');
                        mprPutCharToWideBuf(json->buf, c);
                    } else {
                        mprPutCharToWideBuf(json->buf, c);
                    }
                }
                if (quotes) {
                    mprPutCharToWideBuf(json->buf, '"');
                }
                mprPutCharToWideBuf(json->buf, ':');
                if (json->pretty) {
                    mprPutCharToWideBuf(json->buf, ' ');
                }
            }
            fn = (EjsFunction*) ejsGetPropertyByName(ejs, TYPE(pp)->prototype, N(NULL, "toJSON"));
            // OPT - check that this is going directly to serialize most of the time
            if (!ejsIsFunction(ejs, fn) || (fn->isNativeProc && fn->body.proc == (EjsProc) ejsObjToJSON)) {
                sv = serialize(ejs, pp, json);
            } else {
                sv = (EjsString*) ejsRunFunction(ejs, fn, pp, 1, &json->options);
            }
            if (sv == 0 || !ejsIs(ejs, sv, String)) {
                if (ejs->exception) {
                    ejsThrowTypeError(ejs, "Cannot serialize property %@", qname.name);
                    SET_VISITED(obj, 0);
                    return 0;
                }
            } else {
                if (json->replacer) {
                    replacerArgs[0] = (EjsObj*) qname.name; 
                    replacerArgs[1] = (EjsObj*) sv; 

                    /* function replacer(key: String, value: String): String */
                    sv = ejsRunFunction(ejs, json->replacer, obj, 2, (EjsObj**) replacerArgs);
                }
                mprPutBlockToBuf(json->buf, sv->value, sv->length * sizeof(wchar));
            }
            if ((slotNum + 1) < count || json->commas) {
                mprPutCharToWideBuf(json->buf, ',');
            }
            if (json->pretty) {
                mprPutCharToWideBuf(json->buf, '\n');
            }
        }
        SET_VISITED(obj, 0);
    }
    --ejs->serializeDepth; 
    if (json->pretty) {
        for (i = ejs->serializeDepth; i > 0; i--) {
            mprPutStringToWideBuf(json->buf, json->indent);
        }
    }
    mprPutCharToWideBuf(json->buf, isArray ? ']' : '}');
    mprAddNullToWideBuf(json->buf);

    if (--json->nest == 0) {
        result = ejsCreateString(ejs, mprGetBufStart(json->buf), mprGetBufLength(json->buf) / sizeof(wchar));
        mprRemoveRoot(json->buf);
    } else {
        result = 0;
    }
    return result;
}
Beispiel #19
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;
}
Beispiel #20
0
static EjsAny *coerceNullOperands(Ejs *ejs, EjsObj *lhs, int opcode, EjsObj *rhs)
{
    switch (opcode) {

    case EJS_OP_ADD:
        if (!ejsIs(ejs, rhs, Number)) {
            return ejsInvokeOperator(ejs, ejsToString(ejs, lhs), opcode, rhs);
        }
        /* Fall through */

    case EJS_OP_AND: case EJS_OP_DIV: case EJS_OP_MUL: case EJS_OP_OR: case EJS_OP_REM:
    case EJS_OP_SHL: case EJS_OP_SHR: case EJS_OP_SUB: case EJS_OP_USHR: case EJS_OP_XOR:
        return ejsInvokeOperator(ejs, ESV(zero), opcode, rhs);

    /*
        Comparision
     */
    case EJS_OP_COMPARE_LE: case EJS_OP_COMPARE_LT:
    case EJS_OP_COMPARE_GE: case EJS_OP_COMPARE_GT:
        if (ejsIs(ejs, rhs, Number)) {
            return ejsInvokeOperator(ejs, ESV(zero), opcode, rhs);
        } else if (ejsIs(ejs, rhs, String)) {
            return ejsInvokeOperator(ejs, ejsToString(ejs, lhs), opcode, rhs);
        }
        break;

    case EJS_OP_COMPARE_NE:
        if (ejsIs(ejs, rhs, Void)) {
            return ESV(false);
        }
        return ESV(true);

    case EJS_OP_COMPARE_STRICTLY_NE:
        return ESV(true);

    case EJS_OP_COMPARE_EQ:
        if (ejsIs(ejs, rhs, Void)) {
            return ESV(true);
        }
        return ESV(false);

    case EJS_OP_COMPARE_STRICTLY_EQ:
        return ESV(false);

    case EJS_OP_COMPARE_UNDEFINED:
    case EJS_OP_COMPARE_NOT_ZERO:
    case EJS_OP_COMPARE_NULL:
        return ESV(true);

    case EJS_OP_COMPARE_FALSE:
    case EJS_OP_COMPARE_TRUE:
    case EJS_OP_COMPARE_ZERO:
        return ESV(false);

    /*
        Unary operators
     */
    case EJS_OP_LOGICAL_NOT: case EJS_OP_NOT: case EJS_OP_NEG:
        return 0;

    default:
        ejsThrowTypeError(ejs, "Opcode %d not valid for type %@", opcode, TYPE(lhs)->qname.name);
        return ESV(undefined);
    }
    return 0;
}
Beispiel #21
0
/*
    Get the current exception error. May be an Error object or may be any other object that is thrown.
    Caller must NOT free.
 */
cchar *ejsGetErrorMsg(Ejs *ejs, int withStack)
{
    EjsString   *str, *tag, *msg, *message;
    EjsAny      *stack, *error, *saveException;
    char        *buf, *stackStr;

    error = ejs->exception;
    message = 0;
    stack = 0;
    tag = NULL;

    if (error) {
        tag = TYPE(error)->qname.name;
        if (ejsIs(ejs, error, Error)) {
            message = ejsGetProperty(ejs, error, ES_Error_message);
            if (withStack && ejs->initialized && ejs->state) {
                saveException = ejs->exception;
                ejsClearException(ejs);
                stack = ejsRunFunctionBySlot(ejs, error, ES_Error_formatStack, 0, NULL);
                ejsThrowException(ejs, saveException);
            }

        } else if (ejsIs(ejs, error, String)) {
            tag = ejsCreateStringFromAsc(ejs, "Error");
            message = (EjsString*) error;

        } else if (ejsIs(ejs, error, Number)) {
            tag = ejsCreateStringFromAsc(ejs, "Error");
            message = (EjsString*) error;
            
        } else if (error == EST(StopIteration)) {
            message = ejsCreateStringFromAsc(ejs, "Uncaught StopIteration exception");
        }
    }
    if (message == ESV(null) || message == 0) {
        msg = ejsCreateStringFromAsc(ejs, "Exception");
    } else{
        msg = ejsToString(ejs, message);
    }
    if (ejsIs(ejs, error, Error)) {
        stackStr = (stack) ? ejsToMulti(ejs, stack) : 0;
        if (stackStr && *stackStr) {
            buf = sfmt("%@: %@\nStack:\n%s", tag, msg, (stack) ? ejsToMulti(ejs, stack) : "");
        } else {
            buf = sfmt("%@: %@", tag, msg);
        }

    } else if (message && ejsIs(ejs, message, String)){
        buf = sfmt("%@: %@", tag, msg);

    } else if (message && ejsIs(ejs, message, Number)){
        buf = sfmt("%@: %g", tag, ((EjsNumber*) msg)->value);
        
    } else if (error) {
        EjsObj *saveException = ejs->exception;
        ejs->exception = 0;
        str = ejsToString(ejs, error);
        buf = sclone(ejsToMulti(ejs, str));
        ejs->exception = saveException;

    } else {
        buf = sclone("");
    }
    ejs->errorMsg = buf;
    return buf;
}