Exemplo n.º 1
0
/*
 *  native static function callback(fn: Function): Void
 */
static EjsVar *setRedlineCallback(Ejs *ejs, EjsVar *thisObj, int argc, EjsVar **argv)
{
    mprAssert(argc == 1 && ejsIsFunction(argv[0]));

    if (!ejsIsFunction(argv[0])) {
        ejsThrowArgError(ejs, "Callaback is not a function");
        return 0;
    }
    ejs->memoryCallback = (EjsFunction*) argv[0];
    return 0;
}
Exemplo n.º 2
0
EjsVar *ejsCreateInstance(Ejs *ejs, EjsType *type, int argc, EjsVar **argv)
{
    EjsFunction     *fun;
    EjsVar          *vp;
    int             slotNum;

    mprAssert(type);

    vp = ejsCreateVar(ejs, type, 0);
    if (vp == 0) {
        ejsThrowMemoryError(ejs);
        return 0;
    }

    if (type->hasConstructor) {
        slotNum = type->block.numInherited;
        fun = (EjsFunction*) ejsGetProperty(ejs, (EjsVar*) type, slotNum);
        if (fun == 0) {
            return 0;
        }
        if (!ejsIsFunction(fun)) {
            return 0;
        }

        vp->permanent = 1;
        ejsRunFunction(ejs, fun, vp, argc, argv);
        vp->permanent = 0;
    }

    return vp;
}
Exemplo n.º 3
0
EjsString *ejsSerializeWithOptions(Ejs *ejs, EjsAny *vp, EjsObj *options)
{
    Json        json;
    EjsObj      *arg;
    EjsString   *result;
    int         i;

    memset(&json, 0, sizeof(Json));
    json.depth = 99;
    json.quotes = 1;
    json.indent = sclone("  ");

    if (options) {
        json.options = options;
        if ((arg = ejsGetPropertyByName(ejs, options, EN("baseClasses"))) != 0) {
            json.baseClasses = (arg == ESV(true));
        }
        if ((arg = ejsGetPropertyByName(ejs, options, EN("depth"))) != 0) {
            json.depth = ejsGetInt(ejs, arg);
        }
        if ((arg = ejsGetPropertyByName(ejs, options, EN("indent"))) != 0) {
            if (ejsIs(ejs, arg, String)) {
                json.indent = (char*) ejsToMulti(ejs, arg);
                //  TODO - get another solution to hold
            } else if (ejsIs(ejs, arg, Number)) {
                i = ejsGetInt(ejs, arg);
                if (0 <= i && i < MPR_MAX_STRING) {
                    json.indent = mprAlloc(i + 1);
                    //  TODO - get another solution to hold
                    memset(json.indent, ' ', i);
                    json.indent[i] = '\0';
                }
            }
        }
        if ((arg = ejsGetPropertyByName(ejs, options, EN("commas"))) != 0) {
            json.commas = (arg == ESV(true));
        }
        if ((arg = ejsGetPropertyByName(ejs, options, EN("hidden"))) != 0) {
            json.hidden = (arg == ESV(true));
        }
        if ((arg = ejsGetPropertyByName(ejs, options, EN("namespaces"))) != 0) {
            json.namespaces = (arg == ESV(true));
        }
        if ((arg = ejsGetPropertyByName(ejs, options, EN("quotes"))) != 0) {
            json.quotes = (arg != ESV(false));
        }
        if ((arg = ejsGetPropertyByName(ejs, options, EN("pretty"))) != 0) {
            json.pretty = (arg == ESV(true));
        }
        json.replacer = ejsGetPropertyByName(ejs, options, EN("replacer"));
        if (!ejsIsFunction(ejs, json.replacer)) {
            json.replacer = NULL;
        }
    }
    mprRelease(json.indent);
    mprHold(json.indent);
    result = serialize(ejs, vp, &json);
    //  TODO - get another solution to hold
    return result;
}
Exemplo n.º 4
0
/**
    Get a serialized string representation of a variable using JSON encoding.
    @return Returns a string variable or null if an exception is thrown.
 */
