예제 #1
0
파일: ejsDb.c 프로젝트: jsjohnst/ejscript
void ejsConfigureDbTypes(Ejs *ejs)
{
    EjsType     *type;
    EjsName     qname;

    ejsName(&qname, "ejs.db", "Database");
    type = (EjsType*) ejsGetPropertyByName(ejs, ejs->global, &qname);
    if (type == 0 || !ejsIsType(type)) {
        ejs->hasError = 1;
        return;
    }

    type->instanceSize = sizeof(EjsDb);
    type->helpers->finalizeVar = (EjsFinalizeVarHelper) finalizeDb;

    ejsBindMethod(ejs, type, ES_ejs_db_Database_Database, (EjsNativeFunction) dbConstructor);
    ejsBindMethod(ejs, type, ES_ejs_db_Database_close, (EjsNativeFunction) closeDb);
    ejsBindMethod(ejs, type, ES_ejs_db_Database_sql, (EjsNativeFunction) sql);

#if UNUSED
    ejsSetAccessors(ejs, type, ES_ejs_db_Database_tables, (EjsNativeFunction) tables, -1, 0);
    ejsBindMethod(ejs, type, ES_ejs_db_Database_start, startDb);
    ejsBindMethod(ejs, type, ES_ejs_db_Database_commit, commitDb);
    ejsBindMethod(ejs, type, ES_ejs_db_Database_rollback, rollbackDb);
#endif
}
예제 #2
0
/*
 *  Format the stack backtrace
 */
char *ejsFormatStack(Ejs *ejs)
{
    EjsFrame        *frame;
    EjsType         *type;
    EjsFunction     *fun;
    cchar           *typeName, *functionName, *line, *typeSep, *codeSep;
    char            *backtrace, *traceLine;
    int             level, len;

    mprAssert(ejs);

    backtrace = 0;
    len = 0;
    level = 0;

    for (frame = ejs->frame; frame; frame = frame->caller) {

        if (frame->currentLine == 0) {
            line = "";
        } else {
            for (line = frame->currentLine; *line && isspace((int) *line); line++) {
                ;
            }
        }

        typeName = "";
        functionName = "global";

        fun = &frame->function;
        if (fun) {
            if (fun->owner) {
                functionName = ejsGetPropertyName(ejs, fun->owner, fun->slotNum).name;
            }
            if (ejsIsType(fun->owner)) {
                type = (EjsType*) fun->owner;
                if (type) {
                    typeName = type->qname.name;
                }
            }
        }
        typeSep = (*typeName) ? "." : "";
        codeSep = (*line) ? "->" : "";

        if (mprAllocSprintf(ejs, &traceLine, MPR_MAX_STRING, " [%02d] %s, %s%s%s, line %d %s %s\n",
                level++, frame->fileName ? frame->fileName : "script", typeName, typeSep, functionName,
                frame->lineNumber, codeSep, line) < 0) {
            break;
        }
        backtrace = (char*) mprRealloc(ejs, backtrace, len + (int) strlen(traceLine) + 1);
        if (backtrace == 0) {
            return 0;
        }
        memcpy(&backtrace[len], traceLine, strlen(traceLine) + 1);
        len += (int) strlen(traceLine);
        mprFree(traceLine);
    }
    return backtrace;
}
예제 #3
0
파일: listing.c 프로젝트: varphone/ejs-2
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;
}
예제 #4
0
/*
    Find a property in an object or its prototype and base classes.
 */
