| 188 | | SMOP__Object* value = SMOP__NATIVE__capture_positional(interpreter, capture, 0); |
| 189 | | if (!value) { |
| 190 | | printf("got null as a result of a call (reg = %d, pos = %d) via setr\n",frame->target, frame->position); |
| 191 | | abort(); |
| 192 | | } |
| 193 | | |
| 194 | | if (!frame->target) fprintf(stderr,"calling setr on a frame not expecting a return value\n"); |
| 195 | | if (frame->registers[frame->target]) { |
| 196 | | SMOP_RELEASE(interpreter,frame->registers[frame->target]); |
| 197 | | } |
| 198 | | frame->registers[frame->target] = value; |
| | 195 | SMOP__Object* value = SMOP__NATIVE__capture_positional(interpreter, capture, 0); |
| | 196 | if (!value) { |
| | 197 | printf("got null as a result of a call (reg = %d, pos = %d) via setr\n",frame->target, frame->position); |
| | 198 | abort(); |
| | 199 | } |
| | 200 | |
| | 201 | if (!frame->target) fprintf(stderr,"calling setr on a frame not expecting a return value\n"); |
| | 202 | if (frame->registers[frame->target]) { |
| | 203 | SMOP_RELEASE(interpreter,frame->registers[frame->target]); |
| | 204 | } |
| | 205 | frame->registers[frame->target] = value; |
| 206 | | case 1: ; /*call*/ |
| 207 | | |
| 208 | | int target = mold->opcodes[frame->position++]; |
| 209 | | |
| 210 | | SMOP__Object* call_invocant = get_register(interpreter,frame); |
| 211 | | |
| 212 | | SMOP__Object* call_identifier = get_register(interpreter,frame); |
| 213 | | |
| 214 | | int pos_n = mold->opcodes[frame->position++]; |
| 215 | | SMOP__Object** call_pos = (SMOP__Object**) malloc((pos_n+1) * sizeof(SMOP__Object*)); |
| 216 | | for (i=0;i<pos_n;i++) { |
| 217 | | call_pos[i] = get_register(interpreter,frame); |
| | 213 | case 1: { /*call*/ |
| | 214 | |
| | 215 | int target = mold->opcodes[frame->position++]; |
| | 216 | |
| | 217 | SMOP__Object* call_invocant = get_register(interpreter,frame); |
| | 218 | |
| | 219 | SMOP__Object* call_identifier = get_register(interpreter,frame); |
| | 220 | |
| | 221 | int pos_n = mold->opcodes[frame->position++]; |
| | 222 | SMOP__Object** call_pos = (SMOP__Object**) malloc((pos_n+1) * sizeof(SMOP__Object*)); |
| | 223 | for (i=0;i<pos_n;i++) { |
| | 224 | call_pos[i] = get_register(interpreter,frame); |
| | 225 | } |
| | 226 | call_pos[pos_n] = NULL; |
| | 227 | |
| | 228 | int named_n = mold->opcodes[frame->position++]; |
| | 229 | SMOP__Object** call_named = (SMOP__Object**) malloc((named_n+1) * sizeof(SMOP__Object*)); |
| | 230 | for (i=0;i<named_n;i++) { |
| | 231 | call_named[i] = get_register(interpreter,frame); |
| | 232 | } |
| | 233 | call_named[named_n] = NULL; |
| | 234 | SMOP__Object* capture = SMOP__NATIVE__capture_create(interpreter,call_invocant,call_pos,call_named); |
| | 235 | free(call_named); |
| | 236 | free(call_pos); |
| | 237 | |
| | 238 | SMOP__Object* ret = SMOP_DISPATCH(interpreter,SMOP_RI(call_invocant),call_identifier,capture); |
| | 239 | if (!ret) { |
| | 240 | print_regs_content(frame); |
| | 241 | int identifier_size; |
| | 242 | char *s; |
| | 243 | if (SMOP_RI(call_identifier) == SMOP_RI(SMOP__ID__new)) { |
| | 244 | s = SMOP__NATIVE__idconst_fetch(call_identifier,&identifier_size); |
| | 245 | } else { |
| | 246 | s = "non-constant-identifier"; |
| | 247 | identifier_size = strlen(s); |
| 219 | | |
| 220 | | call_pos[pos_n] = NULL; |
| 221 | | |
| 222 | | int named_n = mold->opcodes[frame->position++]; |
| 223 | | SMOP__Object** call_named = (SMOP__Object**) malloc((named_n+1) * sizeof(SMOP__Object*)); |
| 224 | | for (i=0;i<named_n;i++) { |
| 225 | | call_named[i] = get_register(interpreter,frame); |
| 226 | | } |
| 227 | | call_named[named_n] = NULL; |
| 228 | | SMOP__Object* capture = SMOP__NATIVE__capture_create(interpreter,call_invocant,call_pos,call_named); |
| 229 | | free(call_named); |
| 230 | | free(call_pos); |
| 231 | | SMOP__Object* ret = SMOP_DISPATCH(interpreter,SMOP_RI(call_invocant),call_identifier,capture); |
| 232 | | if (frame->registers[target]) { |
| 233 | | SMOP_RELEASE(interpreter,frame->registers[target]); |
| 234 | | } |
| 235 | | if (!ret) { |
| 236 | | print_regs_content(frame); |
| 237 | | int identifier_size; |
| 238 | | char *s; |
| 239 | | if (SMOP_RI(call_identifier) == SMOP_RI(SMOP__ID__new)) { |
| 240 | | s = SMOP__NATIVE__idconst_fetch(call_identifier,&identifier_size); |
| 241 | | } else { |
| 242 | | s = "non-constant-identifier"; |
| 243 | | identifier_size = strlen(s); |
| 244 | | } |
| 245 | | printf("got NULL as a result of a call (reg = %d, pos=%d, identifier=\"%.*s\")\n", |
| 246 | | frame->target, frame->position, identifier_size, s); |
| 247 | | abort(); |
| 248 | | } |
| 249 | | frame->registers[target] = ret; |
| 250 | | frame->target = target; |
| 251 | | break; |
| 252 | | case 2: /*call2*/ |
| 253 | | { |
| 254 | | int target = mold->opcodes[frame->position++]; |
| 255 | | SMOP__Object* call_responder = get_register(interpreter,frame); |
| 256 | | SMOP__Object* call_identifier = get_register(interpreter,frame); |
| 257 | | SMOP__Object* call_capture = get_register(interpreter,frame); |
| 258 | | |
| 259 | | SMOP__Object* ret = SMOP_DISPATCH(interpreter,SMOP_RI(call_responder),call_identifier,call_capture); |
| 260 | | SMOP_RELEASE(interpreter,call_responder); |
| 261 | | if (frame->registers[target]) { |
| 262 | | SMOP_RELEASE(interpreter,frame->registers[target]); |
| 263 | | } |
| 264 | | frame->registers[target] = ret; |
| 265 | | frame->target = target; |
| 266 | | break; |
| 267 | | } |
| 268 | | case 3: /*goto*/ |
| 269 | | ; |
| 270 | | int where = mold->opcodes[frame->position]; |
| 271 | | frame->position = where; |
| 272 | | break; |
| 273 | | case 4: /*br*/ |
| 274 | | ; |
| 275 | | SMOP__Object* condition = get_register(interpreter,frame); |
| 276 | | int iftrue = mold->opcodes[frame->position++]; |
| 277 | | int iffalse = mold->opcodes[frame->position++]; |
| 278 | | if (SMOP__NATIVE__bool_true == condition ) { |
| 279 | | frame->position = iftrue; |
| 280 | | } else if (SMOP__NATIVE__bool_false == condition) { |
| 281 | | frame->position = iffalse; |
| 282 | | } else { |
| 283 | | fprintf(stderr,"the condition argument to the br op must be a native bool\n"); |
| 284 | | abort(); |
| 285 | | } |
| 286 | | break; |
| 287 | | default: |
| 288 | | fprintf(stderr,"unknown op %d\n",op); |
| 289 | | } |
| 290 | | |
| | 249 | printf("got NULL as a result of a call (reg = %d, pos=%d, identifier=\"%.*s\")\n", |
| | 250 | frame->target, frame->position, identifier_size, s); |
| | 251 | abort(); |
| | 252 | } |
| | 253 | |
| | 254 | if (frame->registers[target]) { |
| | 255 | SMOP_RELEASE(interpreter,frame->registers[target]); |
| | 256 | } |
| | 257 | frame->registers[target] = ret; |
| | 258 | frame->target = target; |
| | 259 | |
| | 260 | break; |
| | 261 | } |
| | 262 | case 2: {/*call2*/ |
| | 263 | int target = mold->opcodes[frame->position++]; |
| | 264 | SMOP__Object* call_responder = get_register(interpreter,frame); |
| | 265 | SMOP__Object* call_identifier = get_register(interpreter,frame); |
| | 266 | SMOP__Object* call_capture = get_register(interpreter,frame); |
| | 267 | |
| | 268 | SMOP__Object* ret = SMOP_DISPATCH(interpreter,SMOP_RI(call_responder),call_identifier,call_capture); |
| | 269 | SMOP_RELEASE(interpreter,call_responder); |
| | 270 | if (frame->registers[target]) { |
| | 271 | SMOP_RELEASE(interpreter,frame->registers[target]); |
| | 272 | } |
| | 273 | frame->registers[target] = ret; |
| | 274 | frame->target = target; |
| | 275 | break; |
| | 276 | } |
| | 277 | case 3: { /*goto*/ |
| | 278 | int where = mold->opcodes[frame->position]; |
| | 279 | frame->position = where; |
| | 280 | break; |
| | 281 | } |
| | 282 | |
| | 283 | case 4: {/*br*/ |
| | 284 | SMOP__Object* condition = get_register(interpreter,frame); |
| | 285 | int iftrue = mold->opcodes[frame->position++]; |
| | 286 | int iffalse = mold->opcodes[frame->position++]; |
| | 287 | if (SMOP__NATIVE__bool_true == condition ) { |
| | 288 | frame->position = iftrue; |
| | 289 | } else if (SMOP__NATIVE__bool_false == condition) { |
| | 290 | frame->position = iffalse; |
| | 291 | } else { |
| | 292 | fprintf(stderr,"the condition argument to the br op must be a native bool\n"); |
| | 293 | abort(); |
| | 294 | } |
| | 295 | break; |
| | 296 | } |
| | 297 | default: fprintf(stderr,"unknown op %d\n",op); |
| | 298 | } |