EjsString *ejsToJson(Ejs *ejs, EjsVar *vp)
{
    EjsFunction     *fn;
    EjsString       *result;

    if (vp == 0) {
        return ejsCreateString(ejs, "undefined");
    }
    if (vp->jsonVisited) {
        return ejsCreateString(ejs, "this");
    }
    vp->jsonVisited = 1;

    /*
     *  Types can provide a toJSON method, a serializeVar helper. If neither are provided, toString is used as a fall-back.
     */
    fn = (EjsFunction*) ejsGetProperty(ejs, (EjsVar*) vp->type, ES_Object_toJSON);
    if (ejsIsFunction(fn)) {
        result = (EjsString*) ejsRunFunction(ejs, fn, vp, 0, NULL);
    } else {
        result = ejsToString(ejs, vp);
    }
    vp->jsonVisited = 0;
    return result;
}
Exemplo n.º 5
0
/**
    Get a string representation of a variable.
    @return Returns a string variable or null if an exception is thrown.
 */
EjsString *ejsToString(Ejs *ejs, EjsVar *vp)
{
    EjsFunction     *fn;

    if (vp == 0) {
        return ejsCreateString(ejs, "undefined");
    } else if (ejsIsString(vp)) {
        return (EjsString*) vp;
    }

    /*
     *  Types can provide a toString method or a castVar helper
     */
    if (vp->type->helpers->getProperty != getProperty) { 
        fn = (EjsFunction*) ejsGetProperty(ejs, (EjsVar*) vp->type, ES_Object_toString);
        if (ejsIsFunction(fn)) {
            return (EjsString*) ejsRunFunction(ejs, fn, vp, 0, NULL);
        }
    }
    if (vp->type->helpers->castVar) {
        return (EjsString*) (vp->type->helpers->castVar)(ejs, vp, ejs->stringType);
    }
    ejsThrowInternalError(ejs, "CastVar helper not defined for type \"%s\"", vp->type->qname.name);
    return 0;
}
Exemplo n.º 6
0
/**
 *  Iterate over all elements in the object and find all elements for which the matching function is true.
 *  The match is called with the following signature:
 *
 *      function match(arrayElement: Object, elementIndex: Number, arr: Array): Boolean
 *
 *  @param match Matching function
 *  @return Returns a new array containing all matching elements.
 */
static EjsVar *findAll(Ejs *ejs, EjsArray *ap, int argc, EjsVar **argv)
{
    EjsVar      *funArgs[3];
    EjsBoolean  *result;
    EjsArray    *elements;
    int         i;

    mprAssert(argc == 1 && ejsIsFunction(argv[0]));

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

    for (i = 0; i < ap->length; i++) {
        funArgs[0] = ap->obj.properties.slots[i];               /* Array element */
        funArgs[1] = (EjsVar*) ejsCreateNumber(ejs, i);             /* element index */
        funArgs[2] = (EjsVar*) ap;                                  /* Array */
        result = (EjsBoolean*) ejsRunFunction(ejs, (EjsFunction*) argv[0], 0, 3, funArgs);
        if (result == 0 || !ejsIsBoolean(result) || !result->value) {
            setArrayProperty(ejs, elements, elements->length, ap->obj.properties.slots[i]);
        }
    }
    return (EjsVar*) elements;
}
Exemplo n.º 7
0
/*
    Constructor to create an iterator using a scripted next().

    public function Iterator(obj, f, deep, ...namespaces)
 */
