This is a port of the mruby/c tutorial Chapter 03 to the mbed environment.
For details, refer to the following.
http://www.s-itoc.jp/activity/research/mrubyc/mrubyc_tutorial/436
Note:There is a change in rtt0.h from the original source in the mruby/c. It was necessary for inclusion in C ++ source.
mrubyc/vm.c@0:33feccbba3ff, 2017-02-15 (annotated)
- Committer:
- tk_takateku
- Date:
- Wed Feb 15 01:03:35 2017 +0000
- Revision:
- 0:33feccbba3ff
Commit before publishing
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tk_takateku | 0:33feccbba3ff | 1 | /*! @file |
tk_takateku | 0:33feccbba3ff | 2 | @brief |
tk_takateku | 0:33feccbba3ff | 3 | mruby bytecode executor. |
tk_takateku | 0:33feccbba3ff | 4 | |
tk_takateku | 0:33feccbba3ff | 5 | <pre> |
tk_takateku | 0:33feccbba3ff | 6 | Copyright (C) 2015 Kyushu Institute of Technology. |
tk_takateku | 0:33feccbba3ff | 7 | Copyright (C) 2015 Shimane IT Open-Innovation Center. |
tk_takateku | 0:33feccbba3ff | 8 | |
tk_takateku | 0:33feccbba3ff | 9 | This file is distributed under BSD 3-Clause License. |
tk_takateku | 0:33feccbba3ff | 10 | |
tk_takateku | 0:33feccbba3ff | 11 | Fetch mruby VM bytecodes, decode and execute. |
tk_takateku | 0:33feccbba3ff | 12 | |
tk_takateku | 0:33feccbba3ff | 13 | </pre> |
tk_takateku | 0:33feccbba3ff | 14 | */ |
tk_takateku | 0:33feccbba3ff | 15 | |
tk_takateku | 0:33feccbba3ff | 16 | #include <stdint.h> |
tk_takateku | 0:33feccbba3ff | 17 | #include <stddef.h> |
tk_takateku | 0:33feccbba3ff | 18 | #include "vm.h" |
tk_takateku | 0:33feccbba3ff | 19 | #include "alloc.h" |
tk_takateku | 0:33feccbba3ff | 20 | #include "static.h" |
tk_takateku | 0:33feccbba3ff | 21 | #include "vm_config.h" |
tk_takateku | 0:33feccbba3ff | 22 | #include "opcode.h" |
tk_takateku | 0:33feccbba3ff | 23 | #include "class.h" |
tk_takateku | 0:33feccbba3ff | 24 | #include "symbol.h" |
tk_takateku | 0:33feccbba3ff | 25 | #include "console.h" |
tk_takateku | 0:33feccbba3ff | 26 | |
tk_takateku | 0:33feccbba3ff | 27 | #include "c_string.h" |
tk_takateku | 0:33feccbba3ff | 28 | #include "c_range.h" |
tk_takateku | 0:33feccbba3ff | 29 | |
tk_takateku | 0:33feccbba3ff | 30 | |
tk_takateku | 0:33feccbba3ff | 31 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 32 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 33 | find sym[n] from symbol table in irep |
tk_takateku | 0:33feccbba3ff | 34 | |
tk_takateku | 0:33feccbba3ff | 35 | @param p |
tk_takateku | 0:33feccbba3ff | 36 | @param n |
tk_takateku | 0:33feccbba3ff | 37 | @return symbol string |
tk_takateku | 0:33feccbba3ff | 38 | */ |
tk_takateku | 0:33feccbba3ff | 39 | static char *find_irep_symbol( uint8_t *p, int n ) |
tk_takateku | 0:33feccbba3ff | 40 | { |
tk_takateku | 0:33feccbba3ff | 41 | int cnt = bin_to_uint32(p); |
tk_takateku | 0:33feccbba3ff | 42 | if( n >= cnt ) return 0; |
tk_takateku | 0:33feccbba3ff | 43 | p += 4; |
tk_takateku | 0:33feccbba3ff | 44 | while( n > 0 ) { |
tk_takateku | 0:33feccbba3ff | 45 | uint16_t s = bin_to_uint16(p); |
tk_takateku | 0:33feccbba3ff | 46 | p += 2+s+1; // size(2 bytes) + symbol len + '\0' |
tk_takateku | 0:33feccbba3ff | 47 | n--; |
tk_takateku | 0:33feccbba3ff | 48 | } |
tk_takateku | 0:33feccbba3ff | 49 | return (char *)p+2; // skip size(2 bytes) |
tk_takateku | 0:33feccbba3ff | 50 | } |
tk_takateku | 0:33feccbba3ff | 51 | |
tk_takateku | 0:33feccbba3ff | 52 | |
tk_takateku | 0:33feccbba3ff | 53 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 54 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 55 | |
tk_takateku | 0:33feccbba3ff | 56 | */ |
tk_takateku | 0:33feccbba3ff | 57 | static void not_supported(void) |
tk_takateku | 0:33feccbba3ff | 58 | { |
tk_takateku | 0:33feccbba3ff | 59 | console_printf("Not supported!\n"); |
tk_takateku | 0:33feccbba3ff | 60 | } |
tk_takateku | 0:33feccbba3ff | 61 | |
tk_takateku | 0:33feccbba3ff | 62 | |
tk_takateku | 0:33feccbba3ff | 63 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 64 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 65 | Execute NOP |
tk_takateku | 0:33feccbba3ff | 66 | |
tk_takateku | 0:33feccbba3ff | 67 | No operation |
tk_takateku | 0:33feccbba3ff | 68 | |
tk_takateku | 0:33feccbba3ff | 69 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 70 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 71 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 72 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 73 | */ |
tk_takateku | 0:33feccbba3ff | 74 | inline static int op_nop( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 75 | { |
tk_takateku | 0:33feccbba3ff | 76 | return 0; |
tk_takateku | 0:33feccbba3ff | 77 | } |
tk_takateku | 0:33feccbba3ff | 78 | |
tk_takateku | 0:33feccbba3ff | 79 | |
tk_takateku | 0:33feccbba3ff | 80 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 81 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 82 | Execute MOVE |
tk_takateku | 0:33feccbba3ff | 83 | |
tk_takateku | 0:33feccbba3ff | 84 | R(A) := R(B) |
tk_takateku | 0:33feccbba3ff | 85 | |
tk_takateku | 0:33feccbba3ff | 86 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 87 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 88 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 89 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 90 | */ |
tk_takateku | 0:33feccbba3ff | 91 | inline static int op_move( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 92 | { |
tk_takateku | 0:33feccbba3ff | 93 | regs[GETARG_A(code)] = regs[GETARG_B(code)]; |
tk_takateku | 0:33feccbba3ff | 94 | return 0; |
tk_takateku | 0:33feccbba3ff | 95 | } |
tk_takateku | 0:33feccbba3ff | 96 | |
tk_takateku | 0:33feccbba3ff | 97 | |
tk_takateku | 0:33feccbba3ff | 98 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 99 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 100 | Execute LOADL |
tk_takateku | 0:33feccbba3ff | 101 | |
tk_takateku | 0:33feccbba3ff | 102 | R(A) := Pool(Bx) |
tk_takateku | 0:33feccbba3ff | 103 | |
tk_takateku | 0:33feccbba3ff | 104 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 105 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 106 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 107 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 108 | */ |
tk_takateku | 0:33feccbba3ff | 109 | inline static int op_loadl( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 110 | { |
tk_takateku | 0:33feccbba3ff | 111 | int rb = GETARG_Bx(code); |
tk_takateku | 0:33feccbba3ff | 112 | mrb_object *ptr = vm->pc_irep->ptr_to_pool; |
tk_takateku | 0:33feccbba3ff | 113 | while( rb > 0 ){ |
tk_takateku | 0:33feccbba3ff | 114 | ptr = ptr->next; |
tk_takateku | 0:33feccbba3ff | 115 | rb--; |
tk_takateku | 0:33feccbba3ff | 116 | } |
tk_takateku | 0:33feccbba3ff | 117 | regs[GETARG_A(code)] = *ptr; |
tk_takateku | 0:33feccbba3ff | 118 | return 0; |
tk_takateku | 0:33feccbba3ff | 119 | } |
tk_takateku | 0:33feccbba3ff | 120 | |
tk_takateku | 0:33feccbba3ff | 121 | |
tk_takateku | 0:33feccbba3ff | 122 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 123 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 124 | Execute LOADI |
tk_takateku | 0:33feccbba3ff | 125 | |
tk_takateku | 0:33feccbba3ff | 126 | R(A) := sBx |
tk_takateku | 0:33feccbba3ff | 127 | |
tk_takateku | 0:33feccbba3ff | 128 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 129 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 130 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 131 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 132 | */ |
tk_takateku | 0:33feccbba3ff | 133 | inline static int op_loadi( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 134 | { |
tk_takateku | 0:33feccbba3ff | 135 | regs[GETARG_A(code)].value.i = GETARG_sBx(code); |
tk_takateku | 0:33feccbba3ff | 136 | regs[GETARG_A(code)].tt = MRB_TT_FIXNUM; |
tk_takateku | 0:33feccbba3ff | 137 | |
tk_takateku | 0:33feccbba3ff | 138 | return 0; |
tk_takateku | 0:33feccbba3ff | 139 | } |
tk_takateku | 0:33feccbba3ff | 140 | |
tk_takateku | 0:33feccbba3ff | 141 | |
tk_takateku | 0:33feccbba3ff | 142 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 143 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 144 | Execute LOADSYM |
tk_takateku | 0:33feccbba3ff | 145 | |
tk_takateku | 0:33feccbba3ff | 146 | R(A) := Syms(Bx) |
tk_takateku | 0:33feccbba3ff | 147 | |
tk_takateku | 0:33feccbba3ff | 148 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 149 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 150 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 151 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 152 | */ |
tk_takateku | 0:33feccbba3ff | 153 | inline static int op_loadsym( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 154 | { |
tk_takateku | 0:33feccbba3ff | 155 | int ra = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 156 | int rb = GETARG_Bx(code); |
tk_takateku | 0:33feccbba3ff | 157 | char *sym = find_irep_symbol(vm->pc_irep->ptr_to_sym, rb); |
tk_takateku | 0:33feccbba3ff | 158 | |
tk_takateku | 0:33feccbba3ff | 159 | mrb_sym sym_id = add_sym(sym); |
tk_takateku | 0:33feccbba3ff | 160 | |
tk_takateku | 0:33feccbba3ff | 161 | regs[ra].value.i = sym_id; |
tk_takateku | 0:33feccbba3ff | 162 | regs[ra].tt = MRB_TT_SYMBOL; |
tk_takateku | 0:33feccbba3ff | 163 | |
tk_takateku | 0:33feccbba3ff | 164 | return 0; |
tk_takateku | 0:33feccbba3ff | 165 | } |
tk_takateku | 0:33feccbba3ff | 166 | |
tk_takateku | 0:33feccbba3ff | 167 | |
tk_takateku | 0:33feccbba3ff | 168 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 169 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 170 | Execute LOADNIL |
tk_takateku | 0:33feccbba3ff | 171 | |
tk_takateku | 0:33feccbba3ff | 172 | R(A) := nil |
tk_takateku | 0:33feccbba3ff | 173 | |
tk_takateku | 0:33feccbba3ff | 174 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 175 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 176 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 177 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 178 | */ |
tk_takateku | 0:33feccbba3ff | 179 | inline static int op_loadnil( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 180 | { |
tk_takateku | 0:33feccbba3ff | 181 | regs[GETARG_A(code)].tt = MRB_TT_NIL; |
tk_takateku | 0:33feccbba3ff | 182 | return 0; |
tk_takateku | 0:33feccbba3ff | 183 | } |
tk_takateku | 0:33feccbba3ff | 184 | |
tk_takateku | 0:33feccbba3ff | 185 | |
tk_takateku | 0:33feccbba3ff | 186 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 187 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 188 | Execute LOADSELF |
tk_takateku | 0:33feccbba3ff | 189 | |
tk_takateku | 0:33feccbba3ff | 190 | R(A) := self |
tk_takateku | 0:33feccbba3ff | 191 | |
tk_takateku | 0:33feccbba3ff | 192 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 193 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 194 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 195 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 196 | */ |
tk_takateku | 0:33feccbba3ff | 197 | inline static int op_loadself( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 198 | { |
tk_takateku | 0:33feccbba3ff | 199 | regs[GETARG_A(code)] = regs[0]; |
tk_takateku | 0:33feccbba3ff | 200 | return 0; |
tk_takateku | 0:33feccbba3ff | 201 | } |
tk_takateku | 0:33feccbba3ff | 202 | |
tk_takateku | 0:33feccbba3ff | 203 | |
tk_takateku | 0:33feccbba3ff | 204 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 205 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 206 | Execute LOADT |
tk_takateku | 0:33feccbba3ff | 207 | |
tk_takateku | 0:33feccbba3ff | 208 | R(A) := true |
tk_takateku | 0:33feccbba3ff | 209 | |
tk_takateku | 0:33feccbba3ff | 210 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 211 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 212 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 213 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 214 | */ |
tk_takateku | 0:33feccbba3ff | 215 | inline static int op_loadt( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 216 | { |
tk_takateku | 0:33feccbba3ff | 217 | regs[GETARG_A(code)].tt = MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 218 | return 0; |
tk_takateku | 0:33feccbba3ff | 219 | } |
tk_takateku | 0:33feccbba3ff | 220 | |
tk_takateku | 0:33feccbba3ff | 221 | |
tk_takateku | 0:33feccbba3ff | 222 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 223 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 224 | Execute LOADF |
tk_takateku | 0:33feccbba3ff | 225 | |
tk_takateku | 0:33feccbba3ff | 226 | R(A) := false |
tk_takateku | 0:33feccbba3ff | 227 | |
tk_takateku | 0:33feccbba3ff | 228 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 229 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 230 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 231 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 232 | */ |
tk_takateku | 0:33feccbba3ff | 233 | inline static int op_loadf( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 234 | { |
tk_takateku | 0:33feccbba3ff | 235 | regs[GETARG_A(code)].tt = MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 236 | return 0; |
tk_takateku | 0:33feccbba3ff | 237 | } |
tk_takateku | 0:33feccbba3ff | 238 | |
tk_takateku | 0:33feccbba3ff | 239 | |
tk_takateku | 0:33feccbba3ff | 240 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 241 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 242 | Execute GETGLOBAL |
tk_takateku | 0:33feccbba3ff | 243 | |
tk_takateku | 0:33feccbba3ff | 244 | R(A) := getglobal(Syms(Bx)) |
tk_takateku | 0:33feccbba3ff | 245 | |
tk_takateku | 0:33feccbba3ff | 246 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 247 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 248 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 249 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 250 | */ |
tk_takateku | 0:33feccbba3ff | 251 | inline static int op_getglobal( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 252 | { |
tk_takateku | 0:33feccbba3ff | 253 | int ra = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 254 | int rb = GETARG_Bx(code); |
tk_takateku | 0:33feccbba3ff | 255 | char *sym = find_irep_symbol(vm->pc_irep->ptr_to_sym, rb); |
tk_takateku | 0:33feccbba3ff | 256 | mrb_sym sym_id = add_sym(sym); |
tk_takateku | 0:33feccbba3ff | 257 | regs[ra] = global_object_get(sym_id); |
tk_takateku | 0:33feccbba3ff | 258 | return 0; |
tk_takateku | 0:33feccbba3ff | 259 | } |
tk_takateku | 0:33feccbba3ff | 260 | |
tk_takateku | 0:33feccbba3ff | 261 | |
tk_takateku | 0:33feccbba3ff | 262 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 263 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 264 | Execute SETGLOBAL |
tk_takateku | 0:33feccbba3ff | 265 | |
tk_takateku | 0:33feccbba3ff | 266 | setglobal(Syms(Bx), R(A)) |
tk_takateku | 0:33feccbba3ff | 267 | |
tk_takateku | 0:33feccbba3ff | 268 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 269 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 270 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 271 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 272 | */ |
tk_takateku | 0:33feccbba3ff | 273 | inline static int op_setglobal( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 274 | { |
tk_takateku | 0:33feccbba3ff | 275 | int ra = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 276 | int rb = GETARG_Bx(code); |
tk_takateku | 0:33feccbba3ff | 277 | char *sym = find_irep_symbol(vm->pc_irep->ptr_to_sym, rb); |
tk_takateku | 0:33feccbba3ff | 278 | mrb_sym sym_id = add_sym(sym); |
tk_takateku | 0:33feccbba3ff | 279 | global_object_add(sym_id, ®s[ra]); |
tk_takateku | 0:33feccbba3ff | 280 | return 0; |
tk_takateku | 0:33feccbba3ff | 281 | } |
tk_takateku | 0:33feccbba3ff | 282 | |
tk_takateku | 0:33feccbba3ff | 283 | |
tk_takateku | 0:33feccbba3ff | 284 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 285 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 286 | Execute GETCONST |
tk_takateku | 0:33feccbba3ff | 287 | |
tk_takateku | 0:33feccbba3ff | 288 | R(A) := constget(Syms(Bx)) |
tk_takateku | 0:33feccbba3ff | 289 | |
tk_takateku | 0:33feccbba3ff | 290 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 291 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 292 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 293 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 294 | */ |
tk_takateku | 0:33feccbba3ff | 295 | inline static int op_getconst( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 296 | { |
tk_takateku | 0:33feccbba3ff | 297 | int ra = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 298 | int rb = GETARG_Bx(code); |
tk_takateku | 0:33feccbba3ff | 299 | char *sym = find_irep_symbol(vm->pc_irep->ptr_to_sym, rb); |
tk_takateku | 0:33feccbba3ff | 300 | mrb_sym sym_id = add_sym(sym); |
tk_takateku | 0:33feccbba3ff | 301 | regs[ra] = const_get(sym_id); |
tk_takateku | 0:33feccbba3ff | 302 | return 0; |
tk_takateku | 0:33feccbba3ff | 303 | } |
tk_takateku | 0:33feccbba3ff | 304 | |
tk_takateku | 0:33feccbba3ff | 305 | |
tk_takateku | 0:33feccbba3ff | 306 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 307 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 308 | Execute SETCONST |
tk_takateku | 0:33feccbba3ff | 309 | |
tk_takateku | 0:33feccbba3ff | 310 | constset(Syms(Bx),R(A)) |
tk_takateku | 0:33feccbba3ff | 311 | |
tk_takateku | 0:33feccbba3ff | 312 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 313 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 314 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 315 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 316 | */ |
tk_takateku | 0:33feccbba3ff | 317 | |
tk_takateku | 0:33feccbba3ff | 318 | inline static int op_setconst( mrb_vm *vm, uint32_t code, mrb_value *regs ) { |
tk_takateku | 0:33feccbba3ff | 319 | int ra = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 320 | int rb = GETARG_Bx(code); |
tk_takateku | 0:33feccbba3ff | 321 | char *sym = find_irep_symbol(vm->pc_irep->ptr_to_sym, rb); |
tk_takateku | 0:33feccbba3ff | 322 | mrb_sym sym_id = add_sym(sym); |
tk_takateku | 0:33feccbba3ff | 323 | const_add(sym_id, ®s[ra]); |
tk_takateku | 0:33feccbba3ff | 324 | return 0; |
tk_takateku | 0:33feccbba3ff | 325 | } |
tk_takateku | 0:33feccbba3ff | 326 | |
tk_takateku | 0:33feccbba3ff | 327 | |
tk_takateku | 0:33feccbba3ff | 328 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 329 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 330 | Execute JMP |
tk_takateku | 0:33feccbba3ff | 331 | |
tk_takateku | 0:33feccbba3ff | 332 | pc += sBx |
tk_takateku | 0:33feccbba3ff | 333 | |
tk_takateku | 0:33feccbba3ff | 334 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 335 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 336 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 337 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 338 | */ |
tk_takateku | 0:33feccbba3ff | 339 | inline static int op_jmp( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 340 | { |
tk_takateku | 0:33feccbba3ff | 341 | vm->pc += GETARG_sBx(code) - 1; |
tk_takateku | 0:33feccbba3ff | 342 | return 0; |
tk_takateku | 0:33feccbba3ff | 343 | } |
tk_takateku | 0:33feccbba3ff | 344 | |
tk_takateku | 0:33feccbba3ff | 345 | |
tk_takateku | 0:33feccbba3ff | 346 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 347 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 348 | Execute JMPIF |
tk_takateku | 0:33feccbba3ff | 349 | |
tk_takateku | 0:33feccbba3ff | 350 | if R(A) pc += sBx |
tk_takateku | 0:33feccbba3ff | 351 | |
tk_takateku | 0:33feccbba3ff | 352 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 353 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 354 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 355 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 356 | */ |
tk_takateku | 0:33feccbba3ff | 357 | inline static int op_jmpif( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 358 | { |
tk_takateku | 0:33feccbba3ff | 359 | if( regs[GETARG_A(code)].tt != MRB_TT_FALSE ) { |
tk_takateku | 0:33feccbba3ff | 360 | vm->pc += GETARG_sBx(code) - 1; |
tk_takateku | 0:33feccbba3ff | 361 | } |
tk_takateku | 0:33feccbba3ff | 362 | return 0; |
tk_takateku | 0:33feccbba3ff | 363 | } |
tk_takateku | 0:33feccbba3ff | 364 | |
tk_takateku | 0:33feccbba3ff | 365 | |
tk_takateku | 0:33feccbba3ff | 366 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 367 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 368 | Execute JMPNOT |
tk_takateku | 0:33feccbba3ff | 369 | |
tk_takateku | 0:33feccbba3ff | 370 | if not R(A) pc += sBx |
tk_takateku | 0:33feccbba3ff | 371 | |
tk_takateku | 0:33feccbba3ff | 372 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 373 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 374 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 375 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 376 | */ |
tk_takateku | 0:33feccbba3ff | 377 | inline static int op_jmpnot( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 378 | { |
tk_takateku | 0:33feccbba3ff | 379 | if( regs[GETARG_A(code)].tt == MRB_TT_FALSE ) { |
tk_takateku | 0:33feccbba3ff | 380 | vm->pc += GETARG_sBx(code) - 1; |
tk_takateku | 0:33feccbba3ff | 381 | } |
tk_takateku | 0:33feccbba3ff | 382 | return 0; |
tk_takateku | 0:33feccbba3ff | 383 | } |
tk_takateku | 0:33feccbba3ff | 384 | |
tk_takateku | 0:33feccbba3ff | 385 | |
tk_takateku | 0:33feccbba3ff | 386 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 387 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 388 | Execute SEND |
tk_takateku | 0:33feccbba3ff | 389 | |
tk_takateku | 0:33feccbba3ff | 390 | R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) |
tk_takateku | 0:33feccbba3ff | 391 | |
tk_takateku | 0:33feccbba3ff | 392 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 393 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 394 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 395 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 396 | */ |
tk_takateku | 0:33feccbba3ff | 397 | inline static int op_send( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 398 | { |
tk_takateku | 0:33feccbba3ff | 399 | mrb_value recv = regs[GETARG_A(code)]; |
tk_takateku | 0:33feccbba3ff | 400 | int rb = GETARG_B(code); |
tk_takateku | 0:33feccbba3ff | 401 | char *sym = find_irep_symbol(vm->pc_irep->ptr_to_sym, rb); |
tk_takateku | 0:33feccbba3ff | 402 | mrb_sym sym_id = str_to_symid(sym); |
tk_takateku | 0:33feccbba3ff | 403 | mrb_proc *m = find_method(vm, recv, sym_id); |
tk_takateku | 0:33feccbba3ff | 404 | |
tk_takateku | 0:33feccbba3ff | 405 | if( m == 0 ) { |
tk_takateku | 0:33feccbba3ff | 406 | console_printf("no method(%s)!\n", sym); |
tk_takateku | 0:33feccbba3ff | 407 | } else { |
tk_takateku | 0:33feccbba3ff | 408 | if( m->c_func == 0 ) { |
tk_takateku | 0:33feccbba3ff | 409 | // Ruby method |
tk_takateku | 0:33feccbba3ff | 410 | // callinfo |
tk_takateku | 0:33feccbba3ff | 411 | mrb_callinfo *callinfo = vm->callinfo + vm->callinfo_top; |
tk_takateku | 0:33feccbba3ff | 412 | callinfo->reg_top = vm->reg_top; |
tk_takateku | 0:33feccbba3ff | 413 | callinfo->pc_irep = vm->pc_irep; |
tk_takateku | 0:33feccbba3ff | 414 | callinfo->pc = vm->pc; |
tk_takateku | 0:33feccbba3ff | 415 | callinfo->n_args = GETARG_C(code); |
tk_takateku | 0:33feccbba3ff | 416 | vm->callinfo_top++; |
tk_takateku | 0:33feccbba3ff | 417 | // target irep |
tk_takateku | 0:33feccbba3ff | 418 | vm->pc = 0; |
tk_takateku | 0:33feccbba3ff | 419 | vm->pc_irep = m->func.irep; |
tk_takateku | 0:33feccbba3ff | 420 | // new regs |
tk_takateku | 0:33feccbba3ff | 421 | vm->reg_top += GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 422 | } else { |
tk_takateku | 0:33feccbba3ff | 423 | // C func |
tk_takateku | 0:33feccbba3ff | 424 | m->func.func(vm, regs+GETARG_A(code)); |
tk_takateku | 0:33feccbba3ff | 425 | } |
tk_takateku | 0:33feccbba3ff | 426 | } |
tk_takateku | 0:33feccbba3ff | 427 | return 0; |
tk_takateku | 0:33feccbba3ff | 428 | } |
tk_takateku | 0:33feccbba3ff | 429 | |
tk_takateku | 0:33feccbba3ff | 430 | |
tk_takateku | 0:33feccbba3ff | 431 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 432 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 433 | Execute ENTER |
tk_takateku | 0:33feccbba3ff | 434 | |
tk_takateku | 0:33feccbba3ff | 435 | arg setup according to flags (23=5:5:1:5:5:1:1) |
tk_takateku | 0:33feccbba3ff | 436 | |
tk_takateku | 0:33feccbba3ff | 437 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 438 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 439 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 440 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 441 | */ |
tk_takateku | 0:33feccbba3ff | 442 | inline static int op_enter( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 443 | { |
tk_takateku | 0:33feccbba3ff | 444 | mrb_callinfo *callinfo = vm->callinfo + vm->callinfo_top - 1; |
tk_takateku | 0:33feccbba3ff | 445 | uint32_t enter_param = GETARG_Ax(code); |
tk_takateku | 0:33feccbba3ff | 446 | int def_args = (enter_param >> 13) & 0x1f; |
tk_takateku | 0:33feccbba3ff | 447 | int args = (enter_param >> 18) & 0x1f; |
tk_takateku | 0:33feccbba3ff | 448 | if( def_args > 0 ){ |
tk_takateku | 0:33feccbba3ff | 449 | vm->pc += callinfo->n_args - args; |
tk_takateku | 0:33feccbba3ff | 450 | } |
tk_takateku | 0:33feccbba3ff | 451 | return 0; |
tk_takateku | 0:33feccbba3ff | 452 | } |
tk_takateku | 0:33feccbba3ff | 453 | |
tk_takateku | 0:33feccbba3ff | 454 | |
tk_takateku | 0:33feccbba3ff | 455 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 456 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 457 | Execute RETURN |
tk_takateku | 0:33feccbba3ff | 458 | |
tk_takateku | 0:33feccbba3ff | 459 | return R(A) (B=normal,in-block return/break) |
tk_takateku | 0:33feccbba3ff | 460 | |
tk_takateku | 0:33feccbba3ff | 461 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 462 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 463 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 464 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 465 | */ |
tk_takateku | 0:33feccbba3ff | 466 | inline static int op_return( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 467 | { |
tk_takateku | 0:33feccbba3ff | 468 | // return value |
tk_takateku | 0:33feccbba3ff | 469 | mrb_value v = regs[GETARG_A(code)]; |
tk_takateku | 0:33feccbba3ff | 470 | regs[0] = v; |
tk_takateku | 0:33feccbba3ff | 471 | // restore irep,pc,regs |
tk_takateku | 0:33feccbba3ff | 472 | vm->callinfo_top--; |
tk_takateku | 0:33feccbba3ff | 473 | mrb_callinfo *callinfo = vm->callinfo + vm->callinfo_top; |
tk_takateku | 0:33feccbba3ff | 474 | vm->reg_top = callinfo->reg_top; |
tk_takateku | 0:33feccbba3ff | 475 | vm->pc_irep = callinfo->pc_irep; |
tk_takateku | 0:33feccbba3ff | 476 | vm->pc = callinfo->pc; |
tk_takateku | 0:33feccbba3ff | 477 | return 0; |
tk_takateku | 0:33feccbba3ff | 478 | } |
tk_takateku | 0:33feccbba3ff | 479 | |
tk_takateku | 0:33feccbba3ff | 480 | |
tk_takateku | 0:33feccbba3ff | 481 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 482 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 483 | Execute ADD |
tk_takateku | 0:33feccbba3ff | 484 | |
tk_takateku | 0:33feccbba3ff | 485 | R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1) |
tk_takateku | 0:33feccbba3ff | 486 | |
tk_takateku | 0:33feccbba3ff | 487 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 488 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 489 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 490 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 491 | */ |
tk_takateku | 0:33feccbba3ff | 492 | inline static int op_add( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 493 | { |
tk_takateku | 0:33feccbba3ff | 494 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 495 | |
tk_takateku | 0:33feccbba3ff | 496 | // support Fixnum + Fixnum |
tk_takateku | 0:33feccbba3ff | 497 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 498 | regs[rr].value.i += regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 499 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 500 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 501 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 502 | regs[rr].value.d += regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 503 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 504 | regs[rr].value.d += regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 505 | } else { |
tk_takateku | 0:33feccbba3ff | 506 | op_send(vm, code, regs); |
tk_takateku | 0:33feccbba3ff | 507 | } |
tk_takateku | 0:33feccbba3ff | 508 | #endif |
tk_takateku | 0:33feccbba3ff | 509 | #if MRBC_USE_STRING |
tk_takateku | 0:33feccbba3ff | 510 | } else if( regs[rr].tt == MRB_TT_STRING && regs[rr+1].tt == MRB_TT_STRING ){ |
tk_takateku | 0:33feccbba3ff | 511 | regs[rr].value.str = mrbc_string_cat(vm, regs[rr].value.str, regs[rr+1].value.str); |
tk_takateku | 0:33feccbba3ff | 512 | |
tk_takateku | 0:33feccbba3ff | 513 | #endif |
tk_takateku | 0:33feccbba3ff | 514 | } else { |
tk_takateku | 0:33feccbba3ff | 515 | op_send(vm, code, regs); |
tk_takateku | 0:33feccbba3ff | 516 | } |
tk_takateku | 0:33feccbba3ff | 517 | |
tk_takateku | 0:33feccbba3ff | 518 | return 0; |
tk_takateku | 0:33feccbba3ff | 519 | } |
tk_takateku | 0:33feccbba3ff | 520 | |
tk_takateku | 0:33feccbba3ff | 521 | |
tk_takateku | 0:33feccbba3ff | 522 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 523 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 524 | Execute ADDI |
tk_takateku | 0:33feccbba3ff | 525 | |
tk_takateku | 0:33feccbba3ff | 526 | R(A) := R(A)+C (Syms[B]=:+) |
tk_takateku | 0:33feccbba3ff | 527 | |
tk_takateku | 0:33feccbba3ff | 528 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 529 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 530 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 531 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 532 | */ |
tk_takateku | 0:33feccbba3ff | 533 | inline static int op_addi( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 534 | { |
tk_takateku | 0:33feccbba3ff | 535 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 536 | |
tk_takateku | 0:33feccbba3ff | 537 | // support Fixnum + (value) |
tk_takateku | 0:33feccbba3ff | 538 | if( regs[rr].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 539 | regs[rr].value.i += GETARG_C(code); |
tk_takateku | 0:33feccbba3ff | 540 | } else { |
tk_takateku | 0:33feccbba3ff | 541 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 542 | } |
tk_takateku | 0:33feccbba3ff | 543 | |
tk_takateku | 0:33feccbba3ff | 544 | return 0; |
tk_takateku | 0:33feccbba3ff | 545 | } |
tk_takateku | 0:33feccbba3ff | 546 | |
tk_takateku | 0:33feccbba3ff | 547 | |
tk_takateku | 0:33feccbba3ff | 548 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 549 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 550 | Execute ADD |
tk_takateku | 0:33feccbba3ff | 551 | |
tk_takateku | 0:33feccbba3ff | 552 | R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1) |
tk_takateku | 0:33feccbba3ff | 553 | |
tk_takateku | 0:33feccbba3ff | 554 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 555 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 556 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 557 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 558 | */ |
tk_takateku | 0:33feccbba3ff | 559 | inline static int op_sub( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 560 | { |
tk_takateku | 0:33feccbba3ff | 561 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 562 | |
tk_takateku | 0:33feccbba3ff | 563 | // support Fixnum - Fixnum |
tk_takateku | 0:33feccbba3ff | 564 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 565 | regs[rr].value.i -= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 566 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 567 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 568 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 569 | regs[rr].value.d -= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 570 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 571 | regs[rr].value.d -= regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 572 | } else { |
tk_takateku | 0:33feccbba3ff | 573 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 574 | } |
tk_takateku | 0:33feccbba3ff | 575 | #endif |
tk_takateku | 0:33feccbba3ff | 576 | } else { |
tk_takateku | 0:33feccbba3ff | 577 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 578 | } |
tk_takateku | 0:33feccbba3ff | 579 | |
tk_takateku | 0:33feccbba3ff | 580 | return 0; |
tk_takateku | 0:33feccbba3ff | 581 | } |
tk_takateku | 0:33feccbba3ff | 582 | |
tk_takateku | 0:33feccbba3ff | 583 | |
tk_takateku | 0:33feccbba3ff | 584 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 585 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 586 | Execute |
tk_takateku | 0:33feccbba3ff | 587 | |
tk_takateku | 0:33feccbba3ff | 588 | R(A) := R(A)-C (Syms[B]=:-) |
tk_takateku | 0:33feccbba3ff | 589 | |
tk_takateku | 0:33feccbba3ff | 590 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 591 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 592 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 593 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 594 | */ |
tk_takateku | 0:33feccbba3ff | 595 | inline static int op_subi( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 596 | { |
tk_takateku | 0:33feccbba3ff | 597 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 598 | |
tk_takateku | 0:33feccbba3ff | 599 | // support Fixnum + (value) |
tk_takateku | 0:33feccbba3ff | 600 | if( regs[rr].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 601 | regs[rr].value.i -= GETARG_C(code); |
tk_takateku | 0:33feccbba3ff | 602 | } else { |
tk_takateku | 0:33feccbba3ff | 603 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 604 | } |
tk_takateku | 0:33feccbba3ff | 605 | |
tk_takateku | 0:33feccbba3ff | 606 | return 0; |
tk_takateku | 0:33feccbba3ff | 607 | } |
tk_takateku | 0:33feccbba3ff | 608 | |
tk_takateku | 0:33feccbba3ff | 609 | |
tk_takateku | 0:33feccbba3ff | 610 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 611 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 612 | Execute |
tk_takateku | 0:33feccbba3ff | 613 | |
tk_takateku | 0:33feccbba3ff | 614 | R(A) := R(A)*R(A+1) (Syms[B]=:*) |
tk_takateku | 0:33feccbba3ff | 615 | |
tk_takateku | 0:33feccbba3ff | 616 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 617 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 618 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 619 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 620 | */ |
tk_takateku | 0:33feccbba3ff | 621 | inline static int op_mul( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 622 | { |
tk_takateku | 0:33feccbba3ff | 623 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 624 | |
tk_takateku | 0:33feccbba3ff | 625 | // support Fixnum * Fixnum |
tk_takateku | 0:33feccbba3ff | 626 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 627 | regs[rr].value.i *= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 628 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 629 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 630 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 631 | regs[rr].value.d *= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 632 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 633 | regs[rr].value.d *= regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 634 | } else { |
tk_takateku | 0:33feccbba3ff | 635 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 636 | } |
tk_takateku | 0:33feccbba3ff | 637 | #endif |
tk_takateku | 0:33feccbba3ff | 638 | } else { |
tk_takateku | 0:33feccbba3ff | 639 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 640 | } |
tk_takateku | 0:33feccbba3ff | 641 | |
tk_takateku | 0:33feccbba3ff | 642 | return 0; |
tk_takateku | 0:33feccbba3ff | 643 | } |
tk_takateku | 0:33feccbba3ff | 644 | |
tk_takateku | 0:33feccbba3ff | 645 | |
tk_takateku | 0:33feccbba3ff | 646 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 647 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 648 | Execute |
tk_takateku | 0:33feccbba3ff | 649 | |
tk_takateku | 0:33feccbba3ff | 650 | R(A) := R(A)/R(A+1) (Syms[B]=:/) |
tk_takateku | 0:33feccbba3ff | 651 | |
tk_takateku | 0:33feccbba3ff | 652 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 653 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 654 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 655 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 656 | */ |
tk_takateku | 0:33feccbba3ff | 657 | inline static int op_div( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 658 | { |
tk_takateku | 0:33feccbba3ff | 659 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 660 | |
tk_takateku | 0:33feccbba3ff | 661 | // support Fixnum * Fixnum |
tk_takateku | 0:33feccbba3ff | 662 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 663 | regs[rr].value.i /= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 664 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 665 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 666 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 667 | regs[rr].value.d /= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 668 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 669 | regs[rr].value.d /= regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 670 | } else { |
tk_takateku | 0:33feccbba3ff | 671 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 672 | } |
tk_takateku | 0:33feccbba3ff | 673 | #endif |
tk_takateku | 0:33feccbba3ff | 674 | } else { |
tk_takateku | 0:33feccbba3ff | 675 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 676 | } |
tk_takateku | 0:33feccbba3ff | 677 | |
tk_takateku | 0:33feccbba3ff | 678 | return 0; |
tk_takateku | 0:33feccbba3ff | 679 | } |
tk_takateku | 0:33feccbba3ff | 680 | |
tk_takateku | 0:33feccbba3ff | 681 | |
tk_takateku | 0:33feccbba3ff | 682 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 683 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 684 | Execute EQ |
tk_takateku | 0:33feccbba3ff | 685 | |
tk_takateku | 0:33feccbba3ff | 686 | R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1) |
tk_takateku | 0:33feccbba3ff | 687 | |
tk_takateku | 0:33feccbba3ff | 688 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 689 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 690 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 691 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 692 | */ |
tk_takateku | 0:33feccbba3ff | 693 | inline static int op_eq( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 694 | { |
tk_takateku | 0:33feccbba3ff | 695 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 696 | int result; |
tk_takateku | 0:33feccbba3ff | 697 | |
tk_takateku | 0:33feccbba3ff | 698 | // |
tk_takateku | 0:33feccbba3ff | 699 | if( mrbc_eq(®s[rr], ®s[rr+1]) ){ |
tk_takateku | 0:33feccbba3ff | 700 | regs[rr].tt = MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 701 | } else { |
tk_takateku | 0:33feccbba3ff | 702 | regs[rr].tt = MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 703 | } |
tk_takateku | 0:33feccbba3ff | 704 | return 1; |
tk_takateku | 0:33feccbba3ff | 705 | |
tk_takateku | 0:33feccbba3ff | 706 | // support Fixnum + Fixnum |
tk_takateku | 0:33feccbba3ff | 707 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 708 | result = (regs[rr].value.i == regs[rr+1].value.i); |
tk_takateku | 0:33feccbba3ff | 709 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 710 | if( regs[rr].tt == MRB_TT_FLOAT ) { |
tk_takateku | 0:33feccbba3ff | 711 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 712 | result = (regs[rr].value.d == regs[rr+1].value.i ); |
tk_takateku | 0:33feccbba3ff | 713 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 714 | result = (regs[rr].value.d == regs[rr+1].value.d ); |
tk_takateku | 0:33feccbba3ff | 715 | } else { |
tk_takateku | 0:33feccbba3ff | 716 | result = 0; |
tk_takateku | 0:33feccbba3ff | 717 | } |
tk_takateku | 0:33feccbba3ff | 718 | } |
tk_takateku | 0:33feccbba3ff | 719 | #endif |
tk_takateku | 0:33feccbba3ff | 720 | } else if( regs[rr].tt == MRB_TT_TRUE ){ |
tk_takateku | 0:33feccbba3ff | 721 | result = regs[rr+1].tt == MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 722 | } else if( regs[rr].tt == MRB_TT_FALSE ){ |
tk_takateku | 0:33feccbba3ff | 723 | result = regs[rr+1].tt == MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 724 | } else { |
tk_takateku | 0:33feccbba3ff | 725 | op_send(vm,code,regs); |
tk_takateku | 0:33feccbba3ff | 726 | result = regs[rr].tt == MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 727 | } |
tk_takateku | 0:33feccbba3ff | 728 | if( result ) { |
tk_takateku | 0:33feccbba3ff | 729 | regs[rr].tt = MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 730 | } else { |
tk_takateku | 0:33feccbba3ff | 731 | regs[rr].tt = MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 732 | } |
tk_takateku | 0:33feccbba3ff | 733 | |
tk_takateku | 0:33feccbba3ff | 734 | return 0; |
tk_takateku | 0:33feccbba3ff | 735 | } |
tk_takateku | 0:33feccbba3ff | 736 | |
tk_takateku | 0:33feccbba3ff | 737 | |
tk_takateku | 0:33feccbba3ff | 738 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 739 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 740 | Execute LT |
tk_takateku | 0:33feccbba3ff | 741 | |
tk_takateku | 0:33feccbba3ff | 742 | R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1) |
tk_takateku | 0:33feccbba3ff | 743 | |
tk_takateku | 0:33feccbba3ff | 744 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 745 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 746 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 747 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 748 | */ |
tk_takateku | 0:33feccbba3ff | 749 | inline static int op_lt( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 750 | { |
tk_takateku | 0:33feccbba3ff | 751 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 752 | int result; |
tk_takateku | 0:33feccbba3ff | 753 | |
tk_takateku | 0:33feccbba3ff | 754 | // support Fixnum + Fixnum |
tk_takateku | 0:33feccbba3ff | 755 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 756 | result = regs[rr].value.i < regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 757 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 758 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 759 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 760 | result = regs[rr].value.d < regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 761 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 762 | result = regs[rr].value.d < regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 763 | } else { |
tk_takateku | 0:33feccbba3ff | 764 | result = 0; |
tk_takateku | 0:33feccbba3ff | 765 | } |
tk_takateku | 0:33feccbba3ff | 766 | #endif |
tk_takateku | 0:33feccbba3ff | 767 | } else { |
tk_takateku | 0:33feccbba3ff | 768 | result = 0; |
tk_takateku | 0:33feccbba3ff | 769 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 770 | } |
tk_takateku | 0:33feccbba3ff | 771 | |
tk_takateku | 0:33feccbba3ff | 772 | if( result ) { |
tk_takateku | 0:33feccbba3ff | 773 | regs[rr].tt = MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 774 | } else { |
tk_takateku | 0:33feccbba3ff | 775 | regs[rr].tt = MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 776 | } |
tk_takateku | 0:33feccbba3ff | 777 | |
tk_takateku | 0:33feccbba3ff | 778 | return 0; |
tk_takateku | 0:33feccbba3ff | 779 | } |
tk_takateku | 0:33feccbba3ff | 780 | |
tk_takateku | 0:33feccbba3ff | 781 | |
tk_takateku | 0:33feccbba3ff | 782 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 783 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 784 | Execute LE |
tk_takateku | 0:33feccbba3ff | 785 | |
tk_takateku | 0:33feccbba3ff | 786 | R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1) |
tk_takateku | 0:33feccbba3ff | 787 | |
tk_takateku | 0:33feccbba3ff | 788 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 789 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 790 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 791 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 792 | */ |
tk_takateku | 0:33feccbba3ff | 793 | inline static int op_le( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 794 | { |
tk_takateku | 0:33feccbba3ff | 795 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 796 | int result; |
tk_takateku | 0:33feccbba3ff | 797 | |
tk_takateku | 0:33feccbba3ff | 798 | // support Fixnum + Fixnum |
tk_takateku | 0:33feccbba3ff | 799 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 800 | result = regs[rr].value.i <= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 801 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 802 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 803 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 804 | result = regs[rr].value.d <= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 805 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 806 | result = regs[rr].value.d <= regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 807 | } else { |
tk_takateku | 0:33feccbba3ff | 808 | result = 0; |
tk_takateku | 0:33feccbba3ff | 809 | } |
tk_takateku | 0:33feccbba3ff | 810 | #endif |
tk_takateku | 0:33feccbba3ff | 811 | } else { |
tk_takateku | 0:33feccbba3ff | 812 | result = 0; |
tk_takateku | 0:33feccbba3ff | 813 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 814 | } |
tk_takateku | 0:33feccbba3ff | 815 | if( result ) { |
tk_takateku | 0:33feccbba3ff | 816 | regs[rr].tt = MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 817 | } else { |
tk_takateku | 0:33feccbba3ff | 818 | regs[rr].tt = MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 819 | } |
tk_takateku | 0:33feccbba3ff | 820 | |
tk_takateku | 0:33feccbba3ff | 821 | return 0; |
tk_takateku | 0:33feccbba3ff | 822 | } |
tk_takateku | 0:33feccbba3ff | 823 | |
tk_takateku | 0:33feccbba3ff | 824 | |
tk_takateku | 0:33feccbba3ff | 825 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 826 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 827 | Execute GE |
tk_takateku | 0:33feccbba3ff | 828 | |
tk_takateku | 0:33feccbba3ff | 829 | R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1) |
tk_takateku | 0:33feccbba3ff | 830 | |
tk_takateku | 0:33feccbba3ff | 831 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 832 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 833 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 834 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 835 | */ |
tk_takateku | 0:33feccbba3ff | 836 | inline static int op_gt( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 837 | { |
tk_takateku | 0:33feccbba3ff | 838 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 839 | int result; |
tk_takateku | 0:33feccbba3ff | 840 | |
tk_takateku | 0:33feccbba3ff | 841 | // support Fixnum + Fixnum |
tk_takateku | 0:33feccbba3ff | 842 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 843 | result = regs[rr].value.i > regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 844 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 845 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 846 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 847 | result = regs[rr].value.d > regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 848 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 849 | result = regs[rr].value.d > regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 850 | } else { |
tk_takateku | 0:33feccbba3ff | 851 | result = 0; |
tk_takateku | 0:33feccbba3ff | 852 | } |
tk_takateku | 0:33feccbba3ff | 853 | #endif |
tk_takateku | 0:33feccbba3ff | 854 | } else { |
tk_takateku | 0:33feccbba3ff | 855 | result = 0; |
tk_takateku | 0:33feccbba3ff | 856 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 857 | } |
tk_takateku | 0:33feccbba3ff | 858 | if( result ) { |
tk_takateku | 0:33feccbba3ff | 859 | regs[rr].tt = MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 860 | } else { |
tk_takateku | 0:33feccbba3ff | 861 | regs[rr].tt = MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 862 | } |
tk_takateku | 0:33feccbba3ff | 863 | |
tk_takateku | 0:33feccbba3ff | 864 | return 0; |
tk_takateku | 0:33feccbba3ff | 865 | } |
tk_takateku | 0:33feccbba3ff | 866 | |
tk_takateku | 0:33feccbba3ff | 867 | |
tk_takateku | 0:33feccbba3ff | 868 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 869 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 870 | Execute GE |
tk_takateku | 0:33feccbba3ff | 871 | |
tk_takateku | 0:33feccbba3ff | 872 | R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1) |
tk_takateku | 0:33feccbba3ff | 873 | |
tk_takateku | 0:33feccbba3ff | 874 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 875 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 876 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 877 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 878 | */ |
tk_takateku | 0:33feccbba3ff | 879 | inline static int op_ge( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 880 | { |
tk_takateku | 0:33feccbba3ff | 881 | int rr = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 882 | int result; |
tk_takateku | 0:33feccbba3ff | 883 | |
tk_takateku | 0:33feccbba3ff | 884 | // support Fixnum + Fixnum |
tk_takateku | 0:33feccbba3ff | 885 | if( regs[rr].tt == MRB_TT_FIXNUM && regs[rr+1].tt == MRB_TT_FIXNUM ) { |
tk_takateku | 0:33feccbba3ff | 886 | result = regs[rr].value.i >= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 887 | #if MRBC_USE_FLOAT |
tk_takateku | 0:33feccbba3ff | 888 | } else if( regs[rr].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 889 | if( regs[rr+1].tt == MRB_TT_FIXNUM ){ |
tk_takateku | 0:33feccbba3ff | 890 | result = regs[rr].value.d >= regs[rr+1].value.i; |
tk_takateku | 0:33feccbba3ff | 891 | } else if( regs[rr+1].tt == MRB_TT_FLOAT ){ |
tk_takateku | 0:33feccbba3ff | 892 | result = regs[rr].value.d >= regs[rr+1].value.d; |
tk_takateku | 0:33feccbba3ff | 893 | } else { |
tk_takateku | 0:33feccbba3ff | 894 | result = 0; |
tk_takateku | 0:33feccbba3ff | 895 | } |
tk_takateku | 0:33feccbba3ff | 896 | #endif |
tk_takateku | 0:33feccbba3ff | 897 | } else { |
tk_takateku | 0:33feccbba3ff | 898 | result = 0; |
tk_takateku | 0:33feccbba3ff | 899 | not_supported(); |
tk_takateku | 0:33feccbba3ff | 900 | } |
tk_takateku | 0:33feccbba3ff | 901 | if( result ) { |
tk_takateku | 0:33feccbba3ff | 902 | regs[rr].tt = MRB_TT_TRUE; |
tk_takateku | 0:33feccbba3ff | 903 | } else { |
tk_takateku | 0:33feccbba3ff | 904 | regs[rr].tt = MRB_TT_FALSE; |
tk_takateku | 0:33feccbba3ff | 905 | } |
tk_takateku | 0:33feccbba3ff | 906 | |
tk_takateku | 0:33feccbba3ff | 907 | return 0; |
tk_takateku | 0:33feccbba3ff | 908 | } |
tk_takateku | 0:33feccbba3ff | 909 | |
tk_takateku | 0:33feccbba3ff | 910 | |
tk_takateku | 0:33feccbba3ff | 911 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 912 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 913 | Make Array |
tk_takateku | 0:33feccbba3ff | 914 | |
tk_takateku | 0:33feccbba3ff | 915 | R(A) := ary_new(R(B),R(B+1)..R(B+C)) |
tk_takateku | 0:33feccbba3ff | 916 | |
tk_takateku | 0:33feccbba3ff | 917 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 918 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 919 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 920 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 921 | */ |
tk_takateku | 0:33feccbba3ff | 922 | inline static int op_array( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 923 | { |
tk_takateku | 0:33feccbba3ff | 924 | int arg_a = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 925 | int arg_b = GETARG_B(code); |
tk_takateku | 0:33feccbba3ff | 926 | int arg_c = GETARG_C(code); |
tk_takateku | 0:33feccbba3ff | 927 | mrb_value *ptr; |
tk_takateku | 0:33feccbba3ff | 928 | |
tk_takateku | 0:33feccbba3ff | 929 | mrb_value v; |
tk_takateku | 0:33feccbba3ff | 930 | v.tt = MRB_TT_ARRAY; |
tk_takateku | 0:33feccbba3ff | 931 | v.value.obj = 0; |
tk_takateku | 0:33feccbba3ff | 932 | |
tk_takateku | 0:33feccbba3ff | 933 | if( arg_c >= 0 ){ |
tk_takateku | 0:33feccbba3ff | 934 | mrb_object *p; |
tk_takateku | 0:33feccbba3ff | 935 | // ptr[0] : array info |
tk_takateku | 0:33feccbba3ff | 936 | // ptr[1..] : array elements |
tk_takateku | 0:33feccbba3ff | 937 | ptr = (mrb_value*)mrbc_alloc(vm, sizeof(mrb_value)*(arg_c + 1)); |
tk_takateku | 0:33feccbba3ff | 938 | if( ptr == NULL ) return 0; // ENOMEM |
tk_takateku | 0:33feccbba3ff | 939 | |
tk_takateku | 0:33feccbba3ff | 940 | v.value.obj = ptr; |
tk_takateku | 0:33feccbba3ff | 941 | ptr->tt = MRB_TT_FIXNUM; |
tk_takateku | 0:33feccbba3ff | 942 | ptr->value.i = arg_c; |
tk_takateku | 0:33feccbba3ff | 943 | |
tk_takateku | 0:33feccbba3ff | 944 | p = ptr + 1; |
tk_takateku | 0:33feccbba3ff | 945 | while( arg_c > 0 ){ |
tk_takateku | 0:33feccbba3ff | 946 | p->tt = regs[arg_b].tt; |
tk_takateku | 0:33feccbba3ff | 947 | p->value = regs[arg_b].value; |
tk_takateku | 0:33feccbba3ff | 948 | p++; |
tk_takateku | 0:33feccbba3ff | 949 | arg_c--; |
tk_takateku | 0:33feccbba3ff | 950 | arg_b++; |
tk_takateku | 0:33feccbba3ff | 951 | } |
tk_takateku | 0:33feccbba3ff | 952 | } |
tk_takateku | 0:33feccbba3ff | 953 | |
tk_takateku | 0:33feccbba3ff | 954 | regs[arg_a] = v; |
tk_takateku | 0:33feccbba3ff | 955 | |
tk_takateku | 0:33feccbba3ff | 956 | return 0; |
tk_takateku | 0:33feccbba3ff | 957 | } |
tk_takateku | 0:33feccbba3ff | 958 | |
tk_takateku | 0:33feccbba3ff | 959 | |
tk_takateku | 0:33feccbba3ff | 960 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 961 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 962 | Create string object |
tk_takateku | 0:33feccbba3ff | 963 | |
tk_takateku | 0:33feccbba3ff | 964 | R(A) := str_dup(Lit(Bx)) |
tk_takateku | 0:33feccbba3ff | 965 | |
tk_takateku | 0:33feccbba3ff | 966 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 967 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 968 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 969 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 970 | */ |
tk_takateku | 0:33feccbba3ff | 971 | inline static int op_string( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 972 | { |
tk_takateku | 0:33feccbba3ff | 973 | mrb_value v; |
tk_takateku | 0:33feccbba3ff | 974 | v.tt = MRB_TT_STRING; |
tk_takateku | 0:33feccbba3ff | 975 | |
tk_takateku | 0:33feccbba3ff | 976 | int arg_b = GETARG_Bx(code); |
tk_takateku | 0:33feccbba3ff | 977 | mrb_object *ptr = vm->pc_irep->ptr_to_pool; |
tk_takateku | 0:33feccbba3ff | 978 | while( arg_b > 0 ){ |
tk_takateku | 0:33feccbba3ff | 979 | ptr = ptr->next; |
tk_takateku | 0:33feccbba3ff | 980 | arg_b--; |
tk_takateku | 0:33feccbba3ff | 981 | } |
tk_takateku | 0:33feccbba3ff | 982 | v.value.str = mrbc_string_dup(vm, ptr->value.str); |
tk_takateku | 0:33feccbba3ff | 983 | |
tk_takateku | 0:33feccbba3ff | 984 | int arg_a = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 985 | regs[arg_a] = v; |
tk_takateku | 0:33feccbba3ff | 986 | return 0; |
tk_takateku | 0:33feccbba3ff | 987 | } |
tk_takateku | 0:33feccbba3ff | 988 | |
tk_takateku | 0:33feccbba3ff | 989 | |
tk_takateku | 0:33feccbba3ff | 990 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 991 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 992 | Create HASH object |
tk_takateku | 0:33feccbba3ff | 993 | |
tk_takateku | 0:33feccbba3ff | 994 | R(A) := hash_new(R(B),R(B+1)..R(B+C)) |
tk_takateku | 0:33feccbba3ff | 995 | |
tk_takateku | 0:33feccbba3ff | 996 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 997 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 998 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 999 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1000 | */ |
tk_takateku | 0:33feccbba3ff | 1001 | inline static int op_hash( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 1002 | { |
tk_takateku | 0:33feccbba3ff | 1003 | int arg_a = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 1004 | int arg_b = GETARG_B(code); |
tk_takateku | 0:33feccbba3ff | 1005 | int arg_c = GETARG_C(code); |
tk_takateku | 0:33feccbba3ff | 1006 | |
tk_takateku | 0:33feccbba3ff | 1007 | mrb_value v; // return value |
tk_takateku | 0:33feccbba3ff | 1008 | v.tt = MRB_TT_HASH; |
tk_takateku | 0:33feccbba3ff | 1009 | |
tk_takateku | 0:33feccbba3ff | 1010 | // make handle for hash pair |
tk_takateku | 0:33feccbba3ff | 1011 | mrb_value *handle = (mrb_value *)mrbc_alloc(vm, sizeof(mrb_value)); |
tk_takateku | 0:33feccbba3ff | 1012 | if( handle == NULL ) return 0; // ENOMEM |
tk_takateku | 0:33feccbba3ff | 1013 | |
tk_takateku | 0:33feccbba3ff | 1014 | v.value.obj = handle; |
tk_takateku | 0:33feccbba3ff | 1015 | handle->tt = MRB_TT_HANDLE; |
tk_takateku | 0:33feccbba3ff | 1016 | |
tk_takateku | 0:33feccbba3ff | 1017 | // make hash |
tk_takateku | 0:33feccbba3ff | 1018 | mrb_value *hash = (mrb_value *)mrbc_alloc(vm, sizeof(mrb_value)*(arg_c*2+1)); |
tk_takateku | 0:33feccbba3ff | 1019 | if( hash == NULL ) return 0; // ENOMEM |
tk_takateku | 0:33feccbba3ff | 1020 | handle->value.obj = hash; |
tk_takateku | 0:33feccbba3ff | 1021 | |
tk_takateku | 0:33feccbba3ff | 1022 | hash[0].tt = MRB_TT_FIXNUM; |
tk_takateku | 0:33feccbba3ff | 1023 | hash[0].value.i = arg_c; |
tk_takateku | 0:33feccbba3ff | 1024 | |
tk_takateku | 0:33feccbba3ff | 1025 | mrb_value *src = ®s[arg_b]; |
tk_takateku | 0:33feccbba3ff | 1026 | mrb_value *dst = &hash[1]; |
tk_takateku | 0:33feccbba3ff | 1027 | while( arg_c > 0 ){ |
tk_takateku | 0:33feccbba3ff | 1028 | // copy key |
tk_takateku | 0:33feccbba3ff | 1029 | *dst++ = *src++; |
tk_takateku | 0:33feccbba3ff | 1030 | |
tk_takateku | 0:33feccbba3ff | 1031 | // copy value |
tk_takateku | 0:33feccbba3ff | 1032 | *dst++ = *src++; |
tk_takateku | 0:33feccbba3ff | 1033 | |
tk_takateku | 0:33feccbba3ff | 1034 | arg_c--; |
tk_takateku | 0:33feccbba3ff | 1035 | } |
tk_takateku | 0:33feccbba3ff | 1036 | |
tk_takateku | 0:33feccbba3ff | 1037 | regs[arg_a] = v; |
tk_takateku | 0:33feccbba3ff | 1038 | |
tk_takateku | 0:33feccbba3ff | 1039 | return 0; |
tk_takateku | 0:33feccbba3ff | 1040 | } |
tk_takateku | 0:33feccbba3ff | 1041 | |
tk_takateku | 0:33feccbba3ff | 1042 | |
tk_takateku | 0:33feccbba3ff | 1043 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1044 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1045 | Execute LAMBDA |
tk_takateku | 0:33feccbba3ff | 1046 | |
tk_takateku | 0:33feccbba3ff | 1047 | R(A) := lambda(SEQ[Bz],Cz) |
tk_takateku | 0:33feccbba3ff | 1048 | |
tk_takateku | 0:33feccbba3ff | 1049 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1050 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 1051 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 1052 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1053 | */ |
tk_takateku | 0:33feccbba3ff | 1054 | inline static int op_lambda( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 1055 | { |
tk_takateku | 0:33feccbba3ff | 1056 | // int c = GETARG_C(code); // TODO: Add flags support for OP_LAMBDA |
tk_takateku | 0:33feccbba3ff | 1057 | int b = GETARG_b(code); // sequence position in irep list |
tk_takateku | 0:33feccbba3ff | 1058 | mrb_proc *proc = mrbc_rproc_alloc(vm, "(lambda)"); |
tk_takateku | 0:33feccbba3ff | 1059 | mrb_irep *current = vm->irep; |
tk_takateku | 0:33feccbba3ff | 1060 | mrb_irep *p = current->next; //starting from next for current sequence; |
tk_takateku | 0:33feccbba3ff | 1061 | // code length is p->ilen * sizeof(uint32_t); |
tk_takateku | 0:33feccbba3ff | 1062 | int i; |
tk_takateku | 0:33feccbba3ff | 1063 | for (i=0; i < b; i++) { |
tk_takateku | 0:33feccbba3ff | 1064 | p = p->next; |
tk_takateku | 0:33feccbba3ff | 1065 | } |
tk_takateku | 0:33feccbba3ff | 1066 | proc->c_func = 0; |
tk_takateku | 0:33feccbba3ff | 1067 | proc->func.irep = p; |
tk_takateku | 0:33feccbba3ff | 1068 | int a = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 1069 | regs[a].tt = MRB_TT_PROC; |
tk_takateku | 0:33feccbba3ff | 1070 | regs[a].value.proc = proc; |
tk_takateku | 0:33feccbba3ff | 1071 | return 0; |
tk_takateku | 0:33feccbba3ff | 1072 | } |
tk_takateku | 0:33feccbba3ff | 1073 | |
tk_takateku | 0:33feccbba3ff | 1074 | |
tk_takateku | 0:33feccbba3ff | 1075 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1076 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1077 | Execute RANGE |
tk_takateku | 0:33feccbba3ff | 1078 | |
tk_takateku | 0:33feccbba3ff | 1079 | R(A) := R(A) := range_new(R(B),R(B+1),C) |
tk_takateku | 0:33feccbba3ff | 1080 | |
tk_takateku | 0:33feccbba3ff | 1081 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1082 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 1083 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 1084 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1085 | */ |
tk_takateku | 0:33feccbba3ff | 1086 | inline static int op_range( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 1087 | { |
tk_takateku | 0:33feccbba3ff | 1088 | int a = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 1089 | int b = GETARG_B(code); |
tk_takateku | 0:33feccbba3ff | 1090 | int c = GETARG_C(code); |
tk_takateku | 0:33feccbba3ff | 1091 | regs[a] = mrbc_range_new(vm, ®s[b], ®s[b+1], c); |
tk_takateku | 0:33feccbba3ff | 1092 | return 0; |
tk_takateku | 0:33feccbba3ff | 1093 | } |
tk_takateku | 0:33feccbba3ff | 1094 | |
tk_takateku | 0:33feccbba3ff | 1095 | |
tk_takateku | 0:33feccbba3ff | 1096 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1097 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1098 | Execute CLASS |
tk_takateku | 0:33feccbba3ff | 1099 | |
tk_takateku | 0:33feccbba3ff | 1100 | R(A) := newclass(R(A),Syms(B),R(A+1)) |
tk_takateku | 0:33feccbba3ff | 1101 | Syms(B): class name |
tk_takateku | 0:33feccbba3ff | 1102 | R(A+1): super class |
tk_takateku | 0:33feccbba3ff | 1103 | |
tk_takateku | 0:33feccbba3ff | 1104 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1105 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 1106 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 1107 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1108 | */ |
tk_takateku | 0:33feccbba3ff | 1109 | inline static int op_class( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 1110 | { |
tk_takateku | 0:33feccbba3ff | 1111 | |
tk_takateku | 0:33feccbba3ff | 1112 | |
tk_takateku | 0:33feccbba3ff | 1113 | return 0; |
tk_takateku | 0:33feccbba3ff | 1114 | } |
tk_takateku | 0:33feccbba3ff | 1115 | |
tk_takateku | 0:33feccbba3ff | 1116 | |
tk_takateku | 0:33feccbba3ff | 1117 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1118 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1119 | Execute METHOD |
tk_takateku | 0:33feccbba3ff | 1120 | |
tk_takateku | 0:33feccbba3ff | 1121 | R(A).newmethod(Syms(B),R(A+1)) |
tk_takateku | 0:33feccbba3ff | 1122 | |
tk_takateku | 0:33feccbba3ff | 1123 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1124 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 1125 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 1126 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1127 | */ |
tk_takateku | 0:33feccbba3ff | 1128 | inline static int op_method( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 1129 | { |
tk_takateku | 0:33feccbba3ff | 1130 | int a = GETARG_A(code); |
tk_takateku | 0:33feccbba3ff | 1131 | mrb_proc *rproc = regs[a+1].value.proc; |
tk_takateku | 0:33feccbba3ff | 1132 | |
tk_takateku | 0:33feccbba3ff | 1133 | if( regs[a].tt == MRB_TT_CLASS ) { |
tk_takateku | 0:33feccbba3ff | 1134 | mrb_class *cls = regs[a].value.cls; |
tk_takateku | 0:33feccbba3ff | 1135 | int b = GETARG_B(code); |
tk_takateku | 0:33feccbba3ff | 1136 | // sym_id : method name |
tk_takateku | 0:33feccbba3ff | 1137 | mrb_irep *cur_irep = vm->pc_irep; |
tk_takateku | 0:33feccbba3ff | 1138 | char *sym = find_irep_symbol(cur_irep->ptr_to_sym, b); |
tk_takateku | 0:33feccbba3ff | 1139 | int sym_id = add_sym( sym ); |
tk_takateku | 0:33feccbba3ff | 1140 | mrbc_define_method_proc(vm, cls, sym_id, rproc); |
tk_takateku | 0:33feccbba3ff | 1141 | } |
tk_takateku | 0:33feccbba3ff | 1142 | |
tk_takateku | 0:33feccbba3ff | 1143 | return 0; |
tk_takateku | 0:33feccbba3ff | 1144 | } |
tk_takateku | 0:33feccbba3ff | 1145 | |
tk_takateku | 0:33feccbba3ff | 1146 | |
tk_takateku | 0:33feccbba3ff | 1147 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1148 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1149 | Execute TCLASS |
tk_takateku | 0:33feccbba3ff | 1150 | |
tk_takateku | 0:33feccbba3ff | 1151 | R(A) := target_class |
tk_takateku | 0:33feccbba3ff | 1152 | |
tk_takateku | 0:33feccbba3ff | 1153 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1154 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 1155 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 1156 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1157 | */ |
tk_takateku | 0:33feccbba3ff | 1158 | inline static int op_tclass( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 1159 | { |
tk_takateku | 0:33feccbba3ff | 1160 | regs[GETARG_A(code)].tt = MRB_TT_CLASS; |
tk_takateku | 0:33feccbba3ff | 1161 | regs[GETARG_A(code)].value.cls = vm->target_class; |
tk_takateku | 0:33feccbba3ff | 1162 | |
tk_takateku | 0:33feccbba3ff | 1163 | return 0; |
tk_takateku | 0:33feccbba3ff | 1164 | } |
tk_takateku | 0:33feccbba3ff | 1165 | |
tk_takateku | 0:33feccbba3ff | 1166 | |
tk_takateku | 0:33feccbba3ff | 1167 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1168 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1169 | Execute STOP |
tk_takateku | 0:33feccbba3ff | 1170 | |
tk_takateku | 0:33feccbba3ff | 1171 | stop VM |
tk_takateku | 0:33feccbba3ff | 1172 | |
tk_takateku | 0:33feccbba3ff | 1173 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1174 | @param code bytecode |
tk_takateku | 0:33feccbba3ff | 1175 | @param regs vm->regs + vm->reg_top |
tk_takateku | 0:33feccbba3ff | 1176 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1177 | */ |
tk_takateku | 0:33feccbba3ff | 1178 | inline static int op_stop( mrb_vm *vm, uint32_t code, mrb_value *regs ) |
tk_takateku | 0:33feccbba3ff | 1179 | { |
tk_takateku | 0:33feccbba3ff | 1180 | vm->flag_preemption = 1; |
tk_takateku | 0:33feccbba3ff | 1181 | return -1; |
tk_takateku | 0:33feccbba3ff | 1182 | } |
tk_takateku | 0:33feccbba3ff | 1183 | |
tk_takateku | 0:33feccbba3ff | 1184 | |
tk_takateku | 0:33feccbba3ff | 1185 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1186 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1187 | Allocate new IREP |
tk_takateku | 0:33feccbba3ff | 1188 | |
tk_takateku | 0:33feccbba3ff | 1189 | @param vm Pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1190 | @return Pointer of new IREP. |
tk_takateku | 0:33feccbba3ff | 1191 | */ |
tk_takateku | 0:33feccbba3ff | 1192 | mrb_irep *new_irep(mrb_vm *vm) |
tk_takateku | 0:33feccbba3ff | 1193 | { |
tk_takateku | 0:33feccbba3ff | 1194 | mrb_irep *p = (mrb_irep *)mrbc_alloc(vm, sizeof(mrb_irep)); |
tk_takateku | 0:33feccbba3ff | 1195 | return p; |
tk_takateku | 0:33feccbba3ff | 1196 | } |
tk_takateku | 0:33feccbba3ff | 1197 | |
tk_takateku | 0:33feccbba3ff | 1198 | |
tk_takateku | 0:33feccbba3ff | 1199 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1200 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1201 | VM initializer. |
tk_takateku | 0:33feccbba3ff | 1202 | |
tk_takateku | 0:33feccbba3ff | 1203 | Get a VM from static heap. |
tk_takateku | 0:33feccbba3ff | 1204 | |
tk_takateku | 0:33feccbba3ff | 1205 | @return Pointer of struct VM in static area. |
tk_takateku | 0:33feccbba3ff | 1206 | |
tk_takateku | 0:33feccbba3ff | 1207 | @code |
tk_takateku | 0:33feccbba3ff | 1208 | init_static(); |
tk_takateku | 0:33feccbba3ff | 1209 | struct VM *vm = vm_open(); |
tk_takateku | 0:33feccbba3ff | 1210 | @endcode |
tk_takateku | 0:33feccbba3ff | 1211 | */ |
tk_takateku | 0:33feccbba3ff | 1212 | struct VM *vm_open(void) |
tk_takateku | 0:33feccbba3ff | 1213 | { |
tk_takateku | 0:33feccbba3ff | 1214 | int i; |
tk_takateku | 0:33feccbba3ff | 1215 | mrb_vm *p = 0; |
tk_takateku | 0:33feccbba3ff | 1216 | for( i=0 ; i<MAX_VM_COUNT ; i++ ){ |
tk_takateku | 0:33feccbba3ff | 1217 | if( mrbc_vm[i].priority < 0 ){ |
tk_takateku | 0:33feccbba3ff | 1218 | p = mrbc_vm + i; |
tk_takateku | 0:33feccbba3ff | 1219 | break; |
tk_takateku | 0:33feccbba3ff | 1220 | } |
tk_takateku | 0:33feccbba3ff | 1221 | } |
tk_takateku | 0:33feccbba3ff | 1222 | |
tk_takateku | 0:33feccbba3ff | 1223 | if( p != 0 ){ |
tk_takateku | 0:33feccbba3ff | 1224 | p->priority = 1; |
tk_takateku | 0:33feccbba3ff | 1225 | p->pc = 0; |
tk_takateku | 0:33feccbba3ff | 1226 | p->callinfo_top = 0; |
tk_takateku | 0:33feccbba3ff | 1227 | } |
tk_takateku | 0:33feccbba3ff | 1228 | |
tk_takateku | 0:33feccbba3ff | 1229 | return p; |
tk_takateku | 0:33feccbba3ff | 1230 | } |
tk_takateku | 0:33feccbba3ff | 1231 | |
tk_takateku | 0:33feccbba3ff | 1232 | |
tk_takateku | 0:33feccbba3ff | 1233 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1234 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1235 | VM finalizer. |
tk_takateku | 0:33feccbba3ff | 1236 | |
tk_takateku | 0:33feccbba3ff | 1237 | @param vm Pointer of VM |
tk_takateku | 0:33feccbba3ff | 1238 | */ |
tk_takateku | 0:33feccbba3ff | 1239 | void vm_close(struct VM *vm) |
tk_takateku | 0:33feccbba3ff | 1240 | { |
tk_takateku | 0:33feccbba3ff | 1241 | vm->priority = -1; |
tk_takateku | 0:33feccbba3ff | 1242 | mrbc_free_all(vm); |
tk_takateku | 0:33feccbba3ff | 1243 | |
tk_takateku | 0:33feccbba3ff | 1244 | } |
tk_takateku | 0:33feccbba3ff | 1245 | |
tk_takateku | 0:33feccbba3ff | 1246 | |
tk_takateku | 0:33feccbba3ff | 1247 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1248 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1249 | Boot the VM. |
tk_takateku | 0:33feccbba3ff | 1250 | |
tk_takateku | 0:33feccbba3ff | 1251 | @param vm Pointer of VM |
tk_takateku | 0:33feccbba3ff | 1252 | */ |
tk_takateku | 0:33feccbba3ff | 1253 | // init vm |
tk_takateku | 0:33feccbba3ff | 1254 | void vm_boot(struct VM *vm) |
tk_takateku | 0:33feccbba3ff | 1255 | { |
tk_takateku | 0:33feccbba3ff | 1256 | vm->pc_irep = vm->irep; |
tk_takateku | 0:33feccbba3ff | 1257 | vm->pc = 0; |
tk_takateku | 0:33feccbba3ff | 1258 | vm->reg_top = 0; |
tk_takateku | 0:33feccbba3ff | 1259 | // set self to reg[0] |
tk_takateku | 0:33feccbba3ff | 1260 | vm->top_self = mrbc_obj_alloc(vm, MRB_TT_OBJECT); |
tk_takateku | 0:33feccbba3ff | 1261 | vm->top_self->value.cls = mrbc_class_object; |
tk_takateku | 0:33feccbba3ff | 1262 | vm->regs[0].tt = MRB_TT_OBJECT; |
tk_takateku | 0:33feccbba3ff | 1263 | vm->regs[0].value.obj = vm->top_self; |
tk_takateku | 0:33feccbba3ff | 1264 | // target_class |
tk_takateku | 0:33feccbba3ff | 1265 | vm->target_class = vm->top_self->value.cls; |
tk_takateku | 0:33feccbba3ff | 1266 | vm->error_code = 0; |
tk_takateku | 0:33feccbba3ff | 1267 | vm->flag_preemption = 0; |
tk_takateku | 0:33feccbba3ff | 1268 | } |
tk_takateku | 0:33feccbba3ff | 1269 | |
tk_takateku | 0:33feccbba3ff | 1270 | |
tk_takateku | 0:33feccbba3ff | 1271 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1272 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1273 | Fetch a bytecode and execute |
tk_takateku | 0:33feccbba3ff | 1274 | |
tk_takateku | 0:33feccbba3ff | 1275 | @param vm A pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1276 | @retval 0 No error. |
tk_takateku | 0:33feccbba3ff | 1277 | */ |
tk_takateku | 0:33feccbba3ff | 1278 | int vm_run( mrb_vm *vm ) |
tk_takateku | 0:33feccbba3ff | 1279 | { |
tk_takateku | 0:33feccbba3ff | 1280 | int ret = 0; |
tk_takateku | 0:33feccbba3ff | 1281 | |
tk_takateku | 0:33feccbba3ff | 1282 | do { |
tk_takateku | 0:33feccbba3ff | 1283 | // get one bytecode |
tk_takateku | 0:33feccbba3ff | 1284 | uint32_t code = bin_to_uint32(vm->pc_irep->code + vm->pc * 4); |
tk_takateku | 0:33feccbba3ff | 1285 | vm->pc++; |
tk_takateku | 0:33feccbba3ff | 1286 | |
tk_takateku | 0:33feccbba3ff | 1287 | // regs |
tk_takateku | 0:33feccbba3ff | 1288 | mrb_value *regs = vm->regs + vm->reg_top; |
tk_takateku | 0:33feccbba3ff | 1289 | |
tk_takateku | 0:33feccbba3ff | 1290 | // Dispatch |
tk_takateku | 0:33feccbba3ff | 1291 | enum OPCODE opcode = GET_OPCODE(code); |
tk_takateku | 0:33feccbba3ff | 1292 | switch( opcode ) { |
tk_takateku | 0:33feccbba3ff | 1293 | case OP_NOP: ret = op_nop (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1294 | case OP_MOVE: ret = op_move (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1295 | case OP_LOADL: ret = op_loadl (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1296 | case OP_LOADI: ret = op_loadi (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1297 | case OP_LOADSYM: ret = op_loadsym (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1298 | case OP_LOADNIL: ret = op_loadnil (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1299 | case OP_LOADSELF: ret = op_loadself (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1300 | case OP_LOADT: ret = op_loadt (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1301 | case OP_LOADF: ret = op_loadf (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1302 | case OP_GETGLOBAL: ret = op_getglobal (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1303 | case OP_SETGLOBAL: ret = op_setglobal (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1304 | case OP_GETCONST: ret = op_getconst (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1305 | case OP_SETCONST: ret = op_setconst (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1306 | case OP_JMP: ret = op_jmp (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1307 | case OP_JMPIF: ret = op_jmpif (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1308 | case OP_JMPNOT: ret = op_jmpnot (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1309 | case OP_SEND: ret = op_send (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1310 | case OP_ENTER: ret = op_enter (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1311 | case OP_RETURN: ret = op_return (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1312 | case OP_ADD: ret = op_add (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1313 | case OP_ADDI: ret = op_addi (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1314 | case OP_SUB: ret = op_sub (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1315 | case OP_SUBI: ret = op_subi (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1316 | case OP_MUL: ret = op_mul (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1317 | case OP_DIV: ret = op_div (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1318 | case OP_EQ: ret = op_eq (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1319 | case OP_LT: ret = op_lt (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1320 | case OP_LE: ret = op_le (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1321 | case OP_GT: ret = op_gt (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1322 | case OP_GE: ret = op_ge (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1323 | case OP_ARRAY: ret = op_array (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1324 | case OP_STRING: ret = op_string (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1325 | case OP_HASH: ret = op_hash (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1326 | case OP_LAMBDA: ret = op_lambda (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1327 | case OP_RANGE: ret = op_range (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1328 | case OP_CLASS: ret = op_class (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1329 | case OP_METHOD: ret = op_method (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1330 | case OP_TCLASS: ret = op_tclass (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1331 | case OP_STOP: ret = op_stop (vm, code, regs); break; |
tk_takateku | 0:33feccbba3ff | 1332 | default: |
tk_takateku | 0:33feccbba3ff | 1333 | console_printf("Skip OP=%02x\n", GET_OPCODE(code)); |
tk_takateku | 0:33feccbba3ff | 1334 | break; |
tk_takateku | 0:33feccbba3ff | 1335 | } |
tk_takateku | 0:33feccbba3ff | 1336 | } while( !vm->flag_preemption ); |
tk_takateku | 0:33feccbba3ff | 1337 | |
tk_takateku | 0:33feccbba3ff | 1338 | return ret; |
tk_takateku | 0:33feccbba3ff | 1339 | } |
tk_takateku | 0:33feccbba3ff | 1340 | |
tk_takateku | 0:33feccbba3ff | 1341 | |
tk_takateku | 0:33feccbba3ff | 1342 | #ifdef MRBC_DEBUG |
tk_takateku | 0:33feccbba3ff | 1343 | |
tk_takateku | 0:33feccbba3ff | 1344 | //================================================================ |
tk_takateku | 0:33feccbba3ff | 1345 | /*!@brief |
tk_takateku | 0:33feccbba3ff | 1346 | |
tk_takateku | 0:33feccbba3ff | 1347 | @param vm Pointer of VM. |
tk_takateku | 0:33feccbba3ff | 1348 | @param irep |
tk_takateku | 0:33feccbba3ff | 1349 | @return |
tk_takateku | 0:33feccbba3ff | 1350 | */ |
tk_takateku | 0:33feccbba3ff | 1351 | void debug_irep(mrb_vm *vm, mrb_irep *irep) |
tk_takateku | 0:33feccbba3ff | 1352 | { |
tk_takateku | 0:33feccbba3ff | 1353 | if( irep->unused == 1 ) { |
tk_takateku | 0:33feccbba3ff | 1354 | console_printf(" not used.\n"); |
tk_takateku | 0:33feccbba3ff | 1355 | return; |
tk_takateku | 0:33feccbba3ff | 1356 | } |
tk_takateku | 0:33feccbba3ff | 1357 | console_printf(" code:0x%x\n", (int)((char *)irep->code - (char *)vm->mrb)); |
tk_takateku | 0:33feccbba3ff | 1358 | console_printf(" regs:%d\n", irep->nregs); |
tk_takateku | 0:33feccbba3ff | 1359 | console_printf(" locals:%d\n", irep->nlocals); |
tk_takateku | 0:33feccbba3ff | 1360 | } |
tk_takateku | 0:33feccbba3ff | 1361 | #endif |
tk_takateku | 0:33feccbba3ff | 1362 |