int countSlots(OperandStack* p1,int argNumber) { OperandStack* p2; Operand operand; int i, slots = 0; stackInit(&p2); for (i = 0; i < argNumber; i++, slots++) { operand = popOperand(&p1); pushOperand(&p2, operand); if (operand.type32_64 == CAT2) slots++; } for (i = 0; i < argNumber; i++) { pushOperand(&p1, popOperand(&p2)); } return slots; }
/** * reverseStack loops through the entire Stacks linked list and placing all the * content into a new created Stack, that way reversing the content of the * Stack. * * @param **head - The target Stack to loop through its linked elements. And * place in reversed order. */ void reverseStack(Stack **head) { Stack *newStack = (Stack *) malloc(sizeof(Stack)); while (*head) { switch ((*head)->opType) { case operand: if ((*head)->operand != 0) { pushOperand(&newStack, operand, (*head)->operand); } break; case constant: break; case unaryOperation: pushUnaryOp(&newStack, unaryOperation, (*head)->UnaryOperation, (*head)->symbol); break; case binaryOperation: pushBinaryOp(&newStack, binaryOperation, (*head)->BinaryOperation, (*head)->symbol); break; } pop(head); } *head = newStack; }
void select(NoImm) { const ValueType condition = popOperand(); const ValueType falseType = popOperand(); const ValueType trueType = popOperand(); validateOperandType(ValueType::i32,condition,"select condition"); validateOperandType(falseType,trueType,"select operands"); pushOperand(falseType); }
void call_indirect(CallIndirectImm imm) { VALIDATE_INDEX(imm.type.index,module.types.size()); VALIDATE_UNLESS("call_indirect is only valid if there is a default function table: ",module.tables.size()==0); const FunctionType* calleeType = module.types[imm.type.index]; popAndValidateOperand("call_indirect function index",ValueType::i32); popAndValidateOperands("call_indirect arguments",calleeType->parameters.data(),(Uptr)calleeType->parameters.size()); pushOperand(calleeType->ret); }
void popControlStack(bool isElse = false) { VALIDATE_UNLESS("stack was not empty at end of control structure: ",stack.size() > controlStack.back().outerStackSize); if(isElse && controlStack.back().type == ControlContext::Type::ifThen) { controlStack.back().type = ControlContext::Type::ifElse; controlStack.back().isReachable = true; } else { VALIDATE_UNLESS("else only allowed in if context: ",isElse); const ResultType resultType = controlStack.back().resultType; if(controlStack.back().type == ControlContext::Type::ifThen && resultType != ResultType::none) { throw ValidationException("else-less if may not yield a result"); } controlStack.pop_back(); if(controlStack.size()) { pushOperand(resultType); } } }
/* * calculate * Calculates an parsed expression using one stack for the operations and * two stack for the operands and operators. * * @param **OpStack - The stack of operations. * @param **OperandStack - The stack of operands. */ double calculate(Stack **OpStack, Stack **OperandStack) { double result = 0; Stack *current = *OpStack; for (; current; current = current->next) { switch (current->opType) { case binaryOperation: //Result is always the result of the lastest made operation result = current->BinaryOperation(pop(OperandStack), pop(OperandStack)); printf("Current result: %f\n", result); //Pushes the latest result to the operand stack incase it should be used again. pushOperand(OperandStack, operand, result); break; default: printf("Something else than an operation was found here..\n"); break; } } return result; }
//-------------------------------------------------------------------- // EXTERNAL FUNCTIONS //-------------------------------------------------------------------- int8_t execute(dvm_state_t* dvm_st, DvmState *eventState) { DVMBasiclib_state_t *s = (&dvm_st->basiclib_st); DvmContext *context = &(eventState->context); while ((context->state == DVM_STATE_RUN) && (context->num_executed < DVM_CPU_SLICE)) { DvmOpcode instr = getOpcode(dvm_st, context->which, context->pc); DEBUG("-----------------------------------------------\n"); DEBUG("[BASIC_LIB] execute: (%d) PC: %d. INSTR: %d\n",context->which, context->pc, instr); if(instr & LIB_ID_BIT) { //Extension Library opcode encountered return SOS_OK; } context->num_executed++; switch(instr) { case OP_START: { __asm __volatile("__sleep_measure_start:"); context->pc += 1; break; } case OP_STOP: { context->pc += 1; break; } case OP_HALT: { DEBUG("<<<<<<<<<<<=====================>>>>>>>>>>>\n"); DEBUG("[BASIC_LIB] execute: (%d): HALT executed.\n", (int)context->which); haltContext(dvm_st, context); context->state = DVM_STATE_HALT; context->pc = 0; break; } case OP_LED: { DvmStackVariable* arg = popOperand( eventState); led_op(arg->value.var); context->pc += 1; break; } case OP_GETVAR + 0: case OP_GETVAR + 1: case OP_GETVAR + 2: case OP_GETVAR + 3: case OP_GETVAR + 4: case OP_GETVAR + 5: case OP_GETVAR + 6: case OP_GETVAR + 7: { uint8_t arg = instr - OP_GETVAR; DEBUG("[BASIC_LIB] execute: OPGETVAR (%d):: Pushing value %d.\n", (int)arg,(int)s->shared_vars[arg].value.var); pushOperand( eventState, &s->shared_vars[arg]); context->pc += 1; break; } case OP_SETVAR + 0: case OP_SETVAR + 1: case OP_SETVAR + 2: case OP_SETVAR + 3: case OP_SETVAR + 4: case OP_SETVAR + 5: case OP_SETVAR + 6: case OP_SETVAR + 7: { uint8_t arg = instr - OP_SETVAR; DvmStackVariable* var = popOperand( eventState); DEBUG("[BASIC_LIB] execute: OPSETVAR (%d):: Setting value to %d.\n",(int)arg,(int)var->value.var); s->shared_vars[arg] = *var; context->pc += 1; break; } case OP_GETVARF + 0: case OP_GETVARF + 1: case OP_GETVARF + 2: case OP_GETVARF + 3: case OP_GETVARF + 4: case OP_GETVARF + 5: case OP_GETVARF + 6: case OP_GETVARF + 7: { // Use for type casting an integer shared var to float uint8_t arg = instr - OP_GETVARF; int32_t res = 0; uint16_t res_part = 0; DEBUG("[BASIC_LIB] execute: OPGETVARF (%d):: Pushing value %d.\n", (int)arg,(int)s->shared_vars[arg].value.var); res = (int32_t)(s->shared_vars[arg].value.var * FLOAT_PRECISION); res_part = res & 0xFFFF; pushValue( eventState, res_part, DVM_TYPE_FLOAT_DEC); res_part = res >> 16; pushValue( eventState, res_part, DVM_TYPE_FLOAT); context->pc += 1; break; } case OP_SETVARF + 0: case OP_SETVARF + 1: case OP_SETVARF + 2: case OP_SETVARF + 3: case OP_SETVARF + 4: case OP_SETVARF + 5: case OP_SETVARF + 6: { // Type-casting an integer to float and saving it in shared var uint8_t arg = instr - OP_SETVARF; DvmStackVariable* var = popOperand( eventState); int32_t res = 0; uint16_t res_part; DEBUG("[BASIC_LIB] execute: OPSETVARF (%d):: Setting value to %d.\n",(int)arg,(int)var->value.var); res = (int32_t)(var->value.var * FLOAT_PRECISION); res_part = res & 0xFFFF; s->shared_vars[arg+1].type = DVM_TYPE_FLOAT_DEC; s->shared_vars[arg+1].value.var = res_part; res_part = res >> 16; s->shared_vars[arg].type = DVM_TYPE_FLOAT; s->shared_vars[arg].value.var = res_part; context->pc += 1; break; } case OP_SETTIMER + 0: case OP_SETTIMER + 1: case OP_SETTIMER + 2: case OP_SETTIMER + 3: case OP_SETTIMER + 4: case OP_SETTIMER + 5: case OP_SETTIMER + 6: case OP_SETTIMER + 7: { uint32_t msec; uint8_t timerID = instr - OP_SETTIMER; DvmStackVariable* arg = popOperand( eventState); DEBUG("[BASIC_LIB] execute: Setting Timer %d period to %d.\n", timerID, arg->value.var); //msec = 102 * arg->value.var + (4 * arg->value.var) / 10; // Set the timer timeout argument in seconds msec = arg->value.var * 4;// * 1000; DEBUG("[BASIC_LIB] execute: <<<<< WARNING - Timer %d not being stopped >>>>\n", timerID); // sys_timer_stop(timerID); if (msec > 0) { // Ram - Where is the init ?? sys_timer_start(timerID, msec, TIMER_REPEAT); DEBUG("[BASIC_LIB] execute: Timer ID: %d started. Period: %d msec.\n", timerID, msec); } context->pc += 1; break; } case OP_RAND: { DvmStackVariable* arg = popOperand( eventState); uint16_t rnd; rnd = sys_rand() % arg->value.var; pushValue( eventState, rnd, DVM_TYPE_INTEGER); context->pc += 1; break; } /* case OP_JMP: case OP_JNZ: case OP_JZ: case OP_JG: case OP_JGE: case OP_JL: case OP_JLE: case OP_JE: case OP_JNE: case OP_ADD: case OP_SUB: case OP_DIV: case OP_MUL: case OP_ABS: case OP_MOD: case OP_INCR: case OP_DECR: { mathlib_executeDL(s->mathlib_execute, eventState, instr); break; } */ // Math Lib case OP_ADD: case OP_SUB: case OP_DIV: case OP_MUL: { DvmStackVariable* arg1 = popOperand( eventState); DvmStackVariable* arg2 = popOperand( eventState); DvmStackVariable* arg3 = NULL, *arg4 = NULL; int32_t fl_arg1, fl_arg2; int32_t res = 0; uint16_t res_part; int16_t int_res = 0; if (arg1->type == DVM_TYPE_FLOAT) { fl_arg1 = convert_to_float(arg1, arg2); arg3 = popOperand( eventState); if (arg3->type == DVM_TYPE_FLOAT) { // FLOAT <op> FLOAT arg4 = popOperand( eventState); fl_arg2 = convert_to_float(arg3, arg4); if(instr == OP_ADD) { res = (int32_t)(fl_arg1 + fl_arg2); DEBUG("[BASIC_LIB] execute: FLOAT ADD FLOAT %d\n", res); } else if(instr == OP_SUB) { res = (int32_t)(fl_arg1 - fl_arg2); DEBUG("[BASIC_LIB] execute: FLOAT SUB FLOAT %d\n", res); } else if(instr == OP_DIV) { res = (int32_t)((fl_arg1 * FLOAT_PRECISION) / fl_arg2); DEBUG("[BASIC_LIB] execute: FLOAT DIV FLOAT: %d\n", res); } else if(instr == OP_MUL) { res = (int32_t)((fl_arg1 * fl_arg2) / FLOAT_PRECISION); DEBUG("[BASIC_LIB] execute: FLOAT MULT FLOAT %d\n", res); } } else { // FLOAT <OP> INTEGER if(instr == OP_ADD) { res = (int32_t)(fl_arg1 + (arg3->value.var * FLOAT_PRECISION)); DEBUG("[BASIC_LIB] execute: FLOAT ADD INT: %d\n", res); } else if(instr == OP_SUB) { res = (int32_t)(fl_arg1 - (arg3->value.var * FLOAT_PRECISION)); DEBUG("[BASIC_LIB] execute: FLOAT SUB INT: %d\n", res); } else if(instr == OP_DIV) { res = (int32_t)(fl_arg1 / arg3->value.var); DEBUG("[BASIC_LIB] execute: FLOAT DIV INT: %d\n", res); sys_led(LED_RED_TOGGLE); #ifdef OUTLIER_SCRIPT_DBG int32_t* post_avg; post_avg = (int32_t*)sys_malloc(sizeof(int32_t)); *post_avg = res; sys_post_uart(OUTLIER_DETECTION_PID, MSG_AVERAGE, sizeof(int32_t), post_avg, SOS_MSG_RELEASE, UART_ADDRESS); #endif } else if(instr == OP_MUL) { res = (int32_t)(fl_arg1 * arg3->value.var); DEBUG("[BASIC_LIB] execute: FLOAT MULT INT %d\n", res); } } res_part = res & 0xFFFF; pushValue( eventState, res_part, DVM_TYPE_FLOAT_DEC); res_part = res >> 16; pushValue( eventState, res_part, DVM_TYPE_FLOAT); context->pc += 1; break; } else if (arg2->type == DVM_TYPE_FLOAT) { arg3 = popOperand( eventState); fl_arg2 = convert_to_float(arg2, arg3); if(instr == OP_ADD) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) + fl_arg2) ; DEBUG("[BASIC_LIB] execute: INT ADD FLOAT: %d\n", res); } else if(instr == OP_SUB) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) - fl_arg2); DEBUG("[BASIC_LIB] execute: INT SUB FLOAT: %d\n", res); } else if(instr == OP_DIV) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) / fl_arg2); DEBUG("[BASIC_LIB] execute: INT DIV FLOAT: %d\n", res); } else if(instr == OP_MUL) { res = (int32_t)((arg1->value.var * FLOAT_PRECISION) * fl_arg2); DEBUG("[BASIC_LIB] execute: INT MULT FLOAT: %d\n", res); } res_part = res & 0xFFFF; pushValue( eventState, res_part, DVM_TYPE_FLOAT_DEC); res_part = res >> 16; pushValue( eventState, res_part, DVM_TYPE_FLOAT); context->pc += 1; break; } if(instr == OP_ADD) { int_res = arg1->value.var + arg2->value.var; DEBUG("[BASIC_LIB] execute: INT ADD INT: %d\n", int_res); } else if(instr == OP_SUB) { int_res = arg1->value.var - arg2->value.var; DEBUG("[BASIC_LIB] execute: INT SUB INT: %d\n", int_res); } else if(instr == OP_DIV) { int_res = (int16_t)(arg1->value.var / arg2->value.var); DEBUG("[BASIC_LIB] execute: INT DIV INT: %d\n", int_res); } else if(instr == OP_MUL) { int_res = (int16_t)(arg1->value.var * arg2->value.var); DEBUG("[BASIC_LIB] execute: INT MULT INT: %d\n", int_res); } pushValue( eventState, int_res, DVM_TYPE_INTEGER); context->pc += 1; break; }
static int pushExtendedOperand(void* word_db, StateObj *pStObj,QueryNode *pQuNode) { QueryNode qnode; int nRet = 0; int nMorpheme = 0; int i = 0; index_word_extractor_t *extractor=NULL; index_word_t indexwords[ENOUGH_INDEXWORD_NUM]; int morp_id=0, indexwordnum=0; nRet = pushDefaultOperator(pStObj); DEBUG(" nRet of pushDefaultOperator is [%d] ",nRet); if ( nRet < 0 ) return nRet; if (is_both_end_bigram_truncation(pQuNode->original_word) == TRUE) { int len = strlen(pQuNode->original_word); pQuNode->original_word[len-1] = '\0'; /* XXX: moving including NULL */ memmove(pQuNode->original_word, pQuNode->original_word+1, len-1); return pushBothEndBigram(word_db, pStObj, pQuNode); } else if (is_left_end_bigram_truncation(pQuNode->original_word) == TRUE) { int len = strlen(pQuNode->original_word); /* XXX: moving including NULL */ memmove(pQuNode->original_word, pQuNode->original_word+1, len); return pushLeftEndBigram(word_db, pStObj, pQuNode); } else if (is_right_end_bigram_truncation(pQuNode->original_word) == TRUE) { int len = strlen(pQuNode->original_word); pQuNode->original_word[len-1] = '\0'; DEBUG("original_word for word> : %s", pQuNode->original_word); return pushRightEndBigram(word_db, pStObj, pQuNode); } morp_id = mQppMorpAnalyzerId[pStObj->searchField]; debug("morp_id[%d], mMorpIdForPhrase[%d], virtualfield_morpid[%d]", morp_id, mMorpIdForPhrase, pStObj->virtualfield_morpid); if (pStObj->posWithinPhrase == TRUE) { /* 구문검색시 무조건 바이그램을 쓰지 않도록 수정 */ morp_id = mMorpIdForPhrase; } if (pStObj->virtualfield != 0) { morp_id = pStObj->virtualfield_morpid; } extractor = sb_run_new_index_word_extractor(morp_id); if (extractor == NULL || extractor == (index_word_extractor_t*)MINUS_DECLINE) { error("cannot create index_word_extractor: %p", extractor); return FAIL; } //sb_run_index_word_extractor_set_text(extractor, pQuNode->word_st.string); info("original_word:%s", pQuNode->original_word); strncpy(pQuNode->word_st.string, pQuNode->original_word, MAX_WORD_LEN-1); pQuNode->word_st.string[MAX_WORD_LEN-1] = '\0'; cut_string(pQuNode->word_st.string, MAX_WORD_LEN-2); sb_run_index_word_extractor_set_text(extractor, pQuNode->original_word); //XXX: get_index_words should be called in a loop // (more than MAX_QPP_INDEXED_WORDS indexwords can be returned) nRet = sb_run_get_index_words(extractor, indexwords, ENOUGH_INDEXWORD_NUM); if (nRet < 0) { error("error while getting index_words. nRet[%d]", nRet); sb_run_delete_index_word_extractor(extractor); return FAIL; } indexwordnum = nRet; if (indexwordnum > MAX_QPP_INDEXED_WORDS) { indexwordnum = reduce_index_words(indexwords, indexwordnum); } nMorpheme = indexwordnum; sb_run_delete_index_word_extractor(extractor); // daum_koma를 사용하는 경우 특수처리 // 이놈은 boolean query를 리턴한다 /* if ( morp_id == 16 ) { char buf[STRING_SIZE]; struct daum_tree_node* tree = parse_daum_query(indexwords, nMorpheme); if ( tree == NULL ) { error("failed parsing daum koma query: %s", pQuNode->original_word); return FAIL; } info("original query: [%s]", pQuNode->original_word); info("parsed daum query: [%s]", print_daum_tree(tree, buf, sizeof(buf))); if ( push_daum_tree(word_db, pStObj, tree) != SUCCESS ) { error("push_daum_tree failed"); destroy_daum_tree(tree); return FAIL; } // 단어가 등장하면 최소한 { 가 } 와 같이 3개가 나온다 if ( nMorpheme >= 3 && pStObj->posWithinPhrase == TRUE ) { pStObj->numPhraseOperand++; } destroy_daum_tree(tree); pStObj->nextTurn = TURN_BINARY_OPERATOR; return SUCCESS; } else*/ if (nMorpheme > 0) { for (i=0; i<nMorpheme; i++) { strncpy(qnode.word_st.string, indexwords[i].word, MAX_WORD_LEN-1); qnode.word_st.string[MAX_WORD_LEN-1] = '\0'; cut_string(qnode.word_st.string, MAX_WORD_LEN-2); INFO("qnode[%d] word:%s", i, qnode.word_st.string); nRet = pushOperand(word_db, pStObj, &qnode); if (nRet < 0) { error("failed to push operand for word[%s]", qnode.word_st.string); return FAIL; } } if (pStObj->posWithinPhrase == TRUE) { pStObj->numPhraseOperand++; } /* 하나의 토큰에서 두개이상의 색인어가 추출되는 경우 within 연산으로 처리 */ if (nMorpheme > 1) { qnode.type = OPERATOR; qnode.operator = QPP_OP_WITHIN; qnode.opParam = 0; /* within 0 */ qnode.num_of_operands = nMorpheme; nRet = stk_push(&(pStObj->postfixStack),&qnode); if (nRet < 0) return nRet; } } else { /* 색인어가 없는 경우 바로 리턴한다. */ return SUCCESS; } /* * 형태소분석 : 10 <= morp_id < 20 * 바이그램 : 20 <= morp_id < 30 */ /* 형태소분석 결과의 버그를 피해가는 코드는 사용하지 않는다. * 2007-09-18 김정겸 */ #if 0 /* if (nMorpheme == 0 && (morp_id >= 10 && morp_id < 20)) { // 형태소 분석 결과가 없으면 원래 단어로 검색 nRet = pushOperand(pStObj, pQuNode); if (nRet < 0) { error("error while pushing original wordp[%s] into stack", pQuNode->word_st.string); return nRet; } } else */ if (nMorpheme == 1 && (morp_id >= 10 && morp_id < 20)) { /* 형태소 분석 결과 단어와 입력단어가 다르면 입력단어를 OR 검색으로 추가 */ if ( strncmp(pQuNode->original_word, indexwords[0].word, MAX_WORD_LEN) != 0) { // or with original word nRet = pushOperand(word_db, pStObj, pQuNode); if (nRet < 0) { error("error while pushing original wordp[%s] into stack", pQuNode->word_st.string); return nRet; } qnode.type = OPERATOR; qnode.operator = QPP_OP_OR; qnode.num_of_operands = 2; nRet = stk_push(&(pStObj->postfixStack), &qnode); if (nRet < 0) { error("error while pushing original word into stack"); return nRet; } } } else if (nMorpheme >= 2 && (morp_id >= 10 && morp_id < 20)) { /* 형태소 분석 결과 단어와 입력단어가 다르면 입력단어를 OR 검색으로 추가 */ // or with original word nRet = pushOperand(word_db, pStObj, pQuNode); if (nRet < 0) { error("error while pushing original word[%s] into stack", pQuNode->word_st.string); return nRet; } qnode.type = OPERATOR; qnode.operator = QPP_OP_OR; qnode.num_of_operands = 2; nRet = stk_push(&(pStObj->postfixStack), &qnode); if (nRet < 0) { error("error while pushing original word into stack"); return nRet; } } #endif pStObj->nextTurn = TURN_BINARY_OPERATOR; return SUCCESS; }
void pushOperand(ResultType type) { if(type != ResultType::none) { pushOperand(asValueType(type)); } }
void call(CallImm imm) { const FunctionType* calleeType = validateFunctionIndex(module,imm.functionIndex); popAndValidateOperands("call arguments",calleeType->parameters.data(),(Uptr)calleeType->parameters.size()); pushOperand(calleeType->ret); }
void get_global(GetOrSetVariableImm<true> imm) { pushOperand(validateGlobalIndex(module,imm.variableIndex,false,false,false,"get_global")); }
void tee_local(GetOrSetVariableImm<false> imm) { const ValueType localType = validateLocalIndex(imm.variableIndex); popAndValidateOperand("tee_local",localType); pushOperand(localType); }
void get_local(GetOrSetVariableImm<false> imm) { pushOperand(validateLocalIndex(imm.variableIndex)); }
void br_if(BranchImm imm) { popAndValidateOperand("br_if condition",ValueType::i32); popAndValidateResultType("br_if argument",getBranchTargetByDepth(imm.targetDepth).branchArgumentType); pushOperand(getBranchTargetByDepth(imm.targetDepth).branchArgumentType); }