Beispiel #1
0
/**
 * Entry function which will process the assembled code and perform the required actions
 */
struct value_defn processAssembledCode(char * assembled, unsigned int currentPoint, unsigned int length) {
    struct value_defn empty;
    empty.type=NONE_TYPE;
    empty.dtype=SCALAR;
    unsigned int i, fnAddr;
    for (i=currentPoint; i<length;) {
        unsigned char command=getUChar(&assembled[i]);
        i+=sizeof(unsigned char);
        if (command == LET_TOKEN) i=handleLet(assembled, i, length, 0);
        if (command == LETNOALIAS_TOKEN) i=handleLet(assembled, i, length, 1);
        if (command == ARRAYSET_TOKEN) i=handleArraySet(assembled, i, length);
        if (command == STOP_TOKEN) return empty;
        if (command == IF_TOKEN) i=handleIf(assembled, i, length);
        if (command == IFELSE_TOKEN) i=handleIf(assembled, i, length);
        if (command == FOR_TOKEN) i=handleFor(assembled, i, length);
        if (command == GOTO_TOKEN) i=handleGoto(assembled, i, length);
        if (command == FNCALL_TOKEN || command == FNCALL_BY_VAR_TOKEN) {
            i=handleFnCall(assembled, i, &fnAddr, length, command == FNCALL_BY_VAR_TOKEN ? 1:0);
            fnLevel++;
            processAssembledCode(assembled, fnAddr, length);
            clearVariablesToLevel(fnLevel);
            fnLevel--;
        }
        if (command == NATIVE_TOKEN) i=handleNative(assembled, i, length, NULL);
        if (command == RETURN_TOKEN) return empty;
        if (command == RETURN_EXP_TOKEN) {
            return getExpressionValue(assembled, &i, length);
        }
        if (stopInterpreter) return empty;
    }
    return empty;
}
Beispiel #2
0
bool QDBCFile::hasFullString(quint32 field, quint32 row) const
{
    if(field < m_fieldCount && row < m_recordCount && field >= 0 && row >= 0 && m_stringSize > 1) {
        if(getUInt(field,row) < m_stringSize)
            if(getUChar(getUInt(field,row)-1)=='\0' && field > 0)
                return true;
    }
    return false;
}
Beispiel #3
0
_Parameter      _CString::FrequencyCompress(unsigned char theAlpha,bool doit)
{

    _String* theAlphabet = SelectAlpha (theAlpha);
  
    if (theAlphabet->sLength>31) {
        return 1.;    // can't do much - the alphabet is too large
    }
    char codeLength[256];
    long freqs [256],j,t;
    long maxOccurences[256], locationsOfMaxSymbols[256] ; //simply ensures that we
    // won't have symbols out of the alphabet


    //analyze the frequency distribution of alphabetic symbols

    for (j=0; j<256; freqs[j]=0,codeLength[j]=0,maxOccurences[j]=0, j++ ) {}


    for (j=0; j<sLength; j++) {
        freqs[getUChar(j)]++;
    }

    t = 0;
    for (j=0; j<theAlphabet->sLength; j++) {
        freqs[NuclAlphabet.getUChar(j)]*=-1;
    }

    //make sure that the alphabet is "large" enough for the nucleotide case
    // NEW 03/29/98
    for (j=0; j<256; j++)
        if (freqs[j]>0) {
            t = 1;
            break;
        } else {
            freqs[j]*=-1;
        }
    if (t) {
        if (theAlphabet == &NuclAlphabet) {
            return FrequencyCompress (FULLNUCLALPHABET, doit);
        } else {
            return 1;
        }
    }



    // now build the prefix code for the alphabet
    // fisrt find four most frequently occurring symbols

    for (j=0; j<(*theAlphabet).sLength; j++) {
        for (long k = 0; k<(*theAlphabet).sLength; k++)
            if (freqs[theAlphabet->getUChar(j)]>=maxOccurences[k]) {
                for (long l=(*theAlphabet).sLength-1; l>=k+1; l--) {
                    maxOccurences[l]=maxOccurences[l-1];
                    locationsOfMaxSymbols[l]=locationsOfMaxSymbols[l-1];
                }
                maxOccurences[k]=freqs[theAlphabet->getUChar(j)];
                locationsOfMaxSymbols[k]=(*theAlphabet)[j];
                break;
            }
    }


    // compute efficiency
    //j will store the predicted bit length of the compressed string

    j = (*theAlphabet).sLength*5; // translation table size
    j=8*((j%8)?(j/8+1):j/8);

    // we are also ready to build the code table

    for (long k = 0; k<(*theAlphabet).sLength; k++) {
        long l;
        for (l=0; l<(*theAlphabet).sLength; l++)
            if ((*theAlphabet)[k]==locationsOfMaxSymbols[l]) {
                j+=(l+1)*freqs[theAlphabet->getUChar(k)];
                codeLength [locationsOfMaxSymbols[l]] = l+1;
                break;
            }
    }

//  if (j>Length()*8) return 1;
// no compression could be performed
    if (!doit) {
        return j/8.0/sLength;
    }

    _String result ((unsigned long)(j%8?j/8+1:j/8)); // allocate output string


// let's roll!!
    long csize = 0; //will indicate the current bit position in the target string
    t = 0; // current position in the string
    //first we must write out the encoding table as 5 bits of length per each

    for (j=0; j<(*theAlphabet).sLength; j++, csize+=5, t = csize/8) {
        long leftover = 8-csize%8;
        if (leftover>=5) {
            unsigned char value = result[t];
            switch (leftover) {
            case 5:
                value+=codeLength[theAlphabet->getUChar(j)];
                break;
            case 6:
                value+=codeLength[theAlphabet->getUChar(j)]*2;
                break;
            case 7:
                value+=codeLength[theAlphabet->getUChar(j)]*4;
                break;
            default:
                value+=codeLength[theAlphabet->getUChar(j)]*8;
            }
            result[t]=value;
        } else {
            result[t]+=codeLength[theAlphabet->getUChar(j)]/realPowersOf2[5-leftover];
            result[++t]=(codeLength[theAlphabet->getUChar(j)]%realPowersOf2[5-leftover])*realPowersOf2[3+leftover];
        }
    }



    //  result[++t]=0;
    // mark the end of tabular encoding
    t++;
    // now encode the actual sequence
    t*=8;
    //t+=8;

    for (j=0; j<sLength; j++) {
        WriteBitsToString (result,t,codeLength[(unsigned char)sData[j]]);
    }

    // pad the rest of the last byte in the string by ones

    if (t%8) {
        unsigned char value = result [t/8];
        value += powersOf2[7-t%8]+1;
        result[t/8]=value;
        t++;
    }

    // yahoo! we are done - store compression flag and replace the string with compressed string
    _Parameter factor = result.sLength/(_Parameter)sLength;
    if (factor<1) { // compression took place
        DuplicateErasing(&result);
        SetFlag( FREQCOMPRESSION);
        SetFlag (theAlpha);
    }
    return factor;

}
Beispiel #4
0
static struct value_defn getExpressionValue(char * assembled, unsigned int * currentPoint, unsigned int length, int threadId) {
#else
static struct value_defn getExpressionValue(char * assembled, unsigned int * currentPoint, unsigned int length) {
#endif
    struct value_defn value;

