This is a port of the mruby/c tutorial Chapter 03 to the mbed environment.

Dependencies:   mbed

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.

Committer:
tk_takateku
Date:
Wed Feb 15 01:03:35 2017 +0000
Revision:
0:33feccbba3ff
Commit before publishing

Who changed what in which revision?

UserRevisionLine numberNew 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, &regs[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, &regs[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(&regs[rr], &regs[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 = &regs[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, &regs[b], &regs[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