int evaluate(char *postfix){ char ch; int i = 0,operand1,operand2; while( (ch = postfix[i++]) != '\0') { if(isdigit(ch)) { push_int(ch-'0'); // Push the operand }else { //Operator,pop two operands operand2 = pop_int(); operand1 = pop_int(); switch(ch) { case '+': push_int(operand1+operand2); break; case '-': push_int(operand1-operand2); break; case '*': push_int(operand1*operand2); break; case '/': push_int(operand1/operand2); break; } } } return stack_int[top_int]; }
void infixTopostfix(char *infix, char *postfix) { Tintstack op; int counter = 0; int top; initialize_int_stack(&op); //go through equation string for (int i = 0; !infix[i] == '\0'; i++) { int scanned = (int)infix[i]; //If char is operand, add it to postfix string if (isdigit(infix[i])) { postfix[counter] = infix[i]; counter++; } //If its an operator else if (infix[i] == '+' || infix[i] == '-' || infix[i] == '*' || infix[i] == '/' || infix[i] == '(' || infix[i] == ')' || infix[i] == '^') { //and if its the first operator or openning parenthesis, add it to stack if (is_empty_int_stack(&op) || scanned == 40) { push_int(&op, scanned); } /* else If topStack has higher precedence over the scanned character, Pop the stack and append to postfix string untill stack is empty or closing parenthesis is detected or topStack has precedence over the scanned char. else, Push the scanned character to stack. */ else { if (!pop_int(&op, &top)) { break; } if ((priority(top)) > (priority(scanned)) || top == 41) { //scanned is lower or top is close bracket do { if (top != 40 && top != 41) { postfix[counter] = (char)top; counter++; } //append postfix if (!pop_int(&op, &top)){ push_int(&op, scanned); break; } //if stack empty, push scanned to stack if ((priority(top)) < (priority(scanned))) { //if scanned is higher, push to stack push_int(&op, top); push_int(&op, scanned); break; } else if ((priority(top)) == (priority(scanned))) { //if same priority, and not parethesis, append top and push scanned if (top != 40 && top != 41) { postfix[counter] = (char)top; counter++; } push_int(&op, scanned); break; } } while (!is_empty_int_stack(&op)); } else if ((priority(top)) == (priority(scanned))) { //same priority if (top != 40 && top != 41) { postfix[counter] = (char)top; counter++; } push_int(&op, scanned); } else { //scanned is higher, simply push to stack push_int(&op, top); push_int(&op, scanned); } } } } while (!is_empty_int_stack(&op)) { //appened whats left in stack if (!pop_int(&op, &top)){ break; } if (top != 40 && top != 41) { postfix[counter] = (char)top; counter++; } } postfix[counter] = '='; counter++; postfix[counter] = '\0'; //terminate string }
static void lex_pop_state_skip() { int i; pop_int(&lex_state_stack); i=pop_int(&lex_state_stack); i=i>>16; while (i) { pop_int(&lex_state_stack); i--; } }
static void lex_pop_state_use() { int i,j; lex_pos=pop_int(&lex_state_stack); stackpos=pop_int(&lex_state_stack); i=stackpos>>16; stackpos=stackpos&0xffff; for (j=stackpos; j>=0; j--) stack[j]=0; while (i) { j=pop_int(&lex_state_stack); stack[j>>16]=j&0xffff; i--; } }
int main() { /* ** Push several values on each stack. */ push_int( 5 ); push_int( 22 ); push_int( 15 ); push_float( 25.3 ); push_float( -40.5 ); /* ** Empty the integer stack and print the values. */ while( !is_empty_int() ) { printf( "Popping %d\n", top_int() ); pop_int(); } /* ** Empty the float stack and print the values. */ while( !is_empty_float() ) { printf( "Popping %f\n", top_float() ); pop_float(); } return EXIT_SUCCESS; }
// evict_cache will pop the first item // which is the earliest cache'line got written // it will reset the line's valid bit to 0 status evict_cache( line cache[], queue *p_Q ){ int index ; pop_int( p_Q , &index ) ; cache[index].valid = 0 ; cache[index].tag = -1 ; return OK ; }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_get_state(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t pobj; pPmObj_t pobj_new; pPmInstance_t pcli; pPmDict_t pdict; int16_t index; float fval; int32_t ival; if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pobj = NATIVE_GET_LOCAL(0); if(OBJ_GET_TYPE(pobj) != OBJ_TYPE_CLI) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } pcli = (pPmInstance_t)pobj; pdict = pcli->cli_attrs; if(*tres_pm_io.state_len > 0) { // restore each attribute of the object for(index = pdict->length - 1; index >= 0; index--) { seglist_getItem(pdict->d_keys, index, &pobj); retv = seglist_getItem(pdict->d_vals, index, &pobj); PM_RETURN_IF_ERROR(retv); switch (OBJ_GET_TYPE(pobj)) { case OBJ_TYPE_INT: //pop int pop_int(&ival); retv = int_new(ival, &pobj_new); break; case OBJ_TYPE_FLT: //pop float pop_float(&fval); retv = float_new(fval, &pobj_new); break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } if (retv == PM_RET_OK) { seglist_setItem(pdict->d_vals, pobj_new, index); } } } NATIVE_SET_TOS((pPmObj_t)pcli); return retv; }
/* ** 'get_number' is called to evaluate an expression that returns an ** integer value. It is used by the functions handling the various ** Basic commands in this file */ static int32 get_number(void) { factor(); switch (get_topitem()) { case STACK_INT: return pop_int(); case STACK_FLOAT: return TOINT(pop_float()); default: error(ERR_TYPENUM); } return 0; }
int main(int argc, char** argv) { stack_int pile; init_int(&pile); push_int(&pile,12); push_int(&pile,24); if(empty_int(&pile) == 0) { printf("Top : %d \n",top_int(&pile)); pop_int(&pile); printf("Top : %d \n",top_int(&pile)); } return (EXIT_SUCCESS); }
/*----------------------------------------------------------------------------*/ PmReturn_t tres_pm_state_pop(pPmFrame_t *ppframe) { PmReturn_t retv = PM_RET_OK; pPmObj_t r_pflt; pPmObj_t pa; float fval; int32_t ival; int pop_retv; /* Raise TypeError if wrong number of args */ pa = NATIVE_GET_LOCAL(0); if(NATIVE_GET_NUM_ARGS() != 1) { PM_RAISE(retv, PM_RET_EX_TYPE); return retv; } switch (OBJ_GET_TYPE(pa)) { //case OBJ_TYPE_STR: // ptr = (char const *)&(((pPmString_t)pa)->val); // // TODO: unimplemented // break; case OBJ_TYPE_INT: pop_retv = pop_int(&ival); if(pop_retv != TRES_ERR_NONE) { ival = ((pPmInt_t) pa)->val; } retv = int_new(ival, &r_pflt); break; case OBJ_TYPE_FLT: pop_retv = pop_float(&fval); if(pop_retv != TRES_ERR_NONE) { fval = ((pPmFloat_t) pa)->val; } retv = float_new(fval, &r_pflt); break; default: /* Raise TypeError */ PM_RAISE(retv, PM_RET_EX_TYPE); } NATIVE_SET_TOS(r_pflt); return retv; }
/* execute the instruction at the current PC (x,y) and move the cursor * depending on the direction after executing the current op. */ int step(runner * run) { int result = 0; operation op = run->memory[run->y * WIDTH + run->x]; #if 0 char stack_str[512] = "[ "; stack_entry * e = run->stack; while (e != NULL) { sprintf(stack_str, "%s%d ", stack_str, e->value); e = e->next; } strcat(stack_str, "]"); printf("(%d, %d): '%c' (%d) :: step :: stack = %s\n", run->x, run->y, op, op, stack_str); #endif if (run->stringmode) { if (op == OP_STRINGMODE) { run->stringmode = 0; } else { push_int(run, val_at_pc(run)); } move(run); return 0; } switch (op) { case OP_ADD: push_int(run, pop_int(run) + pop_int(run)); break; case OP_SUB: { int val1 = pop_int(run); int val2 = pop_int(run); push_int(run, val2 - val1); break; } case OP_MULT: push_int(run, pop_int(run) * pop_int(run)); break; case OP_DIV: { int val1 = pop_int(run); int val2 = pop_int(run); push_int(run, val2 / val1); break; } case OP_MOD: { int val1 = pop_int(run); int val2 = pop_int(run); push_int(run, val2 % val1); break; } case OP_DUP: { int in = pop_int(run); push_int(run, in); push_int(run, in); break; } case OP_SWAP: { int val1 = pop_int(run), val2 = pop_int(run); push_int(run, val1); push_int(run, val2); break; } case OP_POP: pop_int(run); break; case OP_NOT: push_int(run, (pop_int(run) == 0) ? 1 : 0); break; case OP_GREATERTHAN: { int val1 = pop_int(run); int val2 = pop_int(run); push_int(run, val2 > val1 ? 1 : 0); break; } /* directions.. */ case OP_DIR_RIGHT: run->dir = DIR_RIGHT; break; case OP_DIR_DOWN: run->dir = DIR_DOWN; break; case OP_DIR_LEFT: run->dir = DIR_LEFT; break; case OP_DIR_UP: run->dir = DIR_UP; break; case OP_DIR_RANDOM: { int r = rand() % 4; run->dir = r; break; } case OP_IF_HORIZ: if (pop_int(run) != 0) run->dir = DIR_LEFT; else run->dir = DIR_RIGHT; break; case OP_IF_VERT: if (pop_int(run) != 0) run->dir = DIR_UP; else run->dir = DIR_DOWN; break; case OP_STRINGMODE: run->stringmode = 1; break; case OP_OUT_INT: { char buf[512]; sprintf(buf, "%d ", pop_int(run)); write(1, buf, strlen(buf)); break; } case OP_OUT_CHAR: { char buf[1]; buf[0] = pop_int(run); write(1, buf, 1); } break; case OP_IN_INT: { int val; if (scanf("%d ", &val) < 1) { fprintf(stderr, "error at (%d, %d): could not read an int from stdin!\n", run->x, run->y); return -1; } push_int(run, val); break; } case OP_IN_CHAR: { char buf[1]; if (read(0, buf, 1) < 1) { fprintf(stderr, "error at (%d, %d): could not read a byte from stdin!\n", run->x, run->y); return -1; } push_int(run, (int) buf[0]); break; } case OP_BRIDGE: // extra move; will end up past the thing after the bridge move(run); break; case OP_CODE_GET: { int y = pop_int(run); int x = pop_int(run); int val = val_at_xy(run, x, y); push_int(run, val); break; } case OP_CODE_PUT: { int y = pop_int(run); int x = pop_int(run); int val = pop_int(run); set_val_at_xy(run, x, y, val); break; } case OP_END: run->ended = 1; break; case OP_BLANK: // do nothing. break; default: if (op >= '0' && op <= '9') { push_int(run, op - '0'); } else { fprintf(stderr, "error at (%d, %d): unknown befunge instruction '%c' (%d)\n", run->x, run->y, op, op); return -1; } } // move the PC based on current direction. move(run); return result; }
int main( int argc, char * argv[] ) { int tmp; int i = 0; int num1; int num2; int new_num; char op; char * src; char cur_op; char top_op; printf( "expression value demo begin !\n" ); #if 0 push_int( 100 ); push_int( 200 ); tmp = pop_int(); printf( "pop is %d \n", tmp ); tmp = pop_int(); printf( "pop is %d \n", tmp ); #endif if( argc > 1 ) printf( "input expression string is %s \n", argv[1] ); else exit(0); src = argv[1]; push_char( '\0'); while( 1 ) { printf( "src[%d] = %c \n", i, src[i] ); get_num: /* get a number */ num1 = get_number( src[i] ); if( num1 >= 0 ) printf( "get a number : %d \n", num1 ); else break; /* push this number */ printf( "push current int : %d \n", num1 ); push_int( num1 ); /* get the next op */ i++; cur_op = get_operator( src[i] ); if( cur_op > 0 ) printf( "get a operator: %c \n", cur_op ); else if( cur_op == '\0' ) { printf( "get a operator == 0: %c \n", cur_op ); } cmp_op: top_op = get_top_char(); printf( "get top stack operator: %c \n", top_op ); /* if current op > stack top op, then push current op */ if( get_prio( cur_op ) > get_prio( top_op ) ) { printf( "<push> push current op : %c \n", cur_op ); push_char( cur_op ); printf( "<push> push ok!\n" ); } else { op = pop_char(); num2 = pop_int(); if( op == '\0' ) { printf( "op == 0, last result = %d \n", num2 ); exit( 0 ); } num1 = pop_int(); printf( "<calc> pop 2 num and 1 op, do calc: %d %c %d \n", num1, op, num2 ); new_num = calc( num1, num2, op ); printf( "get calc result: %d \n", new_num ); /* push this new number */ printf( "push new int : %d \n", new_num ); push_int( new_num ); goto cmp_op; } /* get the next op */ i++; } return 0; }
void exec_toreal(){ push_real(pop_int()); }
void exec_iumi(){ push_int(-pop_int()); }
void exec_idiv(){ int n, m; n = pop_int(); m = pop_int(); push_int(m/n); }
void exec_itimes(){ int n, m; n = pop_int(); m = pop_int(); push_int(m*n); }
void exec_iminus(){ int n, m; n = pop_int(); m = pop_int(); push_int(m-n); }
void exec_iplus(){ int n, m; n = pop_int(); m = pop_int(); push_int(m+n); }
void exec_ile(){ int n, m; n = pop_int(); m = pop_int(); push_bool(m<=n); }
void exec_ige(){ int n, m; n = pop_int(); m = pop_int(); push_bool(m>=n); }
bool parse(SensorInfo &si) { _error.str(""); std::string spec_type; float x=std::numeric_limits<float>::quiet_NaN(); float y=std::numeric_limits<float>::quiet_NaN(); float z=std::numeric_limits<float>::quiet_NaN(); Spec spec_marker[] = { { "led", "uint32_t", &si.id, true }, { "tracker", "uint32_t", &si.tracker, false }, { "x", "float", &x, false }, { "y", "float", &y, false }, { "z", "float", &z, false }, { "", "", NULL, false } // sentinel }; Spec spec_rigid[] = { { "tracker", "uint32_t", &si.tracker, true }, { "", "", NULL, false } // sentinel }; if(pop_int("sensor", si.sensor_id)) { _error << "required key 'sensor' not found"; return false; } if(pop("type", spec_type)) { _error << "required key 'type' not found"; return false; } Spec* spec = NULL; if(spec_type == "rigid" || spec_type == "rigid_body") { si.type = OWL::Type::RIGID; spec = spec_rigid; } else if(spec_type == "point") { si.type = OWL::Type::MARKER; spec = spec_marker; } else { _error << "unknown sensor type: " << spec_type; return false; } for(int i = 0; spec[i].dest; i++) { int ret = 0; if(spec[i].type == "string") ret = pop(spec[i].key, *((std::string*) spec[i].dest)); else if(spec[i].type == "uint32_t") ret = pop_uint(spec[i].key, *((uint32_t*) spec[i].dest)); else if(spec[i].type == "float") ret = pop_float(spec[i].key, *((float*) spec[i].dest)); else { _error << "unknown spec type: " << spec[i].type; return false; } if(ret == 1) { if(spec[i].required) { _error << "required key not found: " << spec[i].key; return false; } } else if(ret) { _error << "error reading value for key \'" << spec[i].key << "'"; return false; } } if(si.type == OWL::Type::RIGID) si.id = si.tracker; //special case (legacy) if(!isnan(x) || !isnan(y) || !isnan(z)) { if(isnan(x) || isnan(y) || isnan(z)) { _error << "x,y,z keys must all be specified if any are specified."; return false; } if(contains("pos")) { _error << "pos and x,y,z keys are mutually exclusive."; return false; } std::stringstream pos; pos << x << ',' << y << ',' << z; keyvals["pos"] = pos.str(); } si.opt = join(); return true; }
void NativeGenerator::generate_native_string_entries() { comment_section("Native entry points for string functions"); { //--------------------java.lang.String.indexof0--------------------------- rom_linkable_entry("native_string_indexof0_entry"); wtk_profile_quick_call(/* param_size*/ 2); comment("Pop the return address"); popl(edi); comment("Push zero for fromIndex"); pushl(Constant(0)); comment("Push back the return address"); pushl(edi); jmp(Constant("native_string_indexof_entry")); rom_linkable_entry_end(); // native_string_indexof0_entry //--------------------java.lang.String.indexof--------------------------- rom_linkable_entry("native_string_indexof_entry"); Label cont, loop, test, failure, success; wtk_profile_quick_call(/* param_size*/ 3); comment("Pop the return address"); popl(edi); comment("Pop the argument: fromIndex"); pop_int(eax, eax); comment("Pop the argument: ch"); pop_int(ebx, ebx); comment("Pop the receiver"); pop_obj(ecx, ecx); cmpl(ebx, Constant(0xFFFF)); jcc(greater, Constant(failure)); cmpl(eax, Constant(0)); jcc(greater_equal, Constant(cont)); movl(eax, Constant(0)); bind(cont); movl(esi, Address(ecx, Constant(String::count_offset()))); comment("if (fromIndex >= count) { return -1; }"); cmpl(eax, esi); jcc(greater_equal, Constant(failure)); movl(edx, Address(ecx, Constant(String::offset_offset()))); addl(eax, edx); // i = offset + fromIndex addl(edx, esi); // int max = offset + count; movl(esi, Address(ecx, Constant(String::value_offset()))); // v = value. jmp(Constant(test)); bind(loop); cmpw(Address(esi, eax, times_2, Constant(Array::base_offset())), ebx); jcc(equal, Constant(success)); incl(eax); bind(test); cmpl(eax, edx); jcc(less, Constant(loop)); comment("Return -1 by pushing the value and jumping to the return address"); bind(failure); push_int(-1); jmp(edi); comment("Return i - offset by pushing the value and jumping to the return address"); bind(success); movl(esi, Address(ecx, Constant(String::offset_offset()))); // i = offset + fromIndex subl(eax, esi); push_int(eax); jmp(edi); rom_linkable_entry_end(); // native_string_indexof_entry } //----------------------java.lang.String.charAt--------------------------- { rom_linkable_entry("native_string_charAt_entry"); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); } //----------------------java.lang.String(java.lang.StringBuffer)------------- { rom_linkable_entry("native_string_init_entry"); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); } //----------------------java.lang.String.equals(java.lang.Object)------------ { rom_linkable_entry("native_string_equals_entry"); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); } //----------------------java.lang.String.indexOf(java.lang.String)----------- { rom_linkable_entry("native_string_indexof0_string_entry"); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); } //----------------------java.lang.String.indexOf(java.lang.String)----------- { rom_linkable_entry("native_string_indexof_string_entry"); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); } //----------------------java.lang.String.compareTo--------------------------- { // java.lang.String.compareTo // Method int compareTo(java.lang.String) rom_linkable_entry("native_string_compareTo_entry"); wtk_profile_quick_call(/* param_size*/ 2); comment("preserve method"); pushl(ebx); // 8 is return address plus pushed method int str1_offset = JavaFrame::arg_offset_from_sp(0) + 8, str0_offset = JavaFrame::arg_offset_from_sp(1) + 8; comment("load arguments to registers"); movl(ecx, Address(esp, Constant(str1_offset))); movl(eax, Address(esp, Constant(str0_offset))); // eax: str0: this String // ebx: str1: String to compare against Label bailout; comment("Null check"); testl(ecx, ecx); jcc(zero, Constant(bailout)); comment("get str0.value[]"); movl(esi, Address(eax, Constant(String::value_offset()))); comment("get str0.offset"); movl(ebx, Address(eax, Constant(String::offset_offset()))); comment("compute start of character data"); leal(esi, Address(esi, ebx, times_2, Constant(Array::base_offset()))); comment("get str0.count"); movl(eax, Address(eax, Constant(String::count_offset()))); comment("get str1.value[]"); movl(edi, Address(ecx, Constant(String::value_offset()))); comment("get str1.offset"); movl(ebx, Address(ecx, Constant(String::offset_offset()))); comment("compute start of character data"); leal(edi, Address(edi, ebx, times_2, Constant(Array::base_offset()))); comment("get str1.count"); movl(ebx, Address(ecx, Constant(String::count_offset()))); // esi = str0 start of character data // edi = str1 start of character data // eax = str0 length // ebx = str1 length Label str1_longest; subl(eax, ebx); jcc(greater_equal, Constant(str1_longest)); // str1 is longer than str0 addl(ebx, eax); bind(str1_longest); // esi = str0 start of character data // edi = str1 start of character data // eax = str0.count - str1.count // ebx = min(str0.count, str1.count) // save str0.count - str1.count, we might need it later pushl(eax); xorl(ecx, ecx); Label loop, check_lengths, done; bind(loop); cmpl(ecx, ebx); jcc(above_equal, Constant(check_lengths)); movzxw(eax, Address(esi, ecx, times_2)); movzxw(edx, Address(edi, ecx, times_2)); subl(eax, edx); jcc(not_equal, Constant(done)); incl(ecx); jmp(Constant(loop)); bind(check_lengths); movl(eax, Address(esp)); bind(done); popl(ebx); // remove saved length difference // Push result on stack and return to caller popl(ebx); // remove method popl(edi); // pop return address addl(esp, Constant(2 * BytesPerStackElement)); // remove arguments push_int(eax); // push result jmp(edi); // return comment("Bail out to the general compareTo implementation"); bind(bailout); comment("pop method"); popl(ebx); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); // native_string_compareTo_entry } //----------------------java.lang.String.endsWith---------------- { // java.lang.String.endsWith // Method boolean endsWith(java.lang.String) rom_linkable_entry("native_string_endsWith_entry"); wtk_profile_quick_call(/* param_size*/ 2); Label bailout; // 4 is return address int suffix_offset = JavaFrame::arg_offset_from_sp(0) + 4, this_offset = JavaFrame::arg_offset_from_sp(1) + 4; comment("load arguments to registers"); movl(eax, Address(esp, Constant(suffix_offset))); cmpl(eax, Constant(0)); jcc(equal, Constant(bailout)); movl(ecx, Address(esp, Constant(this_offset))); comment("Pop the return address"); popl(edi); movl(edx, Address(ecx, Constant(String::count_offset()))); subl(edx, Address(eax, Constant(String::count_offset()))); comment("Push (this.count - suffix.count) for toffset"); pushl(edx); comment("Push back the return address"); pushl(edi); jmp(Constant("native_string_startsWith_entry")); comment("Bail out to the general startsWith implementation"); bind(bailout); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); // native_string_endsWith_entry } //----------------------java.lang.String.startsWith---------------- { // java.lang.String.startsWith // Method boolean startsWith(java.lang.String) rom_linkable_entry("native_string_startsWith0_entry"); wtk_profile_quick_call(/* param_size*/ 2); Label bailout; // 4 is return address int prefix_offset = JavaFrame::arg_offset_from_sp(0) + 4; comment("Check if prefix is null"); cmpl(Address(esp, Constant(prefix_offset)), Constant(0)); jcc(equal, Constant(bailout)); comment("Pop the return address"); popl(edi); comment("Push zero for toffset"); pushl(Constant(0)); comment("Push back the return address"); pushl(edi); jmp(Constant("native_string_startsWith_entry")); comment("Bail out to the general startsWith implementation"); bind(bailout); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); // native_string_startsWith0_entry } { // ----------- java.lang.String.startsWith ------------------------------ // Method boolean startsWith(java.lang.String,int) rom_linkable_entry("native_string_startsWith_entry"); wtk_profile_quick_call(/* param_size*/ 3); Label bailout, return_false; // 4 is return address int prefix_offset = JavaFrame::arg_offset_from_sp(1) + 4; comment("Check if prefix is null"); cmpl(Address(esp, Constant(prefix_offset)), Constant(0)); jcc(equal, Constant(bailout)); comment("Pop the return address"); popl(edi); comment("Pop the argument: toffset"); pop_int(edx, edx); comment("Pop the argument: prefix"); pop_obj(eax, eax); comment("Pop the receiver"); pop_obj(ecx, ecx); comment("Preserve the return address"); pushl(edi); // ecx: this String // eax: prefix cmpl(edx, Constant(0)); jcc(less, Constant(return_false)); comment("if (toffset > this.count - prefix.count) return false;"); movl(ebx, Address(ecx, Constant(String::count_offset()))); subl(ebx, Address(eax, Constant(String::count_offset()))); cmpl(edx, ebx); jcc(greater, Constant(return_false)); comment("get this.value[]"); movl(esi, Address(ecx, Constant(String::value_offset()))); comment("get this.offset"); movl(ebx, Address(ecx, Constant(String::offset_offset()))); comment("add toffset"); addl(ebx, edx); comment("compute start of character data"); leal(esi, Address(esi, ebx, times_2, Constant(Array::base_offset()))); comment("get prefix.value[]"); movl(edi, Address(eax, Constant(String::value_offset()))); comment("get prefix.offset"); movl(ebx, Address(eax, Constant(String::offset_offset()))); comment("compute start of character data"); leal(edi, Address(edi, ebx, times_2, Constant(Array::base_offset()))); comment("get prefix.count"); movl(ecx, Address(eax, Constant(String::count_offset()))); comment("get the number of bytes to compare"); shll(ecx, Constant(1)); comment("memcmp(edi, esi, ecx);"); pushl(ecx); pushl(esi); pushl(edi); if (GenerateInlineAsm) { // VC++ treats memcmp() as an intrinsic function and would cause // reference to memcmp in Interpreter_i386.c to fail to compile. call(Constant("memcmp_from_interpreter")); } else { call(Constant("memcmp")); } addl(esp, Constant(12)); cmpl(eax, Constant(0)); jcc(not_equal, Constant(return_false)); // Push 1 on stack and return to caller popl(edi); // pop return address push_int(1); // push result jmp(edi); // return bind(return_false); // Push 0 on stack and return to caller popl(edi); // pop return address push_int(0); // push result jmp(edi); // return comment("Bail out to the general startsWith implementation"); bind(bailout); if (AddExternCUnderscore) { emit_instruction("jmp _interpreter_method_entry"); } else { emit_instruction("jmp interpreter_method_entry"); } rom_linkable_entry_end(); // native_string_startsWith_entry } }
int operator()(cell_ptr& l) { return pop_int(l); }