    unsigned char expressionId=getUChar(&assembled[*currentPoint]);
    *currentPoint+=sizeof(unsigned char);
    if (expressionId == INTEGER_TOKEN) {
        value.type=INT_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(int));
        *currentPoint+=sizeof(int);
    } else if (expressionId == REAL_TOKEN) {
        value.type=REAL_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(float));
        *currentPoint+=sizeof(float);
    } else if (expressionId == BOOLEAN_TOKEN) {
        value.type=BOOLEAN_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(int));
        *currentPoint+=sizeof(int);
    } else if (expressionId == STRING_TOKEN) {
        value.type=STRING_TYPE;
        char * strPtr=assembled + *currentPoint;
        cpy(&value.data, &strPtr, sizeof(char*));
        *currentPoint+=(slength(strPtr)+1);
        value.dtype=SCALAR;
    } else if (expressionId == NONE_TOKEN) {
        value.type=NONE_TYPE;
        value.dtype=SCALAR;
    } else if (expressionId ==FN_ADDR_TOKEN) {
        value.type=FN_ADDR_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(unsigned short));
        *currentPoint+=sizeof(unsigned short);
    } else if (expressionId == LET_TOKEN) {
#ifdef HOST_INTERPRETER
        *currentPoint=handleLet(assembled, *currentPoint, length, 0, threadId);
        value=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        *currentPoint=handleLet(assembled, *currentPoint, length, 0);
        value=getExpressionValue(assembled, currentPoint, length);
#endif
    } else if (expressionId == ARRAY_TOKEN) {
        int i, j, repetitionMultiplier=1, numItems=getInt(&assembled[*currentPoint]), totalSize=numItems;
        *currentPoint+=sizeof(int);
        unsigned char hasRepetition=getUChar(&assembled[*currentPoint]), ndims=1;
        *currentPoint+=sizeof(unsigned char);
        if (hasRepetition) {
#ifdef HOST_INTERPRETER
            struct value_defn repetitionV=getExpressionValue(assembled, currentPoint, length, threadId);
#else
            struct value_defn repetitionV=getExpressionValue(assembled, currentPoint, length);
#endif
            cpy(&repetitionMultiplier, repetitionV.data, sizeof(int));
            totalSize*=repetitionMultiplier;
        }
#ifdef HOST_INTERPRETER
        char * address=getHeapMemory(sizeof(unsigned char) + (sizeof(int)*(totalSize+1)), 0, threadId);
#else
        char * address=getHeapMemory(sizeof(unsigned char) + (sizeof(int)*(totalSize+1)), 0, currentSymbolEntries, symbolTable);
#endif
        cpy(value.data, &address, sizeof(char*));
        ndims=ndims | (1 << 4);
        cpy(address, &ndims, sizeof(unsigned char));
        address+=sizeof(unsigned char);
        cpy(address, &totalSize, sizeof(int));
        unsigned int prevCP=*currentPoint;
        for (j=0; j<repetitionMultiplier; j++) {
            *currentPoint=prevCP;
            for (i=0; i<numItems; i++) {
#ifdef HOST_INTERPRETER
                struct value_defn itemV=getExpressionValue(assembled, currentPoint, length, threadId);
#else
                struct value_defn itemV=getExpressionValue(assembled, currentPoint, length);
#endif
                cpy(address+((i+(j*numItems)+1) * sizeof(int)), itemV.data, sizeof(int));
                value.type=itemV.type;
            }
        }
        value.dtype=ARRAY;
    } else if (expressionId == FNCALL_TOKEN || expressionId == FNCALL_BY_VAR_TOKEN) {
#ifdef HOST_INTERPRETER
        unsigned int fnAddr;
        *currentPoint=handleFnCall(assembled, *currentPoint, &fnAddr, length, expressionId == FNCALL_BY_VAR_TOKEN ? 1:0, threadId);
        fnLevel[threadId]++;
        value=processAssembledCode(assembled, fnAddr, length, threadId);
        clearVariablesToLevel(fnLevel[threadId], threadId);
        fnLevel[threadId]--;
#else
        unsigned int fnAddr;
        *currentPoint=handleFnCall(assembled, *currentPoint, &fnAddr, length, expressionId == FNCALL_BY_VAR_TOKEN ? 1:0);
        fnLevel++;
        value=processAssembledCode(assembled, fnAddr, length);
        clearVariablesToLevel(fnLevel);
        fnLevel--;
#endif
    } else if (expressionId == NATIVE_TOKEN) {
#ifdef HOST_INTERPRETER
        *currentPoint=handleNative(assembled, *currentPoint, length, &value, threadId);
#else
        *currentPoint=handleNative(assembled, *currentPoint, length, &value);
#endif
    } else if (expressionId == IDENTIFIER_TOKEN || expressionId == ARRAYACCESS_TOKEN) {
        unsigned short variable_id=getUShort(&assembled[*currentPoint]);
        *currentPoint+=sizeof(unsigned short);
#ifdef HOST_INTERPRETER
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel[threadId], threadId, 1);
#else
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel, 1);
#endif
        if (expressionId == IDENTIFIER_TOKEN) {
            if (variableSymbol->value.dtype==SCALAR) {
                value=getVariableValue(variableSymbol, -1);
            } else if (variableSymbol->value.dtype==ARRAY) {
                value.dtype=ARRAY;
                value.type=variableSymbol->value.type;
                cpy(value.data, variableSymbol->value.data, sizeof(char*));
            }
        } else if (expressionId == ARRAYACCESS_TOKEN) {
#ifdef HOST_INTERPRETER
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length, threadId);
#else
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length);
#endif
            value=getVariableValue(variableSymbol, targetIndex);
        }
    } else if (expressionId == ADD_TOKEN || expressionId == SUB_TOKEN || expressionId == MUL_TOKEN ||
               expressionId == DIV_TOKEN || expressionId == MOD_TOKEN || expressionId == POW_TOKEN) {
#ifdef HOST_INTERPRETER
        value=computeExpressionResult(expressionId, assembled, currentPoint, length, threadId);
#else
        value=computeExpressionResult(expressionId, assembled, currentPoint, length);
#endif
    } else if (expressionId == EQ_TOKEN || expressionId == NEQ_TOKEN || expressionId == GT_TOKEN || expressionId == GEQ_TOKEN ||
               expressionId == LT_TOKEN || expressionId == LEQ_TOKEN || expressionId == IS_TOKEN) {
        *currentPoint-=sizeof(unsigned char);
#ifdef HOST_INTERPRETER
        int retVal=determine_logical_expression(assembled, currentPoint, length, threadId);
#else
        int retVal=determine_logical_expression(assembled, currentPoint, length);
#endif
        value.type=BOOLEAN_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &retVal, sizeof(int));
    }
    return value;
}