int ejsLookupVar(Ejs *ejs, EjsAny *obj, EjsName name, EjsLookup *lookup)
{
    EjsType     *type;
    EjsPot      *prototype;
    int         slotNum, nthBase;

    assert(obj);
    assert(lookup);

    memset(lookup, 0, sizeof(*lookup));

    /* Lookup simple object */
    if ((slotNum = ejsLookupVarWithNamespaces(ejs, obj, name, lookup)) >= 0) {
        return slotNum;
    }
    /* Lookup prototype chain */
    for (nthBase = 1, type = TYPE(obj); type; type = type->baseType, nthBase++) {
        if ((prototype = type->prototype) == 0 || prototype->shortScope) {
            break;
        }
        if ((slotNum = ejsLookupVarWithNamespaces(ejs, prototype, name, lookup)) >= 0) {
            lookup->nthBase = nthBase;
            return slotNum;
        }
    }
    /* Lookup base-class chain */
    type = ejsIsType(ejs, obj) ? ((EjsType*) obj)->baseType : TYPE(obj);
    for (nthBase = 1; type; type = type->baseType, nthBase++) {
        if (type->constructor.block.pot.shortScope) {
            continue;
        }
        if ((slotNum = ejsLookupVarWithNamespaces(ejs, type, name, lookup)) >= 0) {
            lookup->nthBase = nthBase;
            return slotNum;
        }
    }
    return -1;
}
예제 #5
0
/*
    Look for a variable by name in the scope chain and return the location in "lookup" and a positive slot number if found. 
    If the name.space is non-empty, then only the given namespace will be used. Otherwise the set of open namespaces will 
    be used. The lookup structure will contain details about the location of the variable.
 */
static int lookupVarInBlock(Ejs *ejs, EjsBlock *bp, EjsName name, EjsLookup *lookup)
{
    EjsFrame        *frame;
    EjsState        *state;
    EjsType         *type;
    EjsObj          *thisObj;
    EjsPot          *prototype;
    int             slotNum, nthBase;

    assert(ejs);
    assert(name.name);
    assert(name.space);
    assert(lookup);

    state = ejs->state;
    slotNum = -1;
    thisObj = state->fp->function.boundThis;

    /* Search simple block */
    lookup->originalObj = bp;
    if ((slotNum = ejsLookupVarWithNamespaces(ejs, bp, name, lookup)) >= 0) {
        return slotNum;
    }
    /* Optimized lookup for frames and types. Simple blocks don't need prototype lookup - so examine the type of block */
    if (ejsIsFrame(ejs, bp)) {
        frame = (EjsFrame*) bp;
        if (thisObj && frame->function.boundThis == thisObj && 
                thisObj != ejs->global && !frame->function.staticMethod && 
                !frame->function.isInitializer) {
            lookup->originalObj = thisObj;
            /* Instance method only */
            if ((slotNum = ejsLookupVarWithNamespaces(ejs, thisObj, name, lookup)) >= 0) {
                return slotNum;
            }
            /* Search prototype chain */
            for (nthBase = 1, type = TYPE(thisObj); type; type = type->baseType, nthBase++) {
                if ((prototype = type->prototype) == 0 || prototype->shortScope) {
                    break;
                }
                if ((slotNum = ejsLookupVarWithNamespaces(ejs, prototype, name, lookup)) >= 0) {
                    lookup->nthBase = nthBase;
                    lookup->type = type;
                    return slotNum;
                }
            }
            if (frame->function.isConstructor) {
                for (nthBase = 1, type = (EjsType*) TYPE(thisObj); type; type = type->baseType, nthBase++) {
                    if (type->constructor.block.pot.shortScope) {
                        break;
                    }
                    if ((slotNum = ejsLookupVarWithNamespaces(ejs, type, name, lookup)) >= 0) {
                        lookup->nthBase = nthBase;
                        return slotNum;
                    }
                }
            }
            thisObj = 0;
        }
    } else if (ejsIsType(ejs, bp)) {
        /* Search base class chain */
        //  OPT -- remove nthBase. Not needed if not binding.
        for (nthBase = 1, type = (EjsType*) bp; type; type = type->baseType, nthBase++) {
            if (type->constructor.block.pot.shortScope) {
                break;
            }
            if ((slotNum = ejsLookupVarWithNamespaces(ejs, type, name, lookup)) >= 0) {
                lookup->nthBase = nthBase;
                return slotNum;
            }
        }
    }
    return -1;
}
예제 #6
0
/*
 *  Format the stack backtrace
 */