static EjsObj *iteratorConstructor(Ejs *ejs, EjsIterator *ip, int argc, EjsObj **argv)
{
    if (argc != 2 || !ejsIsFunction(ejs, argv[1])) {
        ejsThrowArgError(ejs, "usage: Iterator(obj, function)");
        return 0;
    }
    ip->target = argv[0];
    ip->next = (EjsFunction*) argv[1];
    mprAssert(ip->nativeNext == 0);

    return ip;
}
Exemplo n.º 8
0
static EjsString *getBlockName(EjsMod *mp, EjsObj *block, int slotNum)
{
    EjsName         qname;

    if (block) {
        if (ejsIsType(mp->ejs, block)) {
            return ((EjsType*) block)->qname.name;

        } else if (ejsIsFunction(mp->ejs, block)) {
            return ((EjsFunction*) block)->name;
        }
    }
    qname = ejsGetPropertyName(mp->ejs, block, slotNum);
    return qname.name;
}
Exemplo n.º 9
0
/**
    Get a serialized string representation of a variable using JSON encoding.
    This will look for a "toJSON" function on the specified object. Use ejsSerialize for low level JSON.
    @return Returns a string variable or null if an exception is thrown.
 */
PUBLIC EjsString *ejsToJSON(Ejs *ejs, EjsAny *vp, EjsObj *options)
{
    EjsFunction     *fn;
    EjsString       *result;
    EjsObj          *argv[1];
    int             argc;

    fn = (EjsFunction*) ejsGetPropertyByName(ejs, TYPE(vp)->prototype, N(NULL, "toJSON"));
    if (!ejsIsFunction(ejs, fn) || (fn->isNativeProc && fn->body.proc == (EjsProc) ejsObjToJSON)) {
        result = ejsSerializeWithOptions(ejs, vp, options);
    } else {
        argv[0] = options;
        argc = options ? 1 : 0;
        result = (EjsString*) ejsRunFunction(ejs, fn, vp, argc, argv);
    }
    return result;
}
Exemplo n.º 10
0
/**
    Sort the array using the supplied compare function

    function sort(compare: Function = null, direction: Number = 1): Array

    Where compare is defined as:
        function compare(a,b): Number
 */