/**
 * Computes the result of a simple mathematical expression, if one is a real and the other an integer
 * then raises to be a real
 */
#ifdef HOST_INTERPRETER
static struct value_defn computeExpressionResult(unsigned char operator, char * assembled, unsigned int * currentPoint,
        unsigned int length, int threadId) {
#else
static struct value_defn computeExpressionResult(unsigned char operator, char * assembled, unsigned int * currentPoint,
        unsigned int length) {
#endif
    struct value_defn value;
#ifdef HOST_INTERPRETER
    struct value_defn v1=getExpressionValue(assembled, currentPoint, length, threadId);
    struct value_defn v2=getExpressionValue(assembled, currentPoint, length, threadId);
#else
    struct value_defn v1=getExpressionValue(assembled, currentPoint, length);
    struct value_defn v2=getExpressionValue(assembled, currentPoint, length);
#endif
    value.type=v1.type==INT_TYPE && v2.type==INT_TYPE ? INT_TYPE : v1.type==STRING_TYPE || v2.type==STRING_TYPE ? STRING_TYPE : REAL_TYPE;
    value.dtype=SCALAR;
    if (value.type==INT_TYPE) {
        int i, value1=getInt(v1.data), value2=getInt(v2.data), result;
        if (operator==ADD_TOKEN) result=value1+value2;
        if (operator==SUB_TOKEN) result=value1-value2;
        if (operator==MUL_TOKEN) result=value1*value2;
        if (operator==DIV_TOKEN) result=value1/value2;
        if (operator==MOD_TOKEN) result=value1%value2;
        if (operator==POW_TOKEN) {
            result=value2 == 0 ? 1 : value1;
            for (i=1; i<value2; i++) result=result*value1;
        }
        cpy(&value.data, &result, sizeof(int));
    } else if (value.type==REAL_TYPE) {
        float value1=getFloat(v1.data);
        float value2=getFloat(v2.data);
        float result;
        if (v1.type==INT_TYPE) value1=(float) getInt(v1.data);
        if (v2.type==INT_TYPE) {
            value2=(float) getInt(v2.data);
            if (operator == POW_TOKEN) {
                int i;
                result=value2 == 0 ? 1 : value1;
                for (i=1; i<(int) value2; i++) result=result*value1;
            }
        }
        if (operator == ADD_TOKEN) result=value1+value2;
        if (operator == SUB_TOKEN) result=value1-value2;
        if (operator == MUL_TOKEN) result=value1*value2;
        if (operator == DIV_TOKEN) result=value1/value2;
        cpy(&value.data, &result, sizeof(float));
    } else if (value.type==STRING_TYPE) {
        if (operator == ADD_TOKEN) {
#ifdef HOST_INTERPRETER
            return performStringConcatenation(v1, v2, threadId);
#else
            return performStringConcatenation(v1, v2, currentSymbolEntries, symbolTable);
#endif
        } else {
            raiseError(ERR_ONLY_ADDITION_STR);
        }
    }
    return value;
}

/**
 * Retrieves the absolute array target index based upon the provided index expression(s) and dimensions of the array itself. Does some error checking
 * to ensure that the configured values do not exceed the size
 */
#ifdef HOST_INTERPRETER
static int getArrayAccessorIndex(struct symbol_node* variableSymbol, char * assembled, unsigned int * currentPoint, unsigned int length, int threadId) {
#else
static int getArrayAccessorIndex(struct symbol_node* variableSymbol, char * assembled, unsigned int * currentPoint, unsigned int length) {
#endif
    struct value_defn index;
    int i, j, runningWeight, spec_weight, num_weights, specificIndex=0, provIdx;
    unsigned int totSize=1;
    unsigned char num_dims=getUChar(&assembled[*currentPoint]), array_dims, needsExtension=0, allowedExtension;
    *currentPoint+=sizeof(unsigned char);

    char * arraymemory;
    cpy(&arraymemory, variableSymbol->value.data, sizeof(char*));
    cpy(&array_dims, arraymemory, sizeof(unsigned char));
    allowedExtension=(array_dims >> 4) & 1;
    array_dims=array_dims&0xF;
    arraymemory+=sizeof(unsigned char);

    if (num_dims > array_dims) raiseError(ERR_TOO_MANY_ARR_INDEX);

    for (i=0; i<num_dims; i++) {
        num_weights=array_dims-(i+1);
        runningWeight=1;
        for (j=num_weights; j<0; j--) {
            cpy(&spec_weight, &arraymemory[sizeof(int) * (array_dims-j)], sizeof(int));
            runningWeight*=spec_weight;
        }
#ifdef HOST_INTERPRETER
        index=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        index=getExpressionValue(assembled, currentPoint, length);
#endif
        cpy(&spec_weight, &arraymemory[sizeof(int) * i], sizeof(int));
        totSize*=spec_weight;
        provIdx=getInt(index.data);
        if (provIdx < 0) {
            raiseError(ERR_NEG_ARR_INDEX);
        } else if (provIdx >= spec_weight) {
            if (!allowedExtension) raiseError(ERR_ARR_INDEX_EXCEED_SIZE);
            spec_weight=provIdx+1;
            cpy(&arraymemory[sizeof(int) * i], &spec_weight, sizeof(int));
            needsExtension=1;
        }
        specificIndex+=(runningWeight * provIdx);
    }
    if (needsExtension) {
        unsigned int newSize=1;
        for (i=0; i<num_dims; i++) {
            cpy(&spec_weight, &arraymemory[sizeof(int) * i], sizeof(int));
            newSize*=spec_weight;
        }
#ifdef HOST_INTERPRETER
        char * newmem=getHeapMemory((sizeof(int) * newSize) + (sizeof(int) * num_dims) + sizeof(unsigned char), 0, threadId);
#else
        char * newmem=getHeapMemory((sizeof(int) * newSize) + (sizeof(int) * num_dims) + sizeof(unsigned char), 0, currentSymbolEntries, symbolTable);
#endif
        arraymemory-=sizeof(unsigned char);
        cpy(newmem, arraymemory, (sizeof(int) * totSize) + (sizeof(int) * num_dims) + sizeof(unsigned char));
#ifdef HOST_INTERPRETER
        freeMemoryInHeap(arraymemory, threadId);
#else
        freeMemoryInHeap(arraymemory);
#endif
        cpy(variableSymbol->value.data, &newmem, sizeof(char*));
    }
    return specificIndex;
}

/**
 * Retrieves the symbol entry of a variable based upon its id
 */
#ifdef HOST_INTERPRETER
static struct symbol_node* getVariableSymbol(unsigned short id, unsigned char lvl, int threadId, int followAlias) {
#else
static struct symbol_node* getVariableSymbol(unsigned short id, unsigned char lvl, int followAlias) {
#endif
    int i;
#ifdef HOST_INTERPRETER
    for (i=0; i<=currentSymbolEntries[threadId]; i++) {
        if (symbolTable[threadId][i].id == id && symbolTable[threadId][i].state != UNALLOCATED && (symbolTable[threadId][i].level == 0 || symbolTable[threadId][i].level==lvl)) {
            if (followAlias && symbolTable[threadId][i].state == ALIAS) {
                return getVariableSymbol(symbolTable[threadId][i].alias, lvl-1, threadId, 1);
            } else {
                return &(symbolTable[threadId])[i];
            }
        }
#else
    for (i=0; i<=currentSymbolEntries; i++) {
        if (symbolTable[i].id == id && symbolTable[i].state != UNALLOCATED && (symbolTable[i].level == 0 || symbolTable[i].level==lvl)) {
            if (followAlias && symbolTable[i].state == ALIAS) {
                return getVariableSymbol(symbolTable[i].alias, lvl-1, 1);
            } else {
                return &symbolTable[i];
            }
        }
#endif
    }
    int zero=0;
#ifdef HOST_INTERPRETER
    int newEntryLocation=getSymbolTableEntryId(threadId);
    symbolTable[threadId][newEntryLocation].id=id;
    symbolTable[threadId][newEntryLocation].state=ALLOCATED;
    symbolTable[threadId][newEntryLocation].level=lvl;
    symbolTable[threadId][newEntryLocation].value.type=INT_TYPE;
    cpy(symbolTable[threadId][newEntryLocation].value.data, &zero, sizeof(int));
    return &symbolTable[threadId][newEntryLocation];
#else
    int newEntryLocation=getSymbolTableEntryId();
    symbolTable[newEntryLocation].id=id;
    symbolTable[newEntryLocation].level=lvl;
    symbolTable[newEntryLocation].state=ALLOCATED;
    symbolTable[newEntryLocation].value.type=INT_TYPE;
    symbolTable[newEntryLocation].value.dtype=SCALAR;
    cpy(symbolTable[newEntryLocation].value.data, &zero, sizeof(int));
    return &symbolTable[newEntryLocation];
#endif
}
#ifdef HOST_INTERPRETER
static int getSymbolTableEntryId(int threadId) {
#else
static int getSymbolTableEntryId(void) {
#endif
    int i;
#ifdef HOST_INTERPRETER
    for (i=0; i<=currentSymbolEntries[threadId]; i++) {
        if (symbolTable[threadId][i].state == UNALLOCATED) return i;
    }
    return ++currentSymbolEntries[threadId];
#else
    for (i=0; i<=currentSymbolEntries; i++) {
        if (symbolTable[i].state == UNALLOCATED) return i;
    }
    return ++currentSymbolEntries;
#endif
}

#ifdef HOST_INTERPRETER
static void clearVariablesToLevel(unsigned char clearLevel, int threadId) {
#else
static void clearVariablesToLevel(unsigned char clearLevel) {
#endif
    int i;
    char * smallestMemoryAddress=0, *ptr;
#ifdef HOST_INTERPRETER
    for (i=0; i<=currentSymbolEntries[threadId]; i++) {
        if (symbolTable[threadId][i].level >= clearLevel && symbolTable[threadId][i].state != UNALLOCATED) {
            symbolTable[threadId][i].state=UNALLOCATED;
            if (symbolTable[threadId][i].value.dtype==SCALAR && symbolTable[threadId][i].value.type != STRING_TYPE) {
                cpy(&ptr, symbolTable[threadId][i].value.data, sizeof(int*));
                if (ptr != 0 && (smallestMemoryAddress == 0 || smallestMemoryAddress > ptr)) smallestMemoryAddress=ptr;
            }
        }
    }
#else
    for (i=0; i<=currentSymbolEntries; i++) {
        if (symbolTable[i].level >= clearLevel && symbolTable[i].state != UNALLOCATED) {
            symbolTable[i].state=UNALLOCATED;
            if (symbolTable[i].value.dtype==SCALAR && symbolTable[i].value.type != STRING_TYPE) {
                cpy(&ptr, symbolTable[i].value.data, sizeof(char*));
                if (ptr != 0 && (smallestMemoryAddress == 0 || smallestMemoryAddress > ptr)) smallestMemoryAddress=ptr;
            }
        }
    }
#endif
    if (smallestMemoryAddress != 0) clearFreedStackFrames(smallestMemoryAddress);
}

/**
 * Sets a variables value in memory as pointed to by symbol table
 */
void setVariableValue(struct symbol_node* variableSymbol, struct value_defn value, int index) {
    variableSymbol->value.type=value.type;
    if (value.type == STRING_TYPE) {
        cpy(&variableSymbol->value.data, &value.data, sizeof(char*));
    } else {
        int currentAddress=getInt(variableSymbol->value.data);
        if (currentAddress == 0) {
            char * address=getStackMemory(sizeof(int) * index, 0);
            cpy(variableSymbol->value.data, &address, sizeof(char*));
            cpy(address+((index+1) *4), value.data, sizeof(int));
        } else {
            char * ptr;
            cpy(&ptr, variableSymbol->value.data, sizeof(char*));
            if (variableSymbol->value.dtype == ARRAY) {
                unsigned char num_dims;
                cpy(&num_dims, ptr, sizeof(unsigned char));
                num_dims=num_dims & 0xF;
                ptr+=((index+num_dims)*sizeof(int)) + sizeof(unsigned char);
            } else {
                ptr+=(index+1)*sizeof(int);
            }
            cpy(ptr, value.data, sizeof(int));
        }
    }
}

/**
 * Retrieves a variable value from memory, which the symbol table points to
 */
struct value_defn getVariableValue(struct symbol_node* variableSymbol, int index) {
    struct value_defn val;
    val.type=variableSymbol->value.type;
    val.dtype=SCALAR;
    if (variableSymbol->value.type == STRING_TYPE) {
        cpy(&val.data, &variableSymbol->value.data, sizeof(int*));
    } else {
        char * ptr;
        cpy(&ptr, variableSymbol->value.data, sizeof(char*));
        if (variableSymbol->value.dtype == ARRAY) {
            unsigned char num_dims;
            cpy(&num_dims, ptr, sizeof(unsigned char));
            num_dims=num_dims & 0xF;
            ptr+=((index+num_dims)*sizeof(int)) + sizeof(unsigned char);
        } else {
            ptr+=(index+1)*sizeof(int);
        }
        cpy(val.data, ptr, sizeof(char*));
    }
    return val;
}

static unsigned char getUChar(void* data) {
    unsigned char v;
    cpy(&v, data, sizeof(unsigned char));
    return v;
}

/**
 * Helper method to get an unsigned short from data (needed as casting to integer directly requires 4 byte alignment
 * which we do not want to enforce as it wastes memory.)
 */
static unsigned short getUShort(void* data) {
    unsigned short v;
    cpy(&v, data, sizeof(unsigned short));
    return v;
}
Beispiel #5
0
static int determine_logical_expression(char * assembled, unsigned int * currentPoint, unsigned int length, int threadId) {
#else
static int determine_logical_expression(char * assembled, unsigned int * currentPoint, unsigned int length) {
#endif
    unsigned char expressionId=getUChar(&assembled[*currentPoint]);
    *currentPoint+=sizeof(unsigned char);
    if (expressionId == AND_TOKEN || expressionId == OR_TOKEN) {
#ifdef HOST_INTERPRETER
        int s1=determine_logical_expression(assembled, currentPoint, length, threadId);
        int s2=determine_logical_expression(assembled, currentPoint, length, threadId);
#else
        int s1=determine_logical_expression(assembled, currentPoint, length);
        int s2=determine_logical_expression(assembled, currentPoint, length);
#endif
        if (expressionId == AND_TOKEN) return s1 && s2;
        if (expressionId == OR_TOKEN) return s1 || s2;
    } else if (expressionId == NOT_TOKEN) {
#ifdef HOST_INTERPRETER
        struct value_defn expression=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        struct value_defn expression=getExpressionValue(assembled, currentPoint, length);
#endif
        int value=getInt(expression.data);
        if (value > 0) return 0;
        return 1;
    } else if (expressionId == EQ_TOKEN || expressionId == NEQ_TOKEN || expressionId == GT_TOKEN || expressionId == GEQ_TOKEN ||
               expressionId == LT_TOKEN || expressionId == LEQ_TOKEN || expressionId == IS_TOKEN) {
#ifdef HOST_INTERPRETER
        struct value_defn expression1=getExpressionValue(assembled, currentPoint, length, threadId);
        struct value_defn expression2=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        struct value_defn expression1=getExpressionValue(assembled, currentPoint, length);
        struct value_defn expression2=getExpressionValue(assembled, currentPoint, length);
#endif
        if (expressionId == IS_TOKEN) {
            if (expression1.type == NONE_TYPE && expression2.type == NONE_TYPE) return 1;
            if (expression1.type != expression2.type) return 0;
            char *ptr1, *ptr2;
            cpy(&ptr1, expression1.data, sizeof(char*));
            cpy(&ptr2, expression2.data, sizeof(char*));
            return ptr1 == ptr2;
        }
        if (expression1.type == expression2.type && expression1.type == INT_TYPE) {
            int value1=getInt(expression1.data);
            int value2=getInt(expression2.data);
            if (expressionId == EQ_TOKEN) return value1 == value2;
            if (expressionId == NEQ_TOKEN) return value1 != value2;
            if (expressionId == GT_TOKEN) return value1 > value2;
            if (expressionId == GEQ_TOKEN) return value1 >= value2;
            if (expressionId == LT_TOKEN) return value1 < value2;
            if (expressionId == LEQ_TOKEN) return value1 <= value2;
        } else if ((expression1.type == REAL_TYPE || expression1.type == INT_TYPE) &&
                   (expression2.type == REAL_TYPE || expression2.type == INT_TYPE)) {
            float value1=getFloat(expression1.data);
            float value2=getFloat(expression2.data);
            if (expression1.type==INT_TYPE) value1=(float) getInt(expression1.data);
            if (expression2.type==INT_TYPE) value2=(float) getInt(expression2.data);
            if (expressionId == EQ_TOKEN) return value1 == value2;
            if (expressionId == NEQ_TOKEN) return value1 != value2;
            if (expressionId == GT_TOKEN) return value1 > value2;
            if (expressionId == GEQ_TOKEN) return value1 >= value2;
            if (expressionId == LT_TOKEN) return value1 < value2;
            if (expressionId == LEQ_TOKEN) return value1 <= value2;
        } else if (expression1.type == expression2.type && expression1.type == STRING_TYPE) {
            if (expressionId == EQ_TOKEN) {
                return checkStringEquality(expression1, expression2);
            } else if (expressionId == NEQ_TOKEN) {
                return !checkStringEquality(expression1, expression2);
            } else {
                raiseError(ERR_STR_ONLYTEST_EQ);
            }
        } else if (expression1.type == expression2.type && expression1.type == NONE_TYPE) {
            if (expressionId == EQ_TOKEN || expressionId == IS_TOKEN) {
                return 1;
            } else if (expressionId == NEQ_TOKEN) {
                return 0;
            } else {
                raiseError(ERR_NONE_ONLYTEST_EQ);
            }
        }
    } else if (expressionId == BOOLEAN_TOKEN) {
        struct value_defn value;
        cpy(value.data, &assembled[*currentPoint], sizeof(int));
        *currentPoint+=sizeof(int);
        return getInt(value.data) > 0;
    } else if (expressionId == IDENTIFIER_TOKEN || expressionId == ARRAYACCESS_TOKEN) {
        struct value_defn value;
        unsigned short variable_id=getUShort(&assembled[*currentPoint]);
        *currentPoint+=sizeof(unsigned short);
#ifdef HOST_INTERPRETER
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel[threadId], threadId, 1);
#else
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel, 1);
#endif
        value=getVariableValue(variableSymbol, -1);
        if (expressionId == ARRAYACCESS_TOKEN) {
#ifdef HOST_INTERPRETER
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length, threadId);
#else
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length);
#endif
            value=getVariableValue(variableSymbol, targetIndex);
        }
        if (value.type == BOOLEAN_TYPE) {
            return getInt(value.data) > 0;
        }
        return 0;
    } else {
        *currentPoint-=sizeof(unsigned char);
        struct value_defn expValue;
#ifdef HOST_INTERPRETER
        expValue=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        expValue=getExpressionValue(assembled, currentPoint, length);
#endif
        if (expValue.type == BOOLEAN_TYPE || expValue.type == INT_TYPE) {
            return getInt(expValue.data) > 0;
        }
    }
    return 0;
}
Beispiel #6
0
static unsigned int handleGoto(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) {
#else
static unsigned int handleGoto(char * assembled, unsigned int currentPoint, unsigned int length) {
#endif
    return getUShort(&assembled[currentPoint]);
}

#ifdef HOST_INTERPRETER
static unsigned int handleNative(char * assembled, unsigned int currentPoint, unsigned int length, struct value_defn * returnValue, int threadId) {
#else
static unsigned int handleNative(char * assembled, unsigned int currentPoint, unsigned int length, struct value_defn * returnValue) {
#endif
    unsigned char fnCode=getUChar(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned char);
    unsigned short numArgs=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);

    struct value_defn toPassValues[numArgs];
    int i;
    for (i=0; i<numArgs; i++) {
#ifdef HOST_INTERPRETER
        toPassValues[i]=getExpressionValue(assembled, &currentPoint, length, threadId);
#else
        toPassValues[i]=getExpressionValue(assembled, &currentPoint, length);
#endif
    }
    if (returnValue != NULL) {
#ifdef HOST_INTERPRETER
        callNativeFunction(returnValue, fnCode, numArgs, toPassValues, numActiveCores[threadId], localCoreId[threadId], currentSymbolEntries[threadId], symbolTable[threadId], threadId);
#else
        callNativeFunction(returnValue, fnCode, numArgs, toPassValues, numActiveCores, localCoreId, currentSymbolEntries, symbolTable);
#endif
    } else {
        struct value_defn dummy;
#ifdef HOST_INTERPRETER
        callNativeFunction(&dummy, fnCode, numArgs, toPassValues, numActiveCores[threadId], localCoreId[threadId], currentSymbolEntries[threadId], symbolTable[threadId], threadId);
#else
        callNativeFunction(&dummy, fnCode, numArgs, toPassValues, numActiveCores, localCoreId, currentSymbolEntries, symbolTable);
#endif
    }
    return currentPoint;
}

/**
 * Calls some function and stores the call point in the function call stack for returning from this function
 */
#ifdef HOST_INTERPRETER
static unsigned int handleFnCall(char * assembled, unsigned int currentPoint, unsigned int * functionAddress, unsigned int length, char calledByVar, int threadId) {
#else
static unsigned int handleFnCall(char * assembled, unsigned int currentPoint, unsigned int * functionAddress, unsigned int length, char calledByVar) {
#endif
    unsigned short fnAddress;
    if (calledByVar) {
#ifdef HOST_INTERPRETER
        struct symbol_node* callVar=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel[threadId], threadId, 1);
#else
        struct symbol_node* callVar=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel, 1);
#endif
        if (callVar->value.type != FN_ADDR_TYPE) raiseError(ERR_FNCALL_VAR_NOT_CONTAINING_FN_PTR);
        char *ptr;
        cpy(&ptr, callVar->value.data, sizeof(char*));
        fnAddress=getUShort(ptr);
    } else {
        fnAddress=getUShort(&assembled[currentPoint]);
    }
    currentPoint+=sizeof(unsigned short);

    unsigned short fnNumArgs=getUShort(&assembled[fnAddress]);
    fnAddress+=sizeof(unsigned short);

    unsigned short callerNumArgs=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);
    struct symbol_node* srcSymbol, *targetSymbol;
    int i, numArgs;
    numArgs=fnNumArgs > callerNumArgs ? fnNumArgs : callerNumArgs;
    for (i=0; i<numArgs; i++) {
        if (i<callerNumArgs && i<fnNumArgs) {
#ifdef HOST_INTERPRETER
            srcSymbol=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel[threadId], threadId, 0);
            targetSymbol=getVariableSymbol(getUShort(&assembled[fnAddress]), fnLevel[threadId]+1, threadId, 0);
#else
            srcSymbol=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel, 0);
            targetSymbol=getVariableSymbol(getUShort(&assembled[fnAddress]), fnLevel+1, 0);
#endif
            targetSymbol->state=ALIAS;
            targetSymbol->alias=srcSymbol->id;
        }
        if (i<callerNumArgs) currentPoint+=sizeof(unsigned short);
        if (i<fnNumArgs) fnAddress+=sizeof(unsigned short);
    }
    *functionAddress=fnAddress;
    return currentPoint;
}