char *ejsFormatStack(Ejs *ejs, EjsError *error)
{
    EjsType         *type;
    EjsFrame        *fp;
    cchar           *typeName, *functionName, *line, *typeSep, *codeSep;
    char            *backtrace, *traceLine;
    int             level, len, oldFlags;

    mprAssert(ejs);

    backtrace = 0;
    len = 0;
    level = 0;

    /*
     *  Pretend to be the compiler so we can access function frame names
     */
    oldFlags = ejs->flags;
    ejs->flags |= EJS_FLAG_COMPILER;

    for (fp = ejs->state->fp; fp; fp = fp->caller) {

        typeName = "";
        functionName = "global";

        if (fp->currentLine == 0) {
            line = "";
        } else {
            for (line = fp->currentLine; *line && isspace((int) *line); line++) {
                ;
            }
        }
        if (fp) {
            if (fp->function.owner && fp->function.slotNum >= 0) {
                functionName = ejsGetPropertyName(ejs, fp->function.owner, fp->function.slotNum).name;
            }
            if (ejsIsType(fp->function.owner)) {
                type = (EjsType*) fp->function.owner;
                if (type) {
                    typeName = type->qname.name;
                }
            }
        }
        typeSep = (*typeName) ? "." : "";
        codeSep = (*line) ? "->" : "";

        if (error && backtrace == 0) {
            error->filename = mprStrdup(error, fp->filename);
            error->lineNumber = fp->lineNumber;
        }
        if ((traceLine = mprAsprintf(ejs, MPR_MAX_STRING, " [%02d] %s, %s%s%s, line %d %s %s\n",
                level++, fp->filename ? fp->filename : "script", typeName, typeSep, functionName,
                fp->lineNumber, codeSep, line)) == NULL) {
            break;
        }
        backtrace = (char*) mprRealloc(ejs, backtrace, len + (int) strlen(traceLine) + 1);
        if (backtrace == 0) {
            return 0;
        }
        memcpy(&backtrace[len], traceLine, strlen(traceLine) + 1);
        len += (int) strlen(traceLine);
        mprFree(traceLine);
    }
    ejs->flags = oldFlags;
    if (error) {
        error->stack = backtrace;
    }
    return backtrace;
}
예제 #7
0
파일: listing.c 프로젝트: varphone/ejs-2
/*
    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);
}
예제 #8
0
파일: listing.c 프로젝트: varphone/ejs-2
/*
    Return the length of bytes added to buf
 */
static void getGlobal(EjsMod *mp, char *buf, int buflen)
{
    Ejs             *ejs;
    EjsName         qname;
    EjsObj          *vp;
    int             t, slotNum;

    ejs = mp->ejs;
    vp = 0;

    if ((t = (int) getNum(mp)) < 0) {
        mprSprintf(buf, buflen,  "<can't read code>");
        return;
    }

    switch (t & EJS_ENCODE_GLOBAL_MASK) {
    default:
        mprAssert(0);
        return;

    case EJS_ENCODE_GLOBAL_NOREF:
        return;

    case EJS_ENCODE_GLOBAL_SLOT:
        /*
            Type is a builtin primitive type or we are binding globals.
         */
        slotNum = t >> 2;
        if (0 <= slotNum && slotNum < ejsGetLength(ejs, ejs->global)) {
            vp = ejsGetProperty(ejs, ejs->global, slotNum);
        }
        if (vp && ejsIsType(ejs, vp)) {
            mprSprintf(buf, buflen, "<type: 0x%x,  %N> ", t, ((EjsType*) vp)->qname);
        }
        break;

    case EJS_ENCODE_GLOBAL_NAME:
        /*
            Type was unknown at compile time
         */
        qname.name = ejsCreateStringFromConst(ejs, mp->module, t >> 2);
        if (qname.name == 0) {
            mprAssert(0);
            mprSprintf(buf, buflen,  "<var: 0x%x,  missing name> ", t);
            return;
        }
        if ((qname.space = getString(mp->ejs, mp)) == 0) {
            mprSprintf(buf, buflen,  "<var: 0x%x,  missing namespace> ", t);
            return;
        }
        if (qname.name) {
            vp = ejsGetPropertyByName(ejs, ejs->global, qname);
        }
        mprSprintf(buf, buflen, "<var: 0x%x,  %N> ", t, qname);
        break;
    }

    if (vp == 0) {
        mprSprintf(buf, buflen, "<var: %d,  cannot resolve var/typ at slot e> ", t);
    }
}