PUBLIC EjsArray *ejsSortArray(Ejs *ejs, EjsArray *ap, int argc, EjsObj **argv)
{
    EjsFunction     *compare;
    int             direction;

    if (ap->length <= 1) {
        return ap;
    }
    compare = (EjsFunction*) ((argc >= 1) ? argv[0]: NULL);
    if (compare == ESV(null)) {
        compare = 0;
    }
    if (compare && !ejsIsFunction(ejs, compare)) {
        ejsThrowArgError(ejs, "Compare argument is not a function");
        return 0;
    }
    direction = (argc >= 2) ? ejsGetInt(ejs, argv[1]) : 1;
    quickSort(ejs, ap, compare, direction, 0, ap->length - 1);
    return ap;
}
Exemplo n.º 11
0
static void receiveRequest(EjsRequest *req, MprEvent *event)
{
    Ejs             *ejs;
    EjsAny          *argv[1];
    EjsFunction     *onrequest;
    HttpConn        *conn;

    conn = req->conn;
    ejs = req->ejs;
    assert(ejs);

    onrequest = ejsGetProperty(ejs, req->server, ES_ejs_web_HttpServer_onrequest);
    if (!ejsIsFunction(ejs, onrequest)) {
        ejsThrowStateError(ejs, "HttpServer.onrequest is not a function");
        return;
    }
    argv[0] = req;
    ejsRunFunction(ejs, onrequest, req->server, 1, argv);
    if (conn->state == HTTP_STATE_BEGIN) {
        conn->ejs = 0;
        httpUsePrimary(conn);
    }
    httpEnableConnEvents(conn);
}
Exemplo n.º 12
0
static void onWebSocketEvent(EjsWebSocket *ws, int event, EjsAny *data, HttpPacket *packet)
{
    Ejs             *ejs;
    EjsAny          *eobj;
    EjsFunction     *fn;
    HttpRx          *rx;
    cchar           *eventName, *reason;
    int             slot, status;

    ejs = ws->ejs;
    rx = ws->conn->rx;
    eobj = ejsCreateObj(ejs, ESV(Object), 0);
    slot = -1;
    eventName = 0;

    switch(event) {
    case HTTP_EVENT_READABLE:
        slot = ES_WebSocket_onmessage;
        eventName = "readable";
        assert(data);
        ejsSetPropertyByName(ejs, eobj, EN("data"), data);
        ejsSetPropertyByName(ejs, eobj, EN("last"), ejsCreateBoolean(ejs, packet->last));
        ejsSetPropertyByName(ejs, eobj, EN("type"), ejsCreateNumber(ejs, packet->type));
        break;

    case HTTP_EVENT_ERROR:
        eventName = "error";
        slot = ES_WebSocket_onerror;
        break;

    case HTTP_EVENT_APP_OPEN:
        slot = ES_WebSocket_onopen;
        eventName = "headers";
        if (rx->webSocket) {
            httpSetWebSocketPreserveFrames(ws->conn, ws->frames);
        }
        break;

    case HTTP_EVENT_DESTROY:
        if (ws->closed) {
            break;
        }
        ws->closed = 1;
        /* Fall through to close */

    case HTTP_EVENT_APP_CLOSE:
        eventName = "complete";
        slot = ES_WebSocket_onclose;
        status = rx ? rx->webSocket->closeStatus: WS_STATUS_COMMS_ERROR;
        reason = rx ? rx->webSocket->closeReason: 0;
        ejsSetPropertyByName(ejs, eobj, EN("code"), ejsCreateNumber(ejs, status));
        ejsSetPropertyByName(ejs, eobj, EN("reason"), ejsCreateStringFromAsc(ejs, reason));
        ejsSetPropertyByName(ejs, eobj, EN("wasClean"), ejsCreateBoolean(ejs, status != WS_STATUS_COMMS_ERROR));
        break;
    }
    if (slot >= 0) {
        if (ws->emitter) {
            ejsSendEvent(ejs, ws->emitter, eventName, ws, data);
        }
        fn = ejsGetProperty(ejs, ws, slot);
        if (ejsIsFunction(ejs, fn) && !ejs->exception) {
            ejsRunFunction(ejs, fn, ws, 1, &eobj);
        }
    }
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
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);
}
Exemplo n.º 16
0
/*
    List the various property slot assignments
 */