/**
 * Loop iteration
 */
#ifdef HOST_INTERPRETER
static unsigned int handleFor(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) {
#else
static unsigned int handleFor(char * assembled, unsigned int currentPoint, unsigned int length) {
#endif
    unsigned short loopIncrementerId=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);
    unsigned short loopVariantId=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);
#ifdef HOST_INTERPRETER
    struct symbol_node* incrementVarSymbol=getVariableSymbol(loopIncrementerId, fnLevel[threadId], threadId, 1);
    struct symbol_node* variantVarSymbol=getVariableSymbol(loopVariantId, fnLevel[threadId], threadId, 1);
    struct value_defn expressionVal=getExpressionValue(assembled, &currentPoint, length, threadId);
#else
    struct symbol_node* incrementVarSymbol=getVariableSymbol(loopIncrementerId, fnLevel, 1);
    struct symbol_node* variantVarSymbol=getVariableSymbol(loopVariantId, fnLevel, 1);
    struct value_defn expressionVal=getExpressionValue(assembled, &currentPoint, length);
#endif
    unsigned short blockLen=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);

    char * ptr;
    int singleSize, arrSize=1, i, headersize;
    unsigned char numDims;
    cpy(&ptr, expressionVal.data, sizeof(char*));
    cpy(&numDims, ptr, sizeof(unsigned char));
    numDims=numDims & 0xF;
    for (i=0; i<numDims; i++) {
        cpy(&singleSize, &ptr[1+(i*sizeof(unsigned int))], sizeof(unsigned int));
        arrSize*=singleSize;
    }
    headersize=sizeof(unsigned char) + (sizeof(unsigned int) * numDims);
    struct value_defn varVal=getVariableValue(incrementVarSymbol, -1);
    int incrementVal=getInt(varVal.data);
    if (incrementVal < arrSize) {
        struct value_defn nextElement;
        nextElement.type=expressionVal.type;
        cpy(&nextElement.data, ptr+((incrementVal*sizeof(int)) + headersize), sizeof(int));
        setVariableValue(variantVarSymbol, nextElement, -1);
        return currentPoint;
    }
    currentPoint+=(blockLen+sizeof(unsigned short)+sizeof(unsigned char));
    return currentPoint;
}

/**
 * Conditional, with or without else block
 */
#ifdef HOST_INTERPRETER
static unsigned int handleIf(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) {
    int conditionalResult=determine_logical_expression(assembled, &currentPoint, length, threadId);
#else
static unsigned int handleIf(char * assembled, unsigned int currentPoint, unsigned int length) {
    int conditionalResult=determine_logical_expression(assembled, &currentPoint, length);
#endif
    if (conditionalResult) return currentPoint+sizeof(unsigned short);
    unsigned short blockLen=getUShort(&assembled[currentPoint]);
    return currentPoint+sizeof(unsigned short)+blockLen;
}