/** * Checks whether the core has sent some command to the host and actions this command if so */ static void checkStatusFlagsOfCore(struct shared_basic * basicState, struct interpreterconfiguration* configuration, int coreId) { char updateCoreWithComplete=0; if (basicState->core_ctrl[coreId].core_busy == 0) { if (basicState->core_ctrl[coreId].core_run == 0) { deactivateCore(configuration, coreId); } else if (basicState->core_ctrl[coreId].core_command == 1) { displayCoreMessage(coreId, &basicState->core_ctrl[coreId]); updateCoreWithComplete=1; } else if (basicState->core_ctrl[coreId].core_command == 2) { inputCoreMessage(coreId, &basicState->core_ctrl[coreId]); updateCoreWithComplete=1; } else if (basicState->core_ctrl[coreId].core_command == 3) { raiseError(coreId, &basicState->core_ctrl[coreId]); updateCoreWithComplete=1; } else if (basicState->core_ctrl[coreId].core_command == 4) { stringConcatenate(coreId, &basicState->core_ctrl[coreId]); updateCoreWithComplete=1; } else if (basicState->core_ctrl[coreId].core_command >= 1000) { performMathsOp(&basicState->core_ctrl[coreId]); updateCoreWithComplete=1; } if (updateCoreWithComplete) { basicState->core_ctrl[coreId].core_command=0; basicState->core_ctrl[coreId].core_busy=++pb[coreId]; } } }
static int handleSend(char * assembled, int currentPoint, int threadId) { struct value_defn to_send_expression=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn target_expression=getExpressionValue(assembled, ¤tPoint, threadId); sendData(to_send_expression, getInt(target_expression.data), threadId, hostCoresBasePid); #else static int handleSend(char * assembled, int currentPoint) { struct value_defn to_send_expression=getExpressionValue(assembled, ¤tPoint); struct value_defn target_expression=getExpressionValue(assembled, ¤tPoint); sendData(to_send_expression, getInt(target_expression.data)); #endif return currentPoint; } /** * A reduction operation - collective communication between cores */ #ifdef HOST_INTERPRETER static int handleReduction(char * assembled, int currentPoint, int threadId) { #else static int handleReduction(char * assembled, int currentPoint) { #endif unsigned short reductionOperator=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn broadcast_expression=getExpressionValue(assembled, ¤tPoint, threadId); variableSymbol->value=reduceData(broadcast_expression, reductionOperator, threadId, numActiveCores[threadId], hostCoresBasePid); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn broadcast_expression=getExpressionValue(assembled, ¤tPoint); variableSymbol->value=reduceData(broadcast_expression, reductionOperator, numActiveCores); #endif return currentPoint; } /** * Broadcast collective communication */ #ifdef HOST_INTERPRETER static int handleBcast(char * assembled, int currentPoint, int threadId) { #else static int handleBcast(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn broadcast_expression=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn source_expression=getExpressionValue(assembled, ¤tPoint, threadId); variableSymbol->value=bcastData(broadcast_expression, getInt(source_expression.data), threadId, numActiveCores[threadId], hostCoresBasePid); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn broadcast_expression=getExpressionValue(assembled, ¤tPoint); struct value_defn source_expression=getExpressionValue(assembled, ¤tPoint); variableSymbol->value=bcastData(broadcast_expression, getInt(source_expression.data), numActiveCores); #endif return currentPoint; } /** * Receiving some data from another core */ #ifdef HOST_INTERPRETER static int handleRecv(char * assembled, int currentPoint, int threadId) { #else static int handleRecv(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn source_expression=getExpressionValue(assembled, ¤tPoint, threadId); variableSymbol->value=recvData(getInt(source_expression.data), threadId, hostCoresBasePid); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn source_expression=getExpressionValue(assembled, ¤tPoint); variableSymbol->value=recvData(getInt(source_expression.data)); #endif return currentPoint; } /** * Receiving some data from another core and placing this into an array structure */ #ifdef HOST_INTERPRETER static int handleRecvToArray(char * assembled, int currentPoint, int threadId) { #else static int handleRecvToArray(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn index=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn source_expression=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn retrievedData=recvData(getInt(source_expression.data), threadId, hostCoresBasePid); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn index=getExpressionValue(assembled, ¤tPoint); struct value_defn source_expression=getExpressionValue(assembled, ¤tPoint); struct value_defn retrievedData=recvData(getInt(source_expression.data)); #endif variableSymbol->value.type=retrievedData.type; char * ptr; cpy(&ptr, variableSymbol->value.data, sizeof(int*)); cpy(ptr+(getInt(index.data) *4), retrievedData.data, 4); return currentPoint; } /** * Handles the sendrecv call, which does both P2P in one action with 1 synchronisation */ #ifdef HOST_INTERPRETER static int handleSendRecv(char * assembled, int currentPoint, int threadId) { #else static int handleSendRecv(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn tosend_expression=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn target_expression=getExpressionValue(assembled, ¤tPoint, threadId); variableSymbol->value=sendRecvData(tosend_expression, getInt(target_expression.data), threadId, hostCoresBasePid); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn tosend_expression=getExpressionValue(assembled, ¤tPoint); struct value_defn target_expression=getExpressionValue(assembled, ¤tPoint); variableSymbol->value=sendRecvData(tosend_expression, getInt(target_expression.data)); #endif return currentPoint; } /** * Handles the sendrecv call into an array, which does both P2P in one action with 1 synchronisation */ #ifdef HOST_INTERPRETER static int handleSendRecvArray(char * assembled, int currentPoint, int threadId) { #else static int handleSendRecvArray(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn index=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn tosend_expression=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn target_expression=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn retrievedData=sendRecvData(tosend_expression, getInt(target_expression.data), threadId, hostCoresBasePid); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn index=getExpressionValue(assembled, ¤tPoint); struct value_defn tosend_expression=getExpressionValue(assembled, ¤tPoint); struct value_defn target_expression=getExpressionValue(assembled, ¤tPoint); struct value_defn retrievedData=sendRecvData(tosend_expression, getInt(target_expression.data)); #endif variableSymbol->value.type=retrievedData.type; char * ptr; cpy(&ptr, variableSymbol->value.data, sizeof(int*)); cpy(ptr+(getInt(index.data) *4), retrievedData.data, 4); return currentPoint; } /** * Goto some absolute location in the byte code */ #ifdef HOST_INTERPRETER static int handleGoto(char * assembled, int currentPoint, int threadId) { #else static int handleGoto(char * assembled, int currentPoint) { #endif return getUShort(&assembled[currentPoint]); } /** * Loop iteration */ #ifdef HOST_INTERPRETER static int handleFor(char * assembled, int currentPoint, int threadId) { #else static int handleFor(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn to_expression=getExpressionValue(assembled, ¤tPoint, threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn to_expression=getExpressionValue(assembled, ¤tPoint); #endif unsigned short blockLen=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); if (getInt(variableSymbol->value.data) <= getInt(to_expression.data)) return currentPoint; currentPoint+=blockLen+sizeof(unsigned short)*2; return currentPoint; } /** * Conditional, with or without else block */ #ifdef HOST_INTERPRETER static int handleIf(char * assembled, int currentPoint, int threadId) { int conditionalResult=determine_logical_expression(assembled, ¤tPoint, threadId); #else static int handleIf(char * assembled, int currentPoint) { int conditionalResult=determine_logical_expression(assembled, ¤tPoint); #endif if (conditionalResult) return currentPoint+sizeof(unsigned short); unsigned short blockLen=getUShort(&assembled[currentPoint]); return currentPoint+sizeof(unsigned short)+blockLen; } /** * Input from user without string to display */ #ifdef HOST_INTERPRETER static int handleInput(char * assembled, int currentPoint, int threadId) { #else static int handleInput(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); variableSymbol->value=getInputFromUser(threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); variableSymbol->value=getInputFromUser(); #endif return currentPoint; } /** * Input from user with string to display */ #ifdef HOST_INTERPRETER static int handleInputWithString(char * assembled, int currentPoint, int threadId) { #else static int handleInputWithString(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn string_display=getExpressionValue(assembled, ¤tPoint, threadId); variableSymbol->value=getInputFromUserWithString(string_display, threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn string_display=getExpressionValue(assembled, ¤tPoint); variableSymbol->value=getInputFromUserWithString(string_display); #endif return currentPoint; } /** * Print some value to the user */ #ifdef HOST_INTERPRETER static int handlePrint(char * assembled, int currentPoint, int threadId) { struct value_defn result=getExpressionValue(assembled, ¤tPoint, threadId); displayToUser(result, threadId); #else static int handlePrint(char * assembled, int currentPoint) { struct value_defn result=getExpressionValue(assembled, ¤tPoint); displayToUser(result); #endif return currentPoint; } /** * Declaration of an array and whether it is to be in default (core local) or shared memory */ #ifdef HOST_INTERPRETER static int handleDimArray(char * assembled, int currentPoint, char inSharedMemory, int threadId) { #else static int handleDimArray(char * assembled, int currentPoint, char inSharedMemory) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn size=getExpressionValue(assembled, ¤tPoint, threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn size=getExpressionValue(assembled, ¤tPoint); #endif variableSymbol->value.type=INT_TYPE; int * address=getArrayAddress(getInt(size.data), inSharedMemory); cpy(variableSymbol->value.data, &address, sizeof(int*)); return currentPoint; } /** * Set an individual element of an array */ #ifdef HOST_INTERPRETER static int handleArraySet(char * assembled, int currentPoint, int threadId) { #else static int handleArraySet(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); struct value_defn index=getExpressionValue(assembled, ¤tPoint, threadId); struct value_defn value=getExpressionValue(assembled, ¤tPoint, threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); struct value_defn index=getExpressionValue(assembled, ¤tPoint); struct value_defn value=getExpressionValue(assembled, ¤tPoint); #endif variableSymbol->value.type=value.type; char * ptr; cpy(&ptr, variableSymbol->value.data, sizeof(int*)); cpy(ptr+(getInt(index.data) *4), value.data, 4); return currentPoint; } /** * Set a scalar value (held in the symbol table) */ #ifdef HOST_INTERPRETER static int handleLet(char * assembled, int currentPoint, int threadId) { #else static int handleLet(char * assembled, int currentPoint) { #endif unsigned short varId=getUShort(&assembled[currentPoint]); currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER struct symbol_node* variableSymbol=getVariableSymbol(varId, threadId); variableSymbol->value=getExpressionValue(assembled, ¤tPoint, threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(varId); variableSymbol->value=getExpressionValue(assembled, ¤tPoint); #endif return currentPoint; } /** * Determines a logical expression based upon two operands and an operator */ #ifdef HOST_INTERPRETER static int determine_logical_expression(char * assembled, int * currentPoint, int threadId) { #else static int determine_logical_expression(char * assembled, int * currentPoint) { #endif unsigned short expressionId=getUShort(&assembled[*currentPoint]); *currentPoint+=sizeof(unsigned short); if (expressionId == AND_TOKEN || expressionId == OR_TOKEN) { #ifdef HOST_INTERPRETER int s1=determine_logical_expression(assembled, currentPoint, threadId); int s2=determine_logical_expression(assembled, currentPoint, threadId); #else int s1=determine_logical_expression(assembled, currentPoint); int s2=determine_logical_expression(assembled, currentPoint); #endif if (expressionId == AND_TOKEN) return s1 && s2; if (expressionId == OR_TOKEN) return s1 || s2; } else if (expressionId == EQ_TOKEN || expressionId == NEQ_TOKEN || expressionId == GT_TOKEN || expressionId == GEQ_TOKEN || expressionId == LT_TOKEN || expressionId == LEQ_TOKEN) { #ifdef HOST_INTERPRETER struct value_defn expression1=getExpressionValue(assembled, currentPoint, threadId); struct value_defn expression2=getExpressionValue(assembled, currentPoint, threadId); #else struct value_defn expression1=getExpressionValue(assembled, currentPoint); struct value_defn expression2=getExpressionValue(assembled, currentPoint); #endif 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 { raiseError("Can only test for equality with strings"); } } } else if (expressionId == ISHOST_TOKEN) { #ifdef HOST_INTERPRETER return 1; #else return 0; #endif } else if (expressionId == ISDEVICE_TOKEN) { #ifdef HOST_INTERPRETER return 0; #else return 1; #endif } return 0; } /** * Gets the value of an expression, which is number, string, identifier or mathematical */ #ifdef HOST_INTERPRETER static struct value_defn getExpressionValue(char * assembled, int * currentPoint, int threadId) { #else static struct value_defn getExpressionValue(char * assembled, int * currentPoint) { #endif struct value_defn value; unsigned short expressionId=getUShort(&assembled[*currentPoint]); *currentPoint+=sizeof(unsigned short); if (expressionId == INTEGER_TOKEN) { value.type=INT_TYPE; cpy(value.data, &assembled[*currentPoint], sizeof(int)); *currentPoint+=sizeof(int); } else if (expressionId == REAL_TOKEN) { value.type=REAL_TYPE; cpy(value.data, &assembled[*currentPoint], sizeof(float)); *currentPoint+=sizeof(float); } else if (expressionId == STRING_TOKEN) { value.type=STRING_TYPE; char * strPtr=assembled + *currentPoint; cpy(&value.data, &strPtr, sizeof(char*)); *currentPoint+=(slength(strPtr)+1); } else if (expressionId == COREID_TOKEN) { value.type=INT_TYPE; #ifdef HOST_INTERPRETER cpy(value.data, &localCoreId[threadId], sizeof(int)); #else cpy(value.data, &localCoreId, sizeof(int)); #endif } else if (expressionId == NUMCORES_TOKEN) { value.type=INT_TYPE; #ifdef HOST_INTERPRETER cpy(value.data, &numActiveCores[threadId], sizeof(int)); #else cpy(value.data, &numActiveCores, sizeof(int)); #endif } else if (expressionId == RANDOM_TOKEN) { value=performMathsOp(RANDOM_MATHS_OP, value); } else if (expressionId == MATHS_TOKEN) { unsigned short maths_op=getUShort(&assembled[*currentPoint]); *currentPoint+=sizeof(unsigned short); #ifdef HOST_INTERPRETER value=performMathsOp(maths_op, getExpressionValue(assembled, currentPoint, threadId)); #else value=performMathsOp(maths_op, getExpressionValue(assembled, currentPoint)); #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, threadId); #else struct symbol_node* variableSymbol=getVariableSymbol(variable_id); #endif value=variableSymbol->value; if (expressionId == ARRAYACCESS_TOKEN) { #ifdef HOST_INTERPRETER struct value_defn index=getExpressionValue(assembled, currentPoint, threadId); #else struct value_defn index=getExpressionValue(assembled, currentPoint); #endif char * ptr; cpy(&ptr, variableSymbol->value.data, sizeof(int*)); cpy(&value.data, ptr+(getInt(index.data) *4), sizeof(int)); } } 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, threadId); #else value=computeExpressionResult(expressionId, assembled, currentPoint); #endif } 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 short operator, char * assembled, int * currentPoint, int threadId) { #else static struct value_defn computeExpressionResult(unsigned short operator, char * assembled, int * currentPoint) { #endif struct value_defn value; #ifdef HOST_INTERPRETER struct value_defn v1=getExpressionValue(assembled, currentPoint, threadId); struct value_defn v2=getExpressionValue(assembled, currentPoint, threadId); #else struct value_defn v1=getExpressionValue(assembled, currentPoint); struct value_defn v2=getExpressionValue(assembled, currentPoint); #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; 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=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=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) { return performStringConcatenation(v1, v2); } else { raiseError("Can only perform addition with strings"); } } return value; } /** * Retrieves the symbol entry of a variable based upon its id */ #ifdef HOST_INTERPRETER static struct symbol_node* getVariableSymbol(unsigned short id, int threadId) { #else static struct symbol_node* getVariableSymbol(unsigned short id) { #endif int i; #ifdef HOST_INTERPRETER for (i=0;i<currentSymbolEntries[threadId];i++) { if (symbolTable[threadId][i].id == id) return &(symbolTable[threadId])[i]; #else for (i=0;i<currentSymbolEntries;i++) { if (symbolTable[i].id == id) return &symbolTable[i]; #endif } int zero=0; #ifdef HOST_INTERPRETER symbolTable[threadId][currentSymbolEntries[threadId]].id=id; symbolTable[threadId][currentSymbolEntries[threadId]].value.type=INT_TYPE; cpy(symbolTable[threadId][currentSymbolEntries[threadId]].value.data, &zero, sizeof(int)); return &symbolTable[threadId][currentSymbolEntries[threadId]++]; #else symbolTable[currentSymbolEntries].id=id; symbolTable[currentSymbolEntries].value.type=INT_TYPE; cpy(symbolTable[currentSymbolEntries].value.data, &zero, sizeof(int)); return &symbolTable[currentSymbolEntries++]; #endif } /** * Helper method to get an integer from data (needed as casting to integer directly requires 4 byte alignment which we * do not want to enforce as it wastes memory.) */ static int getInt(void* data) { int v; cpy(&v, data, sizeof(int)); return v; } /** * Helper method to get a float from data (needed as casting to integer directly requires 4 byte alignment which we * do not want to enforce as it wastes memory.) */ static float getFloat(void* data) { float v; cpy(&v, data, sizeof(float)); 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; }