static void lstSlotAssignments(EjsMod *mp, EjsModule *module, EjsObj *parent, int slotNum, EjsObj *obj)
{
    Ejs             *ejs;
    EjsTrait        *trait;
    EjsType         *type;
    EjsObj          *vp;
    EjsPot          *prototype;
    EjsFunction     *fun;
    EjsBlock        *block;
    EjsName         qname;
    int             i, numInherited, count;

    mprAssert(obj);
    mprAssert(module);

    ejs = mp->ejs;
    if (VISITED(obj)) {
        return;
    }
    SET_VISITED(obj, 1);

    if (obj == ejs->global) {
        mprFprintf(mp->file,  "\n#\n"
            "#  Global slot assignments (Num prop %d)\n"
            "#\n", ejsGetLength(ejs, obj));

        /*
            List slots for global
         */
        for (i = module->firstGlobal; i < module->lastGlobal; i++) {
            trait = ejsGetPropertyTraits(ejs, ejs->global, i);
            qname = ejsGetPropertyName(ejs, ejs->global, i);
            if (qname.name == 0) {
                continue;
            }
            lstVarSlot(mp, module, &qname, trait, i);
        }

        /*
            List slots for the initializer
         */
        fun = (EjsFunction*) module->initializer;
        if (fun) {
            mprFprintf(mp->file,  "\n#\n"
                "#  Initializer slot assignments (Num prop %d)\n"
                "#\n", ejsGetLength(ejs, (EjsObj*) fun));

            count = ejsGetLength(ejs, (EjsObj*) fun);
            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, (EjsObj*) fun, i);
                qname = ejsGetPropertyName(ejs, (EjsObj*) fun, i);
                if (qname.name == 0) {
                    continue;
                }
                mprAssert(trait);
                lstVarSlot(mp, module, &qname, trait, i);
            }
        }

    } else if (ejsIsFunction(ejs, obj)) {
        fun = (EjsFunction*) obj;
        count = ejsGetLength(ejs, (EjsObj*) obj);
        if (count > 0) {
            mprFprintf(mp->file,  "\n#\n"
                "#  Local slot assignments for the \"%@\" function (Num slots %d)\n"
                "#\n", fun->name, count);

            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, obj, i);
                mprAssert(trait);
                qname = ejsGetPropertyName(ejs, obj, i);
                lstVarSlot(mp, module, &qname, trait, i);
            }
        }

    } else if (ejsIsType(ejs, obj)) {
        /*
            Types
         */
        type = (EjsType*) obj;
        mprFprintf(mp->file,  "\n#\n"
            "#  Class slot assignments for the \"%@\" class (Num slots %d)\n"
            "#\n", type->qname.name,
            ejsGetLength(ejs, (EjsObj*) type));

        count = ejsGetLength(ejs, (EjsObj*) type);
        for (i = 0; i < count; i++) {
            trait = ejsGetPropertyTraits(ejs, (EjsObj*) type, i);
            mprAssert(trait);
            qname = ejsGetPropertyName(ejs, obj, i);
            lstVarSlot(mp, module, &qname, trait, i);
        }

        prototype = type->prototype;
        if (type->baseType && type->baseType->prototype) {
            numInherited = ejsGetLength(ejs, type->baseType->prototype);
        } else {
            numInherited = 0;
        }
        mprFprintf(mp->file,  "\n#\n"
            "#  Instance slot assignments for the \"%@\" class (Num prop %d, num inherited %d)\n"
            "#\n", type->qname.name,
            prototype ? ejsGetLength(ejs, prototype): 0, numInherited);

        if (prototype) {
            count = ejsGetLength(ejs, prototype);
            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, prototype, i);
                mprAssert(trait);
                qname = ejsGetPropertyName(ejs, prototype, i);
                if (qname.name) {
                    lstVarSlot(mp, module, &qname, trait, i);
                }
            }
        }

    } else if (ejsIsBlock(ejs, obj)) {
        qname = ejsGetPropertyName(ejs, parent, slotNum);
        block = (EjsBlock*) obj;
        count = ejsGetLength(ejs, (EjsObj*) block);
        if (count > 0) {
            mprFprintf(mp->file,  
                "\n#\n"
                "#  Block slot assignments for the \"%@\" (Num slots %d)\n"
                "#\n", qname.name, ejsGetLength(ejs, obj));
            
            count = ejsGetLength(ejs, obj);
            for (i = 0; i < count; i++) {
                trait = ejsGetPropertyTraits(ejs, obj, i);
                mprAssert(trait);
                qname = ejsGetPropertyName(ejs, obj, i);
                lstVarSlot(mp, module, &qname, trait, i);
            }
        }
    }

    /*
        Now recurse on types, functions and blocks
     */
    if (obj == ejs->global) {
        i = module->firstGlobal;
        count = module->lastGlobal;
    } else {
        i = 0;
        count = ejsGetLength(ejs, obj);
    }
    for (; i < count; i++) {
        qname = ejsGetPropertyName(ejs, obj, i);
        vp = ejsGetProperty(ejs, obj, i);
        if (vp == 0) {
            continue;
        }
        if (ejsIsType(ejs, vp) || ejsIsFunction(ejs, vp) || ejsIsBlock(ejs, vp)) {
            lstSlotAssignments(mp, module, obj, i, vp);
        }
    }
    SET_VISITED(obj, 0);
}