*** empty log message ***
[chuck-blob.git] / v2 / chuck_instr.cpp
blobeb33101d57e9ed8ad9eaf85b1efc04fc77745848
1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: chuck_instr.cpp
27 // desc: ...
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 // date: Autumn 2002
32 //-----------------------------------------------------------------------------
33 #include <math.h>
34 #include <limits.h>
36 #include "chuck_type.h"
37 #include "chuck_lang.h"
38 #include "chuck_instr.h"
39 #include "chuck_vm.h"
40 #include "chuck_ugen.h"
41 #include "chuck_bbq.h"
42 #include "chuck_dl.h"
43 #include "chuck_errmsg.h"
44 #include "chuck_globals.h"
46 #include "util_string.h"
48 #include <typeinfo>
49 using namespace std;
54 //-----------------------------------------------------------------------------
55 // name: name()
56 // desc: ...
57 //-----------------------------------------------------------------------------
58 const char * Chuck_Instr::name() const
60 return mini_type( typeid(*this).name() );
66 //-----------------------------------------------------------------------------
67 // name: handle_overflow()
68 // desc: stack overflow
69 //-----------------------------------------------------------------------------
70 static void handle_overflow( Chuck_VM_Shred * shred, Chuck_VM * vm )
72 // we have a problem
73 fprintf( stderr,
74 "[chuck](VM): Exception StackOverflow in shred[id=%d:%s], PC=[%d]\n",
75 shred->xid, shred->name.c_str(), shred->pc );
76 // do something!
77 shred->is_running = FALSE;
78 shred->is_done = TRUE;
84 //-----------------------------------------------------------------------------
85 // name: execute()
86 // desc: ...
87 //-----------------------------------------------------------------------------
88 void Chuck_Instr_Add_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
90 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
91 pop_( sp, 2 );
92 push_( sp, val_(sp) + val_(sp+1) );
98 //-----------------------------------------------------------------------------
99 // name: execute()
100 // desc: ...
101 //-----------------------------------------------------------------------------
102 void Chuck_Instr_PreInc_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
104 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
105 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
106 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
108 // pointer
109 pop_( reg_sp, 1 );
110 // increment value
111 (**(reg_sp))++;
112 // value on stack
113 push_( the_sp, **(reg_sp) );
119 //-----------------------------------------------------------------------------
120 // name: execute()
121 // desc: ...
122 //-----------------------------------------------------------------------------
123 void Chuck_Instr_PostInc_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
125 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
126 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
127 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
128 t_CKINT * ptr;
130 // pointer
131 pop_( reg_sp, 1 );
132 // copy
133 ptr = *reg_sp;
134 // value on stack
135 push_( the_sp, **(reg_sp) );
136 // increment value
137 (*(ptr))++;
143 //-----------------------------------------------------------------------------
144 // name: execute()
145 // desc: ...
146 //-----------------------------------------------------------------------------
147 void Chuck_Instr_PreDec_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
149 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
150 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
151 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
153 // pointer
154 pop_( reg_sp, 1 );
155 // decrement value
156 (**(reg_sp))--;
157 // value on stack
158 push_( the_sp, **(reg_sp) );
164 //-----------------------------------------------------------------------------
165 // name: execute()
166 // desc: ...
167 //-----------------------------------------------------------------------------
168 void Chuck_Instr_PostDec_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
170 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
171 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
172 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
173 t_CKINT * ptr;
175 // pointer
176 pop_( reg_sp, 1 );
177 // copy
178 ptr = *reg_sp;
179 // value on stack
180 push_( the_sp, **(reg_sp) );
181 // decrement value
182 (*(ptr))--;
188 //-----------------------------------------------------------------------------
189 // name: class Chuck_Instr_Dec_int_Addr
190 // desc: ...
191 //-----------------------------------------------------------------------------
192 void Chuck_Instr_Dec_int_Addr::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
194 // decrement value
195 (*((t_CKINT *)(m_val)))--;
201 //-----------------------------------------------------------------------------
202 // name: exexute()
203 // desc: ...
204 //-----------------------------------------------------------------------------
205 void Chuck_Instr_Complement_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
207 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
208 (*(sp-1)) = ~(*(sp-1));
214 //-----------------------------------------------------------------------------
215 // name: execute()
216 // desc: ...
217 //-----------------------------------------------------------------------------
218 void Chuck_Instr_Mod_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
220 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
221 pop_( sp, 2 );
222 push_( sp, val_(sp) % val_(sp+1) );
228 //-----------------------------------------------------------------------------
229 // name: execute()
230 // desc: ...
231 //-----------------------------------------------------------------------------
232 void Chuck_Instr_Mod_int_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
234 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
235 pop_( sp, 2 );
236 push_( sp, val_(sp+1) % val_(sp) );
242 //-----------------------------------------------------------------------------
243 // name: execute()
244 // desc: ...
245 //-----------------------------------------------------------------------------
246 void Chuck_Instr_Minus_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
248 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
249 pop_( sp, 2 );
250 push_( sp, val_(sp) - val_(sp+1) );
256 //-----------------------------------------------------------------------------
257 // name: execute()
258 // desc: ...
259 //-----------------------------------------------------------------------------
260 void Chuck_Instr_Minus_int_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
262 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
263 pop_( sp, 2 );
264 push_( sp, val_(sp+1) - val_(sp) );
270 //-----------------------------------------------------------------------------
271 // name: execute()
272 // desc: ...
273 //-----------------------------------------------------------------------------
274 void Chuck_Instr_Times_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
276 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
277 pop_( sp, 2 );
278 push_( sp, val_(sp) * val_(sp+1) );
284 //-----------------------------------------------------------------------------
285 // name: execute()
286 // desc: ...
287 //-----------------------------------------------------------------------------
288 void Chuck_Instr_Divide_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
290 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
291 pop_( sp, 2 );
292 push_( sp, val_(sp) / val_(sp+1) );
298 //-----------------------------------------------------------------------------
299 // name: execute()
300 // desc: ...
301 //-----------------------------------------------------------------------------
302 void Chuck_Instr_Divide_int_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
304 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
305 pop_( sp, 2 );
306 push_( sp, val_(sp+1) / val_(sp) );
312 //-----------------------------------------------------------------------------
313 // name: execute()
314 // desc: ...
315 //-----------------------------------------------------------------------------
316 void Chuck_Instr_Add_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
318 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
319 pop_( sp, 2 );
320 push_( sp, val_(sp) + val_(sp+1) );
326 //-----------------------------------------------------------------------------
327 // name: execute()
328 // desc: ...
329 //-----------------------------------------------------------------------------
330 void Chuck_Instr_Minus_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
332 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
333 pop_( sp, 2 );
334 push_( sp, val_(sp) - val_(sp+1) );
340 //-----------------------------------------------------------------------------
341 // name: execute()
342 // desc: ...
343 //-----------------------------------------------------------------------------
344 void Chuck_Instr_Minus_double_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
346 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
347 pop_( sp, 2 );
348 push_( sp, val_(sp+1) - val_(sp) );
354 //-----------------------------------------------------------------------------
355 // name: execute()
356 // desc: ...
357 //-----------------------------------------------------------------------------
358 void Chuck_Instr_Times_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
360 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
361 pop_( sp, 2 );
362 push_( sp, val_(sp) * val_(sp+1) );
368 //-----------------------------------------------------------------------------
369 // name: execute()
370 // desc: ...
371 //-----------------------------------------------------------------------------
372 void Chuck_Instr_Divide_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
374 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
375 pop_( sp, 2 );
376 push_( sp, val_(sp) / val_(sp+1) );
383 //-----------------------------------------------------------------------------
384 // name: execute()
385 // desc: ...
386 //-----------------------------------------------------------------------------
387 void Chuck_Instr_Divide_double_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
389 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
390 pop_( sp, 2 );
391 push_( sp, val_(sp+1) / val_(sp) );
397 //-----------------------------------------------------------------------------
398 // name: execute()
399 // desc: ...
400 //-----------------------------------------------------------------------------
401 void Chuck_Instr_Mod_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
403 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
404 pop_( sp, 2 );
405 push_( sp, ::fmod( val_(sp), val_(sp+1) ) );
411 //-----------------------------------------------------------------------------
412 // name: execute()
413 // desc: ...
414 //-----------------------------------------------------------------------------
415 void Chuck_Instr_Mod_double_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
417 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
418 pop_( sp, 2 );
419 push_( sp, ::fmod( val_(sp+1), val_(sp) ) );
425 //-----------------------------------------------------------------------------
426 // name: execute()
427 // desc: ...
428 //-----------------------------------------------------------------------------
429 void Chuck_Instr_Add_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
431 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
432 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
433 t_CKFLOAT re, im;
434 pop_( sp, 2 );
435 re = sp->re + (sp+1)->re;
436 im = sp->im + (sp+1)->im;
437 push_( sp_float, re );
438 push_( sp_float, im );
444 //-----------------------------------------------------------------------------
445 // name: execute()
446 // desc: ...
447 //-----------------------------------------------------------------------------
448 void Chuck_Instr_Minus_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
450 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
451 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
452 t_CKFLOAT re, im;
453 pop_( sp, 2 );
454 re = sp->re - (sp+1)->re;
455 im = sp->im - (sp+1)->im;
456 push_( sp_float, re );
457 push_( sp_float, im );
463 //-----------------------------------------------------------------------------
464 // name: execute()
465 // desc: ...
466 //-----------------------------------------------------------------------------
467 void Chuck_Instr_Minus_complex_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
469 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
470 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
471 t_CKFLOAT re, im;
472 pop_( sp, 2 );
473 re = (sp+1)->re - sp->re;
474 im = (sp+1)->im - sp->im;
475 push_( sp_float, re );
476 push_( sp_float, im );
482 //-----------------------------------------------------------------------------
483 // name: execute()
484 // desc: ...
485 //-----------------------------------------------------------------------------
486 void Chuck_Instr_Times_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
488 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
489 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
490 t_CKFLOAT re, im;
491 pop_( sp, 2 );
492 re = sp->re * (sp+1)->re - sp->im * (sp+1)->im;
493 im = sp->re * (sp+1)->im + sp->im * (sp+1)->re;
494 push_( sp_float, re );
495 push_( sp_float, im );
501 //-----------------------------------------------------------------------------
502 // name: execute()
503 // desc: ...
504 //-----------------------------------------------------------------------------
505 void Chuck_Instr_Divide_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
507 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
508 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
509 t_CKFLOAT re, im, denom;
511 // pop
512 pop_( sp, 2 );
513 // complex division -> * complex conjugate of divisor
514 denom = (sp+1)->re*(sp+1)->re + (sp+1)->im*(sp+1)->im;
515 // go
516 re = sp->re*(sp+1)->re + sp->im*(sp+1)->im;
517 im = sp->im*(sp+1)->re - sp->re*(sp+1)->im;
518 // result
519 push_( sp_float, re/denom );
520 push_( sp_float, im/denom );
527 //-----------------------------------------------------------------------------
528 // name: execute()
529 // desc: ...
530 //-----------------------------------------------------------------------------
531 void Chuck_Instr_Divide_complex_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
533 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
534 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
535 t_CKFLOAT re, im, denom;
537 // pop
538 pop_( sp, 2 );
539 // complex division -> * complex conjugate of divisor
540 denom = sp->re*sp->re + sp->im*sp->im;
541 // go
542 re = sp->re*(sp+1)->re + sp->im*(sp+1)->im;
543 im = (sp+1)->im*sp->re - (sp+1)->re*sp->im;
544 // result
545 push_( sp_float, re/denom );
546 push_( sp_float, im/denom );
552 //-----------------------------------------------------------------------------
553 // name: execute()
554 // desc: ...
555 //-----------------------------------------------------------------------------
556 void Chuck_Instr_Add_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
558 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
559 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
560 t_CKCOMPLEX a, b;
561 pop_( sp, 2 );
562 a.re = sp->modulus * ::cos( sp->phase );
563 a.im = sp->modulus * ::sin( sp->phase );
564 b.re = (sp+1)->modulus * ::cos( (sp+1)->phase );
565 b.im = (sp+1)->modulus * ::sin( (sp+1)->phase );
566 a.re += b.re;
567 a.im += b.im;
568 push_( sp_float, ::hypot( a.re, a.im ) );
569 push_( sp_float, ::atan2( a.im, a.re ) );
575 //-----------------------------------------------------------------------------
576 // name: execute()
577 // desc: ...
578 //-----------------------------------------------------------------------------
579 void Chuck_Instr_Minus_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
581 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
582 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
583 t_CKCOMPLEX a, b;
584 pop_( sp, 2 );
585 a.re = sp->modulus * ::cos( sp->phase );
586 a.im = sp->modulus * ::sin( sp->phase );
587 b.re = (sp+1)->modulus * ::cos( (sp+1)->phase );
588 b.im = (sp+1)->modulus * ::sin( (sp+1)->phase );
589 a.re -= b.re;
590 a.im -= b.im;
591 push_( sp_float, ::hypot( a.re, a.im ) );
592 push_( sp_float, ::atan2( a.im, a.re ) );
598 //-----------------------------------------------------------------------------
599 // name: execute()
600 // desc: ...
601 //-----------------------------------------------------------------------------
602 void Chuck_Instr_Minus_polar_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
604 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
605 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
606 t_CKCOMPLEX a, b;
607 pop_( sp, 2 );
608 a.re = sp->modulus * ::cos( sp->phase );
609 a.im = sp->modulus * ::sin( sp->phase );
610 b.re = (sp+1)->modulus * ::cos( (sp+1)->phase );
611 b.im = (sp+1)->modulus * ::sin( (sp+1)->phase );
612 a.re = b.re - a.re;
613 a.im = b.im - a.im;
614 push_( sp_float, ::hypot( a.re, a.im ) );
615 push_( sp_float, ::atan2( a.im, a.re ) );
621 //-----------------------------------------------------------------------------
622 // name: execute()
623 // desc: ...
624 //-----------------------------------------------------------------------------
625 void Chuck_Instr_Times_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
627 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
628 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
629 t_CKFLOAT mag, phase;
630 pop_( sp, 2 );
631 mag = sp->modulus * (sp+1)->modulus;
632 phase = sp->phase + (sp+1)->phase;
633 push_( sp_float, mag );
634 push_( sp_float, phase );
640 //-----------------------------------------------------------------------------
641 // name: execute()
642 // desc: ...
643 //-----------------------------------------------------------------------------
644 void Chuck_Instr_Divide_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
646 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
647 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
648 t_CKFLOAT mag, phase;
649 pop_( sp, 2 );
650 mag = sp->modulus / (sp+1)->modulus;
651 phase = sp->phase - (sp+1)->phase;
652 push_( sp_float, mag );
653 push_( sp_float, phase );
660 //-----------------------------------------------------------------------------
661 // name: execute()
662 // desc: ...
663 //-----------------------------------------------------------------------------
664 void Chuck_Instr_Divide_polar_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
666 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
667 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
668 t_CKFLOAT mag, phase;
669 pop_( sp, 2 );
670 mag = (sp+1)->modulus / (sp)->modulus;
671 phase = (sp+1)->phase - sp->phase;
672 push_( sp_float, mag );
673 push_( sp_float, phase );
679 //-----------------------------------------------------------------------------
680 // name: execute()
681 // desc: ...
682 //-----------------------------------------------------------------------------
683 void Chuck_Instr_Add_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
685 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
686 pop_( sp, 2 );
687 temp = **(t_CKINT **)(sp+1) += val_(sp);
688 push_( sp, temp );
694 //-----------------------------------------------------------------------------
695 // name: execute()
696 // desc: ...
697 //-----------------------------------------------------------------------------
698 void Chuck_Instr_Mod_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
700 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
701 pop_( sp, 2 );
702 temp = **(t_CKINT **)(sp+1) %= val_(sp);
703 push_( sp, temp );
709 //-----------------------------------------------------------------------------
710 // name: execute()
711 // desc: ...
712 //-----------------------------------------------------------------------------
713 void Chuck_Instr_Minus_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
715 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
716 pop_( sp, 2 );
717 temp = **(t_CKINT **)(sp+1) -= val_(sp);
718 push_( sp, temp );
724 //-----------------------------------------------------------------------------
725 // name: execute()
726 // desc: ...
727 //-----------------------------------------------------------------------------
728 void Chuck_Instr_Times_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
730 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
731 pop_( sp, 2 );
732 temp = **(t_CKINT **)(sp+1) *= val_(sp);
733 push_( sp, temp );
739 //-----------------------------------------------------------------------------
740 // name: execute()
741 // desc: ...
742 //-----------------------------------------------------------------------------
743 void Chuck_Instr_Divide_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
745 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
746 pop_( sp, 2 );
747 temp = **(t_CKINT **)(sp+1) /= val_(sp);
748 push_( sp, temp );
753 //-----------------------------------------------------------------------------
754 // name: execute()
755 // desc: ...
756 //-----------------------------------------------------------------------------
757 void Chuck_Instr_Add_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
759 t_CKFLOAT temp;
760 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
761 // pop value + pointer
762 pop_( sp, sz_FLOAT + sz_UINT );
763 // assign
764 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) += val_((t_CKFLOAT *&)sp);
765 // push result
766 push_( (t_CKFLOAT *&)sp, temp );
772 //-----------------------------------------------------------------------------
773 // name: execute()
774 // desc: ...
775 //-----------------------------------------------------------------------------
776 void Chuck_Instr_Minus_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
778 t_CKFLOAT temp;
779 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
780 // pop value + pointer
781 pop_( sp, sz_FLOAT + sz_UINT );
782 // assign
783 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) -= val_((t_CKFLOAT *&)sp);
784 // push result
785 push_( (t_CKFLOAT *&)sp, temp );
791 //-----------------------------------------------------------------------------
792 // name: execute()
793 // desc: ...
794 //-----------------------------------------------------------------------------
795 void Chuck_Instr_Times_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
797 t_CKFLOAT temp;
798 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
799 // pop value + pointer
800 pop_( sp, sz_FLOAT + sz_UINT );
801 // assign
802 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) *= val_((t_CKFLOAT *&)sp);
803 // push result
804 push_( (t_CKFLOAT *&)sp, temp );
810 //-----------------------------------------------------------------------------
811 // name: execute()
812 // desc: ...
813 //-----------------------------------------------------------------------------
814 void Chuck_Instr_Divide_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
816 t_CKFLOAT temp;
817 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
818 // pop value + pointer
819 pop_( sp, sz_FLOAT + sz_UINT );
820 // assign
821 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) /= val_((t_CKFLOAT *&)sp);
822 // push result
823 push_( (t_CKFLOAT *&)sp, temp );
829 //-----------------------------------------------------------------------------
830 // name: execute()
831 // desc: ...
832 //-----------------------------------------------------------------------------
833 void Chuck_Instr_Mod_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
835 t_CKFLOAT temp;
836 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
837 // pop value + pointer
838 pop_( sp, sz_FLOAT + sz_UINT );
839 // assign
840 temp = ::fmod( **(t_CKFLOAT **)(sp+sz_FLOAT), val_((t_CKFLOAT *&)sp) );
841 **(t_CKFLOAT **)(sp+sz_FLOAT) = temp;
842 // push result
843 push_( (t_CKFLOAT *&)sp, temp );
849 //-----------------------------------------------------------------------------
850 // name: execute()
851 // desc: ...
852 //-----------------------------------------------------------------------------
853 void Chuck_Instr_Add_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
855 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
856 t_CKCOMPLEX temp;
857 // pop value + pointer
858 pop_( sp, sz_COMPLEX + sz_UINT );
860 // assign
861 temp.re = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re += ((t_CKCOMPLEX *&)sp)->re;
862 temp.im = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im += ((t_CKCOMPLEX *&)sp)->im;
863 // push result
864 push_( (t_CKCOMPLEX *&)sp, temp );
870 //-----------------------------------------------------------------------------
871 // name: execute()
872 // desc: ...
873 //-----------------------------------------------------------------------------
874 void Chuck_Instr_Minus_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
876 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
877 t_CKCOMPLEX temp;
878 // pop value + pointer
879 pop_( sp, sz_COMPLEX + sz_UINT );
881 // assign
882 temp.re = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re -= ((t_CKCOMPLEX *&)sp)->re;
883 temp.im = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im -= ((t_CKCOMPLEX *&)sp)->im;
884 // push result
885 push_( (t_CKCOMPLEX *&)sp, temp );
891 //-----------------------------------------------------------------------------
892 // name: execute()
893 // desc: ...
894 //-----------------------------------------------------------------------------
895 void Chuck_Instr_Times_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
897 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
898 t_CKCOMPLEX temp, a, b;
899 // pop value + pointer
900 pop_( sp, sz_COMPLEX + sz_UINT );
901 // copy
902 a = **(t_CKCOMPLEX **)(sp+sz_COMPLEX);
903 b = *(t_CKCOMPLEX *&)sp;
904 // calculate
905 temp.re = a.re * b.re - a.im * b.im;
906 temp.im = a.re * b.im + a.im * b.re;
907 // assign
908 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re = temp.re;
909 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im = temp.im;
910 // push result
911 push_( (t_CKCOMPLEX *&)sp, temp );
917 //-----------------------------------------------------------------------------
918 // name: execute()
919 // desc: ...
920 //-----------------------------------------------------------------------------
921 void Chuck_Instr_Divide_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
923 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
924 t_CKCOMPLEX temp, a, b;
925 t_CKFLOAT denom;
926 // pop value + pointer
927 pop_( sp, sz_COMPLEX + sz_UINT );
928 // copy
929 a = **(t_CKCOMPLEX **)(sp+sz_COMPLEX);
930 b = *(t_CKCOMPLEX *&)sp;
931 // calculate
932 temp.re = a.re * b.re + a.im * b.im;
933 temp.im = a.im * b.re - a.re * b.im;
934 denom = b.re * b.re + b.im * b.im;
935 temp.re /= denom;
936 temp.im /= denom;
937 // assign
938 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re = temp.re;
939 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im = temp.im;
940 // push result
941 push_( (t_CKCOMPLEX *&)sp, temp );
947 //-----------------------------------------------------------------------------
948 // name: execute()
949 // desc: ...
950 //-----------------------------------------------------------------------------
951 void Chuck_Instr_Add_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
953 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
954 t_CKPOLAR result, * pa, * pb;
955 t_CKCOMPLEX temp, a, b;
956 // pop value + pointer
957 pop_( sp, sz_POLAR + sz_UINT );
958 // pointer copy
959 pa = *(t_CKPOLAR **)(sp+sz_POLAR);
960 pb = (t_CKPOLAR *&)sp;
961 // rectangular
962 a.re = pa->modulus * ::cos(pa->phase);
963 a.im = pa->modulus * ::sin(pa->phase);
964 b.re = pb->modulus * ::cos(pb->phase);
965 b.im = pb->modulus * ::sin(pb->phase);
966 // calculate
967 temp.re = a.re + b.re;
968 temp.im = a.im + b.im;
969 // assign
970 result.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus = ::hypot(temp.re,temp.im);
971 result.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase = ::atan2(temp.im,temp.re);
972 // push result
973 push_( (t_CKPOLAR *&)sp, result );
979 //-----------------------------------------------------------------------------
980 // name: execute()
981 // desc: ...
982 //-----------------------------------------------------------------------------
983 void Chuck_Instr_Minus_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
985 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
986 t_CKPOLAR result, * pa, * pb;
987 t_CKCOMPLEX temp, a, b;
988 // pop value + pointer
989 pop_( sp, sz_POLAR + sz_UINT );
990 // pointer copy
991 pa = *(t_CKPOLAR **)(sp+sz_POLAR);
992 pb = (t_CKPOLAR *&)sp;
993 // rectangular
994 a.re = pa->modulus * ::cos(pa->phase);
995 a.im = pa->modulus * ::sin(pa->phase);
996 b.re = pb->modulus * ::cos(pb->phase);
997 b.im = pb->modulus * ::sin(pb->phase);
998 // calculate
999 temp.re = a.re - b.re;
1000 temp.im = a.im - b.im;
1001 // assign
1002 result.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus = ::hypot(temp.re,temp.im);
1003 result.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase = ::atan2(temp.im,temp.re);
1004 // push result
1005 push_( (t_CKPOLAR *&)sp, result );
1011 //-----------------------------------------------------------------------------
1012 // name: execute()
1013 // desc: ...
1014 //-----------------------------------------------------------------------------
1015 void Chuck_Instr_Times_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1017 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1018 t_CKPOLAR temp;
1019 // pop value + pointer
1020 pop_( sp, sz_POLAR + sz_UINT );
1022 // assign
1023 temp.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus *= ((t_CKPOLAR *&)sp)->modulus;
1024 temp.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase += ((t_CKPOLAR *&)sp)->phase;
1025 // push result
1026 push_( (t_CKPOLAR *&)sp, temp );
1032 //-----------------------------------------------------------------------------
1033 // name: execute()
1034 // desc: ...
1035 //-----------------------------------------------------------------------------
1036 void Chuck_Instr_Divide_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1038 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1039 t_CKPOLAR temp;
1040 // pop value + pointer
1041 pop_( sp, sz_POLAR + sz_UINT );
1043 // assign
1044 temp.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus /= ((t_CKPOLAR *&)sp)->modulus;
1045 temp.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase -= ((t_CKPOLAR *&)sp)->phase;
1046 // push result
1047 push_( (t_CKPOLAR *&)sp, temp );
1053 //-----------------------------------------------------------------------------
1054 // name: execute()
1055 // desc: string + string
1056 //-----------------------------------------------------------------------------
1057 void Chuck_Instr_Add_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1059 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1060 Chuck_String * lhs = NULL;
1061 Chuck_String * rhs = NULL;
1062 Chuck_String * result = NULL;
1064 // pop word from reg stack
1065 pop_( reg_sp, 2 );
1066 // left
1067 lhs = (Chuck_String *)(*(reg_sp));
1068 // right
1069 rhs = (Chuck_String *)(*(reg_sp+1));
1071 // make sure no null
1072 if( !rhs || !lhs ) goto null_pointer;
1074 // make new string
1075 result = (Chuck_String *)instantiate_and_initialize_object( &t_string, shred );
1077 // concat
1078 result->str = lhs->str + rhs->str;
1080 // push the reference value to reg stack
1081 push_( reg_sp, (t_CKUINT)(result) );
1083 return;
1085 null_pointer:
1086 // we have a problem
1087 fprintf( stderr,
1088 "[chuck](VM): NullPointerException: (string + string) in shred[id=%d:%s], PC=[%d]\n",
1089 shred->xid, shred->name.c_str(), shred->pc );
1090 goto done;
1092 done:
1093 // do something!
1094 shred->is_running = FALSE;
1095 shred->is_done = TRUE;
1101 //-----------------------------------------------------------------------------
1102 // name: execute()
1103 // desc: add assign string
1104 //-----------------------------------------------------------------------------
1105 void Chuck_Instr_Add_string_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1107 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1108 Chuck_String * lhs = NULL;
1109 Chuck_String ** rhs_ptr = NULL;
1111 // pop word from reg stack
1112 pop_( reg_sp, 2 );
1113 // the previous reference
1114 rhs_ptr = (Chuck_String **)(*(reg_sp+1));
1115 // copy popped value into memory
1116 lhs = (Chuck_String *)(*(reg_sp));
1118 // make sure no null
1119 if( !(*rhs_ptr) ) goto null_pointer;
1121 // concat
1122 (*rhs_ptr)->str += lhs->str;
1124 // push the reference value to reg stack
1125 push_( reg_sp, (t_CKUINT)(*rhs_ptr) );
1127 return;
1129 null_pointer:
1130 // we have a problem
1131 fprintf( stderr,
1132 "[chuck](VM): NullPointerException: (string + string) in shred[id=%d:%s], PC=[%d]\n",
1133 shred->xid, shred->name.c_str(), shred->pc );
1134 goto done;
1136 done:
1137 // do something!
1138 shred->is_running = FALSE;
1139 shred->is_done = TRUE;
1145 //-----------------------------------------------------------------------------
1146 // name: execute()
1147 // desc: string + int
1148 //-----------------------------------------------------------------------------
1149 void Chuck_Instr_Add_string_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1151 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1152 Chuck_String * lhs = NULL;
1153 t_CKINT rhs = 0;
1154 Chuck_String * result = NULL;
1156 // pop word from reg stack
1157 pop_( reg_sp, 2 );
1158 // left
1159 lhs = (Chuck_String *)(*(reg_sp));
1160 // right
1161 rhs = (*(t_CKINT *)(reg_sp+1));
1163 // make sure no null
1164 if( !lhs ) goto null_pointer;
1166 // make new string
1167 result = (Chuck_String *)instantiate_and_initialize_object( &t_string, shred );
1169 // concat
1170 result->str = lhs->str + ::itoa(rhs);
1172 // push the reference value to reg stack
1173 push_( reg_sp, (t_CKUINT)(result) );
1175 return;
1177 null_pointer:
1178 // we have a problem
1179 fprintf( stderr,
1180 "[chuck](VM): NullPointerException: (string + int) in shred[id=%d:%s], PC=[%d]\n",
1181 shred->xid, shred->name.c_str(), shred->pc );
1182 goto done;
1184 done:
1185 // do something!
1186 shred->is_running = FALSE;
1187 shred->is_done = TRUE;
1193 //-----------------------------------------------------------------------------
1194 // name: execute()
1195 // desc: string + float
1196 //-----------------------------------------------------------------------------
1197 void Chuck_Instr_Add_string_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1199 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1200 Chuck_String * lhs = NULL;
1201 t_CKFLOAT rhs = 0;
1202 Chuck_String * result = NULL;
1204 // pop word from reg stack
1205 pop_( reg_sp, 3 );
1206 // left
1207 lhs = (Chuck_String *)(*(reg_sp));
1208 // right
1209 rhs = (*(t_CKFLOAT *)(reg_sp+1));
1211 // make sure no null
1212 if( !lhs ) goto null_pointer;
1214 // make new string
1215 result = (Chuck_String *)instantiate_and_initialize_object( &t_string, shred );
1217 // concat
1218 result->str = lhs->str + ::ftoa(rhs, 4);
1220 // push the reference value to reg stack
1221 push_( reg_sp, (t_CKUINT)(result) );
1223 return;
1225 null_pointer:
1226 // we have a problem
1227 fprintf( stderr,
1228 "[chuck](VM): NullPointerException: (string + float) in shred[id=%d:%s], PC=[%d]\n",
1229 shred->xid, shred->name.c_str(), shred->pc );
1230 goto done;
1232 done:
1233 // do something!
1234 shred->is_running = FALSE;
1235 shred->is_done = TRUE;
1241 //-----------------------------------------------------------------------------
1242 // name: execute()
1243 // desc: int + string
1244 //-----------------------------------------------------------------------------
1245 void Chuck_Instr_Add_int_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1247 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1248 t_CKINT lhs = 0;
1249 Chuck_String * rhs = NULL;
1250 Chuck_String * result = NULL;
1252 // pop word from reg stack
1253 pop_( reg_sp, 2 );
1254 // left
1255 lhs = (*(t_CKINT *)(reg_sp));
1256 // right
1257 rhs = (Chuck_String *)(*(reg_sp+1));
1259 // make sure no null
1260 if( !rhs ) goto null_pointer;
1262 // make new string
1263 result = (Chuck_String *)instantiate_and_initialize_object( &t_string, shred );
1265 // concat
1266 result->str = ::itoa(lhs) + rhs->str;
1268 // push the reference value to reg stack
1269 push_( reg_sp, (t_CKUINT)(result) );
1271 return;
1273 null_pointer:
1274 // we have a problem
1275 fprintf( stderr,
1276 "[chuck](VM): NullPointerException: (int + string) in shred[id=%d:%s], PC=[%d]\n",
1277 shred->xid, shred->name.c_str(), shred->pc );
1278 goto done;
1280 done:
1281 // do something!
1282 shred->is_running = FALSE;
1283 shred->is_done = TRUE;
1289 //-----------------------------------------------------------------------------
1290 // name: execute()
1291 // desc: float + string
1292 //-----------------------------------------------------------------------------
1293 void Chuck_Instr_Add_float_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1295 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1296 t_CKFLOAT lhs = 0;
1297 Chuck_String * rhs = NULL;
1298 Chuck_String * result = NULL;
1300 // pop word from reg stack
1301 pop_( reg_sp, 3 );
1302 // left (2 word)
1303 lhs = (*(t_CKFLOAT *)(reg_sp));
1304 // right
1305 rhs = (Chuck_String *)(*(reg_sp+2));
1307 // make sure no null
1308 if( !rhs ) goto null_pointer;
1310 // make new string
1311 result = (Chuck_String *)instantiate_and_initialize_object( &t_string, shred );
1313 // concat
1314 result->str = ::ftoa(lhs, 4) + rhs->str;
1316 // push the reference value to reg stack
1317 push_( reg_sp, (t_CKUINT)(result) );
1319 return;
1321 null_pointer:
1322 // we have a problem
1323 fprintf( stderr,
1324 "[chuck](VM): NullPointerException: (int + string) in shred[id=%d:%s], PC=[%d]\n",
1325 shred->xid, shred->name.c_str(), shred->pc );
1326 goto done;
1328 done:
1329 // do something!
1330 shred->is_running = FALSE;
1331 shred->is_done = TRUE;
1337 //-----------------------------------------------------------------------------
1338 // name: execute()
1339 // desc: add assign int string
1340 //-----------------------------------------------------------------------------
1341 void Chuck_Instr_Add_int_string_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1343 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1344 t_CKINT lhs = 0;
1345 Chuck_String ** rhs_ptr = NULL;
1347 // pop word from reg stack
1348 pop_( reg_sp, 2 );
1349 // the previous reference
1350 rhs_ptr = (Chuck_String **)(*(reg_sp+1));
1351 // copy popped value into memory
1352 lhs = (*(t_CKINT *)(reg_sp));
1354 // make sure no null
1355 if( !(*rhs_ptr) ) goto null_pointer;
1357 // concat
1358 (*rhs_ptr)->str += ::itoa(lhs);
1360 // push the reference value to reg stack
1361 push_( reg_sp, (t_CKUINT)(*rhs_ptr) );
1363 return;
1365 null_pointer:
1366 // we have a problem
1367 fprintf( stderr,
1368 "[chuck](VM): NullPointerException: () in shred[id=%d:%s], PC=[%d]\n",
1369 shred->xid, shred->name.c_str(), shred->pc );
1370 goto done;
1372 done:
1373 // do something!
1374 shred->is_running = FALSE;
1375 shred->is_done = TRUE;
1381 //-----------------------------------------------------------------------------
1382 // name: execute()
1383 // desc: add assign float string
1384 //-----------------------------------------------------------------------------
1385 void Chuck_Instr_Add_float_string_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1387 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1388 t_CKFLOAT lhs = 0;
1389 Chuck_String ** rhs_ptr = NULL;
1391 // pop word from reg stack
1392 pop_( reg_sp, 3 );
1393 // the previous reference
1394 rhs_ptr = (Chuck_String **)(*(reg_sp+2));
1395 // copy popped value into memory
1396 lhs = (*(t_CKFLOAT *)(reg_sp));
1398 // make sure no null
1399 if( !(*rhs_ptr) ) goto null_pointer;
1401 // concat
1402 (*rhs_ptr)->str += ::ftoa(lhs, 4);
1404 // push the reference value to reg stack
1405 push_( reg_sp, (t_CKUINT)(*rhs_ptr) );
1407 return;
1409 null_pointer:
1410 // we have a problem
1411 fprintf( stderr,
1412 "[chuck](VM): NullPointerException: (string + string) in shred[id=%d:%s], PC=[%d]\n",
1413 shred->xid, shred->name.c_str(), shred->pc );
1414 goto done;
1416 done:
1417 // do something!
1418 shred->is_running = FALSE;
1419 shred->is_done = TRUE;
1425 //-----------------------------------------------------------------------------
1426 // name: execute()
1427 // desc: ...
1428 //-----------------------------------------------------------------------------
1429 void Chuck_Instr_Reg_Push_Imm::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1431 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1433 // push val into reg stack
1434 push_( reg_sp, m_val );
1440 //-----------------------------------------------------------------------------
1441 // name: execute()
1442 // desc: ...
1443 //-----------------------------------------------------------------------------
1444 void Chuck_Instr_Reg_Push_Imm2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1446 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
1448 // push val into reg stack
1449 push_( reg_sp, m_val );
1455 //-----------------------------------------------------------------------------
1456 // name: execute()
1457 // desc: ...
1458 //-----------------------------------------------------------------------------
1459 void Chuck_Instr_Reg_Push_Imm4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1461 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
1463 // push val into reg stack
1464 push_( reg_sp, m_val );
1465 push_( reg_sp, m_val2 );
1471 //-----------------------------------------------------------------------------
1472 // name: execute()
1473 // desc: ...
1474 //-----------------------------------------------------------------------------
1475 void Chuck_Instr_Reg_Dup_Last::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1477 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1479 // dup val into reg stack
1480 push_( reg_sp, *(reg_sp-1) );
1486 //-----------------------------------------------------------------------------
1487 // name: execute()
1488 // desc: ...
1489 //-----------------------------------------------------------------------------
1490 void Chuck_Instr_Reg_Dup_Last2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1492 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
1494 // dup val into reg stack
1495 push_( reg_sp, *(reg_sp-1) );
1501 //-----------------------------------------------------------------------------
1502 // name: execute()
1503 // desc: ...
1504 //-----------------------------------------------------------------------------
1505 void Chuck_Instr_Reg_Push_Now::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1507 t_CKTIME *& reg_sp = (t_CKTIME *&)shred->reg->sp;
1509 // push val into reg stack
1510 push_( reg_sp, shred->now );
1516 //-----------------------------------------------------------------------------
1517 // name: execute()
1518 // desc: ...
1519 //-----------------------------------------------------------------------------
1520 void Chuck_Instr_Reg_Push_Me::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1522 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1524 // push val into reg stack
1525 push_( reg_sp, (t_CKUINT)shred );
1531 //-----------------------------------------------------------------------------
1532 // name: execute()
1533 // desc: ...
1534 //-----------------------------------------------------------------------------
1535 void Chuck_Instr_Reg_Push_This::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1537 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1538 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
1540 // push val into reg stack
1541 push_( reg_sp, *(mem_sp) );
1547 //-----------------------------------------------------------------------------
1548 // name: execute()
1549 // desc: ...
1550 //-----------------------------------------------------------------------------
1551 void Chuck_Instr_Reg_Push_Start::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1553 t_CKTIME *& reg_sp = (t_CKTIME *&)shred->reg->sp;
1555 // push val into reg stack
1556 push_( reg_sp, shred->start );
1562 //-----------------------------------------------------------------------------
1563 // name: execute()
1564 // desc: ...
1565 //-----------------------------------------------------------------------------
1566 void Chuck_Instr_Reg_Push_Maybe::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1568 t_CKINT *& reg_sp = (t_CKINT *&)shred->reg->sp;
1570 // push val into reg stack
1571 float num = (float)rand() / (float)RAND_MAX;
1572 push_( reg_sp, num > .5 );
1578 //-----------------------------------------------------------------------------
1579 // name: execute()
1580 // desc: push the value pointed to by m_val onto register stack
1581 //-----------------------------------------------------------------------------
1582 void Chuck_Instr_Reg_Push_Deref::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1584 if( m_size == 4 ) // ISSUE: 64-bit
1586 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1587 push_( reg_sp, *((t_CKUINT *)m_val) );
1589 else
1591 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
1592 push_( reg_sp, *((t_CKFLOAT *)m_val) );
1599 //-----------------------------------------------------------------------------
1600 // name: execute()
1601 // desc: push value from memory stack to register stack
1602 //-----------------------------------------------------------------------------
1603 void Chuck_Instr_Reg_Push_Mem::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1605 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
1606 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1608 // push mem stack content into reg stack
1609 push_( reg_sp, *((t_CKUINT *)(mem_sp + m_val)) );
1615 //-----------------------------------------------------------------------------
1616 // name: execute()
1617 // desc: ...
1618 //-----------------------------------------------------------------------------
1619 void Chuck_Instr_Reg_Push_Mem2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1621 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
1622 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
1624 // push mem stack content into reg stack
1625 push_( reg_sp, *((t_CKFLOAT *)(mem_sp + m_val)) );
1631 //-----------------------------------------------------------------------------
1632 // name: execute()
1633 // desc: ...
1634 //-----------------------------------------------------------------------------
1635 void Chuck_Instr_Reg_Push_Mem4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1637 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
1638 t_CKCOMPLEX *& reg_sp = (t_CKCOMPLEX *&)shred->reg->sp;
1640 // push mem stack content into reg stack
1641 push_( reg_sp, *((t_CKCOMPLEX *)(mem_sp + m_val)) );
1647 //-----------------------------------------------------------------------------
1648 // name: execute()
1649 // desc: ...
1650 //-----------------------------------------------------------------------------
1651 void Chuck_Instr_Reg_Push_Mem_Addr::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1653 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
1654 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1656 // push mem stack addr into reg stack
1657 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
1663 //-----------------------------------------------------------------------------
1664 // name: execute()
1665 // desc: ...
1666 //-----------------------------------------------------------------------------
1667 void Chuck_Instr_Reg_Pop_Mem::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1669 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
1670 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1672 // pop word from reg stack
1673 pop_( reg_sp, 2 );
1674 // copy popped value into mem stack
1675 *((t_CKUINT *)(mem_sp + *(reg_sp+1) )) = *reg_sp;
1681 //-----------------------------------------------------------------------------
1682 // name: execute()
1683 // desc: ...
1684 //-----------------------------------------------------------------------------
1685 void Chuck_Instr_Reg_Pop_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1687 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1689 // pop word from reg stack
1690 pop_( reg_sp, 1 );
1696 //-----------------------------------------------------------------------------
1697 // name: execute()
1698 // desc: ...
1699 //-----------------------------------------------------------------------------
1700 void Chuck_Instr_Reg_Pop_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1702 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
1704 // pop word from reg stack
1705 pop_( reg_sp, 1 );
1711 //-----------------------------------------------------------------------------
1712 // name: execute()
1713 // desc: ...
1714 //-----------------------------------------------------------------------------
1715 void Chuck_Instr_Reg_Pop_Word3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1717 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1719 // pop word from reg stack
1720 pop_( reg_sp, m_val );
1726 //-----------------------------------------------------------------------------
1727 // name: execute()
1728 // desc: ...
1729 //-----------------------------------------------------------------------------
1730 void Chuck_Instr_Mem_Set_Imm::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1732 t_CKUINT * mem_sp = (t_CKUINT *)(shred->mem->sp + m_offset);
1734 // set
1735 *(mem_sp) = m_val;
1741 //-----------------------------------------------------------------------------
1742 // name: execute()
1743 // desc: ...
1744 //-----------------------------------------------------------------------------
1745 void Chuck_Instr_Mem_Set_Imm2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1747 t_CKFLOAT * mem_sp = (t_CKFLOAT *)(shred->mem->sp + m_offset);
1749 // set
1750 *(mem_sp) = m_val;
1756 //-----------------------------------------------------------------------------
1757 // name: execute()
1758 // desc: ...
1759 //-----------------------------------------------------------------------------
1760 void Chuck_Instr_Mem_Push_Imm::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1762 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
1764 // pop word from reg stack
1765 push_( mem_sp, m_val );
1771 //-----------------------------------------------------------------------------
1772 // name: execute()
1773 // desc: ...
1774 //-----------------------------------------------------------------------------
1775 void Chuck_Instr_Mem_Push_Imm2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1777 t_CKFLOAT *& mem_sp = (t_CKFLOAT *&)shred->mem->sp;
1779 // pop word from reg stack
1780 push_( mem_sp, m_val );
1786 //-----------------------------------------------------------------------------
1787 // name: execute()
1788 // desc: ...
1789 //-----------------------------------------------------------------------------
1790 void Chuck_Instr_Mem_Pop_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1792 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
1794 // pop word from reg stack
1795 pop_( mem_sp, 1 );
1801 //-----------------------------------------------------------------------------
1802 // name: execute()
1803 // desc: ...
1804 //-----------------------------------------------------------------------------
1805 void Chuck_Instr_Mem_Pop_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1807 t_CKFLOAT *& mem_sp = (t_CKFLOAT *&)shred->mem->sp;
1809 // pop word from reg stack
1810 pop_( mem_sp, 1 );
1816 //-----------------------------------------------------------------------------
1817 // name: execute()
1818 // desc: ...
1819 //-----------------------------------------------------------------------------
1820 void Chuck_Instr_Mem_Pop_Word3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1822 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
1824 // pop word from reg stack
1825 pop_( mem_sp, m_val );
1831 //-----------------------------------------------------------------------------
1832 // name: execute()
1833 // desc: ...
1834 //-----------------------------------------------------------------------------
1835 void Chuck_Instr_Branch_Lt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1837 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1838 pop_( sp, 2 );
1839 if( val_(sp) < val_(sp+1) )
1840 shred->next_pc = m_jmp;
1846 //-----------------------------------------------------------------------------
1847 // name: execute()
1848 // desc: ...
1849 //-----------------------------------------------------------------------------
1850 void Chuck_Instr_Branch_Gt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1852 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1853 pop_( sp, 2 );
1854 if( val_(sp) > val_(sp+1) )
1855 shred->next_pc = m_jmp;
1861 //-----------------------------------------------------------------------------
1862 // name: execute()
1863 // desc: ...
1864 //-----------------------------------------------------------------------------
1865 void Chuck_Instr_Branch_Le_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1867 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1868 pop_( sp, 2 );
1869 if( val_(sp) <= val_(sp+1) )
1870 shred->next_pc = m_jmp;
1876 //-----------------------------------------------------------------------------
1877 // name: execute()
1878 // desc: ...
1879 //-----------------------------------------------------------------------------
1880 void Chuck_Instr_Branch_Ge_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1882 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1883 pop_( sp, 2 );
1884 if( val_(sp) >= val_(sp+1) )
1885 shred->next_pc = m_jmp;
1891 //-----------------------------------------------------------------------------
1892 // name: execute()
1893 // desc: ...
1894 //-----------------------------------------------------------------------------
1895 void Chuck_Instr_Branch_Eq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1897 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1898 pop_( sp, 2 );
1899 if( val_(sp) == val_(sp+1) )
1900 shred->next_pc = m_jmp;
1906 //-----------------------------------------------------------------------------
1907 // name: execute()
1908 // desc: ...
1909 //-----------------------------------------------------------------------------
1910 void Chuck_Instr_Branch_Neq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1912 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1913 pop_( sp, 2 );
1914 if( val_(sp) != val_(sp+1) )
1915 shred->next_pc = m_jmp;
1921 //-----------------------------------------------------------------------------
1922 // name: execute()
1923 // desc: ...
1924 //-----------------------------------------------------------------------------
1925 void Chuck_Instr_Not_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1927 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1928 (*(sp-1)) = !(*(sp-1));
1934 //-----------------------------------------------------------------------------
1935 // name: execute()
1936 // desc: ...
1937 //-----------------------------------------------------------------------------
1938 void Chuck_Instr_Negate_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1940 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
1941 (*(sp-1)) = -(*(sp-1));
1947 //-----------------------------------------------------------------------------
1948 // name: execute()
1949 // desc: ...
1950 //-----------------------------------------------------------------------------
1951 void Chuck_Instr_Negate_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1953 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
1954 (*(sp-1)) = -(*(sp-1));
1960 //-----------------------------------------------------------------------------
1961 // name: execute()
1962 // desc: ...
1963 //-----------------------------------------------------------------------------
1964 void Chuck_Instr_Branch_Lt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1966 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
1967 pop_( sp, 2 );
1968 if( val_(sp) < val_(sp+1) )
1969 shred->next_pc = m_jmp;
1975 //-----------------------------------------------------------------------------
1976 // name: execute()
1977 // desc: ...
1978 //-----------------------------------------------------------------------------
1979 void Chuck_Instr_Branch_Gt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1981 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
1982 pop_( sp, 2 );
1983 if( val_(sp) > val_(sp+1) )
1984 shred->next_pc = m_jmp;
1990 //-----------------------------------------------------------------------------
1991 // name: execute()
1992 // desc: ...
1993 //-----------------------------------------------------------------------------
1994 void Chuck_Instr_Branch_Le_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1996 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
1997 pop_( sp, 2 );
1998 if( val_(sp) <= val_(sp+1) )
1999 shred->next_pc = m_jmp;
2005 //-----------------------------------------------------------------------------
2006 // name: execute()
2007 // desc: ...
2008 //-----------------------------------------------------------------------------
2009 void Chuck_Instr_Branch_Ge_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2011 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2012 pop_( sp, 2 );
2013 if( val_(sp) >= val_(sp+1) )
2014 shred->next_pc = m_jmp;
2020 //-----------------------------------------------------------------------------
2021 // name: execute()
2022 // desc: ...
2023 //-----------------------------------------------------------------------------
2024 void Chuck_Instr_Branch_Eq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2026 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2027 pop_( sp, 2 );
2028 if( val_(sp) == val_(sp+1) )
2029 shred->next_pc = m_jmp;
2035 //-----------------------------------------------------------------------------
2036 // name: execute()
2037 // desc: ...
2038 //-----------------------------------------------------------------------------
2039 void Chuck_Instr_Branch_Neq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2041 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2042 pop_( sp, 2 );
2043 if( val_(sp) != val_(sp+1) )
2044 shred->next_pc = m_jmp;
2050 //-----------------------------------------------------------------------------
2051 // name: execute()
2052 // desc: ...
2053 //-----------------------------------------------------------------------------
2054 void Chuck_Instr_Binary_And::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2056 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2057 pop_( sp, 2 );
2058 push_( sp, val_(sp) & val_(sp+1) );
2064 //-----------------------------------------------------------------------------
2065 // name: execute()
2066 // desc: ...
2067 //-----------------------------------------------------------------------------
2068 void Chuck_Instr_Binary_Or::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2070 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2071 pop_( sp, 2 );
2072 push_( sp, val_(sp) | val_(sp+1) );
2078 //-----------------------------------------------------------------------------
2079 // name: execute()
2080 // desc: ...
2081 //-----------------------------------------------------------------------------
2082 void Chuck_Instr_Binary_Xor::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2084 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2085 pop_( sp, 2 );
2086 push_( sp, val_(sp) ^ val_(sp+1) );
2092 //-----------------------------------------------------------------------------
2093 // name: execute()
2094 // desc: ...
2095 //-----------------------------------------------------------------------------
2096 void Chuck_Instr_Binary_Shift_Right::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2098 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2099 pop_( sp, 2 );
2100 push_( sp, val_(sp) >> val_(sp+1) );
2106 //-----------------------------------------------------------------------------
2107 // name: execute()
2108 // desc: ...
2109 //-----------------------------------------------------------------------------
2110 void Chuck_Instr_Binary_Shift_Right_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2112 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2113 pop_( sp, 2 );
2114 push_( sp, val_(sp+1) >> val_(sp) );
2120 //-----------------------------------------------------------------------------
2121 // name: execute()
2122 // desc: ...
2123 //-----------------------------------------------------------------------------
2124 void Chuck_Instr_Binary_Shift_Left::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2126 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2127 pop_( sp, 2 );
2128 push_( sp, val_(sp) << val_(sp+1) );
2134 //-----------------------------------------------------------------------------
2135 // name: execute()
2136 // desc: ...
2137 //-----------------------------------------------------------------------------
2138 void Chuck_Instr_Binary_Shift_Left_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2140 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2141 pop_( sp, 2 );
2142 push_( sp, val_(sp+1) << val_(sp) );
2148 //-----------------------------------------------------------------------------
2149 // name: execute()
2150 // desc: ...
2151 //-----------------------------------------------------------------------------
2152 void Chuck_Instr_Binary_And_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2154 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2155 pop_( sp, 2 );
2156 temp = **(t_CKINT **)(sp+1) &= val_(sp);
2157 push_( sp, temp );
2163 //-----------------------------------------------------------------------------
2164 // name: execute()
2165 // desc: ...
2166 //-----------------------------------------------------------------------------
2167 void Chuck_Instr_Binary_Or_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2169 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2170 pop_( sp, 2 );
2171 temp = **(t_CKINT **)(sp+1) |= val_(sp);
2172 push_( sp, temp );
2178 //-----------------------------------------------------------------------------
2179 // name: execute()
2180 // desc: ...
2181 //-----------------------------------------------------------------------------
2182 void Chuck_Instr_Binary_Xor_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2184 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2185 pop_( sp, 2 );
2186 temp = **(t_CKINT **)(sp+1) ^= val_(sp);
2187 push_( sp, temp );
2193 //-----------------------------------------------------------------------------
2194 // name: execute()
2195 // desc: ...
2196 //-----------------------------------------------------------------------------
2197 void Chuck_Instr_Binary_Shift_Right_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2199 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2200 pop_( sp, 2 );
2201 temp = **(t_CKINT **)(sp+1) >>= val_(sp);
2202 push_( sp, temp );
2208 //-----------------------------------------------------------------------------
2209 // name: execute()
2210 // desc: ...
2211 //-----------------------------------------------------------------------------
2212 void Chuck_Instr_Binary_Shift_Left_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2214 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2215 pop_( sp, 2 );
2216 temp = **(t_CKINT **)(sp+1) <<= val_(sp);
2217 push_( sp, temp );
2223 //-----------------------------------------------------------------------------
2224 // name: execute()
2225 // desc: ...
2226 //-----------------------------------------------------------------------------
2227 void Chuck_Instr_Lt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2229 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2230 pop_( sp, 2 );
2231 push_( sp, val_(sp) < val_(sp+1) );
2237 //-----------------------------------------------------------------------------
2238 // name: execute()
2239 // desc: ...
2240 //-----------------------------------------------------------------------------
2241 void Chuck_Instr_Gt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2243 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2244 pop_( sp, 2 );
2245 push_( sp, val_(sp) > val_(sp+1) );
2251 //-----------------------------------------------------------------------------
2252 // name: execute()
2253 // desc: ...
2254 //-----------------------------------------------------------------------------
2255 void Chuck_Instr_Le_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2257 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2258 pop_( sp, 2 );
2259 push_( sp, val_(sp) <= val_(sp+1) );
2265 //-----------------------------------------------------------------------------
2266 // name: execute()
2267 // desc: ...
2268 //-----------------------------------------------------------------------------
2269 void Chuck_Instr_Ge_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2271 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2272 pop_( sp, 2 );
2273 push_( sp, val_(sp) >= val_(sp+1) );
2279 //-----------------------------------------------------------------------------
2280 // name: execute()
2281 // desc: ...
2282 //-----------------------------------------------------------------------------
2283 void Chuck_Instr_Eq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2285 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2286 pop_( sp, 2 );
2287 push_( sp, val_(sp) == val_(sp+1) );
2293 //-----------------------------------------------------------------------------
2294 // name: execute()
2295 // desc: ...
2296 //-----------------------------------------------------------------------------
2297 void Chuck_Instr_Neq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2299 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2300 pop_( sp, 2 );
2301 push_( sp, val_(sp) != val_(sp+1) );
2307 //-----------------------------------------------------------------------------
2308 // name: execute()
2309 // desc: ...
2310 //-----------------------------------------------------------------------------
2311 void Chuck_Instr_Lt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2313 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2314 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
2315 pop_( sp, 2 );
2316 push_( sp_uint, val_(sp) < val_(sp+1) );
2322 //-----------------------------------------------------------------------------
2323 // name: execute()
2324 // desc: ...
2325 //-----------------------------------------------------------------------------
2326 void Chuck_Instr_Gt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2328 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2329 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
2330 pop_( sp, 2 );
2331 push_( sp_uint, val_(sp) > val_(sp+1) );
2337 //-----------------------------------------------------------------------------
2338 // name: execute()
2339 // desc: ...
2340 //-----------------------------------------------------------------------------
2341 void Chuck_Instr_Le_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2343 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2344 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
2345 pop_( sp, 2 );
2346 push_( sp_uint, val_(sp) <= val_(sp+1) );
2352 //-----------------------------------------------------------------------------
2353 // name: execute()
2354 // desc: ...
2355 //-----------------------------------------------------------------------------
2356 void Chuck_Instr_Ge_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2358 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2359 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
2360 pop_( sp, 2 );
2361 push_( sp_uint, val_(sp) >= val_(sp+1) );
2367 //-----------------------------------------------------------------------------
2368 // name: execute()
2369 // desc: ...
2370 //-----------------------------------------------------------------------------
2371 void Chuck_Instr_Eq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2373 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2374 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
2375 pop_( sp, 2 );
2376 push_( sp_uint, val_(sp) == val_(sp+1) );
2382 //-----------------------------------------------------------------------------
2383 // name: execute()
2384 // desc: ...
2385 //-----------------------------------------------------------------------------
2386 void Chuck_Instr_Neq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2388 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2389 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
2390 pop_( sp, 2 );
2391 push_( sp_uint, val_(sp) != val_(sp+1) );
2397 //-----------------------------------------------------------------------------
2398 // name: execute()
2399 // desc: ...
2400 //-----------------------------------------------------------------------------
2401 void Chuck_Instr_And::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2403 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2404 pop_( sp, 2 );
2405 push_( sp, val_(sp) && val_(sp+1) );
2411 //-----------------------------------------------------------------------------
2412 // name: execute()
2413 // desc: ...
2414 //-----------------------------------------------------------------------------
2415 void Chuck_Instr_Or::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2417 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2418 pop_( sp, 2 );
2419 push_( sp, val_(sp) || val_(sp+1) );
2425 //-----------------------------------------------------------------------------
2426 // name: execute()
2427 // desc: ...
2428 //-----------------------------------------------------------------------------
2429 void Chuck_Instr_Goto::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2431 shred->next_pc = m_jmp;
2437 //-----------------------------------------------------------------------------
2438 // name: execute()
2439 // desc: ...
2440 //-----------------------------------------------------------------------------
2441 void Chuck_Instr_Nop::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2443 // no op
2449 //-----------------------------------------------------------------------------
2450 // name: execute()
2451 // desc: ...
2452 //-----------------------------------------------------------------------------
2453 void Chuck_Instr_EOC::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2455 // end the shred
2456 shred->is_done = TRUE;
2457 shred->is_running = FALSE;
2463 //-----------------------------------------------------------------------------
2464 // name: execute()
2465 // desc: alloc local
2466 //-----------------------------------------------------------------------------
2467 void Chuck_Instr_Alloc_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2469 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
2470 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2472 // zero out the memory stack
2473 *( (t_CKUINT *)(mem_sp + m_val) ) = 0;
2474 // push addr onto operand stack
2475 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
2481 //-----------------------------------------------------------------------------
2482 // name: execute()
2483 // desc: alloc local
2484 //-----------------------------------------------------------------------------
2485 void Chuck_Instr_Alloc_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2487 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
2488 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2490 // zero out the memory stack
2491 *( (t_CKFLOAT *)(mem_sp + m_val) ) = 0.0;
2492 // push addr onto operand stack
2493 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
2499 //-----------------------------------------------------------------------------
2500 // name: execute()
2501 // desc: alloc local
2502 //-----------------------------------------------------------------------------
2503 void Chuck_Instr_Alloc_Word4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2505 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
2506 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2508 // zero out the memory stack
2509 ( (t_CKCOMPLEX *)(mem_sp + m_val) )->re = 0.0;
2510 ( (t_CKCOMPLEX *)(mem_sp + m_val) )->im = 0.0;
2511 // push addr onto operand stack
2512 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
2518 //-----------------------------------------------------------------------------
2519 // name: execute()
2520 // desc: alloc member
2521 //-----------------------------------------------------------------------------
2522 void Chuck_Instr_Alloc_Member_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2524 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
2525 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2527 // get the object
2528 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
2529 // zero out the memory stack
2530 *( (t_CKUINT *)(obj->data + m_val) ) = 0;
2531 // push addr onto operand stack
2532 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
2538 //-----------------------------------------------------------------------------
2539 // name: execute()
2540 // desc: alloc member
2541 //-----------------------------------------------------------------------------
2542 void Chuck_Instr_Alloc_Member_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2544 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
2545 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2547 // get the object
2548 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
2549 // zero out the memory stack
2550 *( (t_CKFLOAT *)(obj->data + m_val) ) = 0.0;
2551 // push addr onto operand stack
2552 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
2558 //-----------------------------------------------------------------------------
2559 // name: execute()
2560 // desc: alloc member
2561 //-----------------------------------------------------------------------------
2562 void Chuck_Instr_Alloc_Member_Word4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2564 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
2565 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2567 // get the object
2568 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
2569 // zero out the memory stack
2570 ( (t_CKCOMPLEX *)(obj->data + m_val) )->re = 0.0;
2571 ( (t_CKCOMPLEX *)(obj->data + m_val) )->im = 0.0;
2572 // push addr onto operand stack
2573 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
2579 static Chuck_Instr_Func_Call g_func_call;
2580 static Chuck_Instr_Func_Call_Member g_func_call_member( 0 );
2581 //-----------------------------------------------------------------------------
2582 // name: call_pre_constructor()
2583 // desc: ...
2584 //-----------------------------------------------------------------------------
2585 inline void call_pre_constructor( Chuck_VM * vm, Chuck_VM_Shred * shred,
2586 Chuck_VM_Code * pre_ctor, t_CKUINT stack_offset )
2588 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2590 // sanity
2591 assert( pre_ctor != NULL );
2593 // first duplicate the top of the stack, which should be object pointer
2594 push_( reg_sp, *(reg_sp-1) );
2595 // push the pre constructor
2596 push_( reg_sp, (t_CKUINT)pre_ctor );
2597 // push the stack offset
2598 push_( reg_sp, stack_offset );
2600 // call the function
2601 if( pre_ctor->native_func != 0 )
2602 g_func_call_member.execute( vm, shred );
2603 else
2604 g_func_call.execute( vm, shred );
2610 //-----------------------------------------------------------------------------
2611 // name: execute()
2612 // desc: object pre construct
2613 //-----------------------------------------------------------------------------
2614 void Chuck_Instr_Pre_Constructor::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2616 call_pre_constructor( vm, shred, pre_ctor, stack_offset );
2622 //-----------------------------------------------------------------------------
2623 // name: instantiate_object()
2624 // desc: ...
2625 //-----------------------------------------------------------------------------
2626 t_CKBOOL initialize_object( Chuck_Object * object, Chuck_Type * type )
2628 // sanity
2629 assert( type != NULL );
2630 assert( type->info != NULL );
2632 // allocate virtual table
2633 object->vtable = new Chuck_VTable;
2634 if( !object->vtable ) goto out_of_memory;
2635 // copy the object's virtual table
2636 object->vtable->funcs = type->info->obj_v_table.funcs;
2637 // set the type reference
2638 // TODO: reference count
2639 object->type_ref = type;
2640 object->type_ref->add_ref();
2641 // get the size
2642 object->size = type->obj_size;
2643 // allocate memory
2644 if( object->size )
2646 // check to ensure enough memory
2647 object->data = new t_CKBYTE[object->size];
2648 if( !object->data ) goto out_of_memory;
2649 // zero it out
2650 memset( object->data, 0, object->size );
2652 else object->data = NULL;
2654 // special
2655 if( type->ugen_info )
2657 // ugen
2658 Chuck_UGen * ugen = (Chuck_UGen *)object;
2659 if( type->ugen_info->tick ) ugen->tick = type->ugen_info->tick;
2660 if( type->ugen_info->pmsg ) ugen->pmsg = type->ugen_info->pmsg;
2661 // TODO: another hack!
2662 if( type->ugen_info->tock ) ((Chuck_UAna *)ugen)->tock = type->ugen_info->tock;
2663 // allocate multi chan
2664 ugen->alloc_multi_chan( type->ugen_info->num_ins,
2665 type->ugen_info->num_outs );
2666 // allocate the channels
2667 for( t_CKUINT i = 0; i < ugen->m_multi_chan_size; i++ )
2669 // allocate ugen for each
2670 Chuck_Object * obj = instantiate_and_initialize_object(
2671 &t_ugen, ugen->shred );
2672 // cast to ugen
2673 ugen->m_multi_chan[i] = (Chuck_UGen *)obj;
2674 // additional reference count
2675 ugen->m_multi_chan[i]->add_ref();
2676 // owner
2677 ugen->m_multi_chan[i]->owner = ugen;
2678 // ref count
2679 ugen->add_ref();
2681 // TODO: alloc channels for uana
2684 return TRUE;
2686 out_of_memory:
2688 // we have a problem
2689 fprintf( stderr,
2690 "[chuck](VM): OutOfMemory: while instantiating object '%s'\n",
2691 type->c_name() );
2693 // delete
2694 if( object ) SAFE_DELETE( object->vtable );
2696 // return FALSE
2697 return FALSE;
2703 //-----------------------------------------------------------------------------
2704 // name: instantiate_and_initialize_object()
2705 // desc: ...
2706 //-----------------------------------------------------------------------------
2707 Chuck_Object * instantiate_and_initialize_object( Chuck_Type * type, Chuck_VM_Shred * shred )
2709 Chuck_Object * object = NULL;
2710 Chuck_UAna * uana = NULL;
2711 // TODO: this is a hack!
2712 Chuck_VM * vm_ref = shred ? shred->vm_ref : g_vm;
2714 // sanity
2715 assert( type != NULL );
2716 assert( type->info != NULL );
2718 // allocate the VM object
2719 if( !type->ugen_info )
2721 // check type TODO: make this faster
2722 if( isa( type, &t_event ) ) object = new Chuck_Event;
2723 else if( isa( type, &t_string ) ) object = new Chuck_String;
2724 // TODO: is this ok?
2725 else if( isa( type, &t_shred ) ) object = new Chuck_VM_Shred;
2726 else object = new Chuck_Object;
2728 else
2730 // make ugen
2731 Chuck_UGen * ugen = NULL;
2732 // ugen vs. uana
2733 if( type->ugen_info->tock != NULL )
2735 // uana
2736 object = ugen = uana = new Chuck_UAna;
2737 ugen->alloc_v( vm_ref->shreduler()->m_max_block_size );
2739 else
2741 object = ugen = new Chuck_UGen;
2742 ugen->alloc_v( vm_ref->shreduler()->m_max_block_size );
2745 if( shred )
2747 ugen->shred = shred;
2748 shred->add( ugen );
2752 // check to see enough memory
2753 if( !object ) goto out_of_memory;
2755 // initialize
2756 if( !initialize_object( object, type ) ) goto error;
2758 return object;
2760 out_of_memory:
2762 // we have a problem
2763 fprintf( stderr,
2764 "[chuck](VM): OutOfMemory: while instantiating object '%s'\n",
2765 type->c_name() );
2767 error:
2769 // delete
2770 SAFE_DELETE( object );
2772 // return NULL
2773 return NULL;
2779 //-----------------------------------------------------------------------------
2780 // name: instantiate_object()
2781 // desc: ...
2782 //-----------------------------------------------------------------------------
2783 inline void instantiate_object( Chuck_VM * vm, Chuck_VM_Shred * shred,
2784 Chuck_Type * type )
2786 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2788 // allocate the VM object
2789 Chuck_Object * object = instantiate_and_initialize_object( type, shred );
2790 if( !object ) goto error;
2792 // push the pointer on the operand stack
2793 push_( reg_sp, (t_CKUINT)object );
2795 // call preconstructor
2796 // call_pre_constructor( vm, shred, object, type, stack_offset );
2798 return;
2800 error:
2802 // do something!
2803 shred->is_running = FALSE;
2804 shred->is_done = TRUE;
2810 //-----------------------------------------------------------------------------
2811 // name: execute()
2812 // desc: instantiate object
2813 //-----------------------------------------------------------------------------
2814 void Chuck_Instr_Instantiate_Object::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2816 instantiate_object( vm, shred, this->type );
2822 //-----------------------------------------------------------------------------
2823 // name: params()
2824 // desc: ...
2825 //-----------------------------------------------------------------------------
2826 const char * Chuck_Instr_Instantiate_Object::params() const
2828 static char buffer[256];
2829 sprintf( buffer, "%s", this->type->c_name() );
2830 return buffer;
2836 //-----------------------------------------------------------------------------
2837 // name: params()
2838 // desc: text description
2839 //-----------------------------------------------------------------------------
2840 const char * Chuck_Instr_Pre_Ctor_Array_Top::params() const
2842 static char buffer[256];
2843 sprintf( buffer, "val=%ld, type=\"%s\"", m_val, type ? type->c_name() : "[empty]" );
2844 return buffer;
2850 //-----------------------------------------------------------------------------
2851 // name: execute()
2852 // desc: object pre construct top
2853 //-----------------------------------------------------------------------------
2854 void Chuck_Instr_Pre_Ctor_Array_Top::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2856 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2858 // see if we are done with all elements in the array
2859 if( *(reg_sp-2) >= *(reg_sp-1) )
2860 shred->next_pc = m_val;
2861 else
2863 // instantiate
2864 instantiate_object( vm, shred, type );
2871 //-----------------------------------------------------------------------------
2872 // name: execute()
2873 // desc: object pre construct bottom
2874 //-----------------------------------------------------------------------------
2875 void Chuck_Instr_Pre_Ctor_Array_Bottom::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2877 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2879 // pop the object
2880 pop_( reg_sp, 1 );
2882 // cast the object
2883 Chuck_Object * obj = (Chuck_Object *)(*(reg_sp));
2885 // assign object
2886 t_CKUINT * array = (t_CKUINT *)(*(reg_sp-3));
2887 // get the object pointer
2888 Chuck_Object ** dest = (Chuck_Object **)(array[*(reg_sp-2)]);
2889 // copy
2890 *dest = obj;
2891 // ref count
2892 obj->add_ref();
2893 // increment the index
2894 (*(reg_sp-2))++; //= (*(reg_sp-2)) + 1;
2896 // goto top
2897 shred->next_pc = m_val;
2903 //-----------------------------------------------------------------------------
2904 // name: execute()
2905 // desc: object pre construct post
2906 //-----------------------------------------------------------------------------
2907 void Chuck_Instr_Pre_Ctor_Array_Post::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2909 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2911 // pop the array, index, and size
2912 pop_( reg_sp, 3 );
2914 // clean up the array
2915 t_CKUINT * arr = (t_CKUINT *)*reg_sp;
2916 SAFE_DELETE_ARRAY( arr );
2922 //-----------------------------------------------------------------------------
2923 // name: execute()
2924 // desc: assign primitive (word)
2925 //-----------------------------------------------------------------------------
2926 void Chuck_Instr_Assign_Primitive::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2928 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2930 // pop word from reg stack
2931 pop_( reg_sp, 2 );
2932 // copy popped value into mem stack
2933 *((t_CKUINT *)(*(reg_sp+1))) = *reg_sp;
2935 push_( reg_sp, *reg_sp );
2941 //-----------------------------------------------------------------------------
2942 // name: execute()
2943 // desc: assign primitive (2 word)
2944 //-----------------------------------------------------------------------------
2945 void Chuck_Instr_Assign_Primitive2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2947 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2949 // pop word from reg stack // ISSUE: 64-bit
2950 pop_( reg_sp, 3 );
2951 // copy popped value into mem stack
2952 *( (t_CKFLOAT *)(*(reg_sp+2)) ) = *(t_CKFLOAT *)reg_sp;
2954 t_CKFLOAT *& sp_double = (t_CKFLOAT *&)reg_sp;
2955 push_( sp_double, *sp_double );
2961 //-----------------------------------------------------------------------------
2962 // name: execute()
2963 // desc: assign primitive (4 word)
2964 //-----------------------------------------------------------------------------
2965 void Chuck_Instr_Assign_Primitive4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2967 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2969 // pop word from reg stack
2970 pop_( reg_sp, 5 );
2971 // copy popped value into mem stack
2972 *( (t_CKCOMPLEX*)(*(reg_sp+4)) ) = *(t_CKCOMPLEX *)reg_sp;
2974 t_CKCOMPLEX *& sp_complex = (t_CKCOMPLEX *&)reg_sp;
2975 push_( sp_complex, *sp_complex );
2981 //-----------------------------------------------------------------------------
2982 // name: execute()
2983 // desc: assign object with reference counting and releasing previous reference
2984 //-----------------------------------------------------------------------------
2985 void Chuck_Instr_Assign_Object::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2987 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2988 Chuck_VM_Object ** obj = NULL, * done = NULL;
2990 // pop word from reg stack
2991 pop_( reg_sp, 2 );
2992 // the previous reference
2993 obj = (Chuck_VM_Object **)(*(reg_sp+1));
2994 // save the reference (release should come after, in case same object)
2995 done = *obj;
2996 // copy popped value into memory
2997 *obj = (Chuck_VM_Object *)(*(reg_sp));
2998 // add reference
2999 if( *obj ) (*obj)->add_ref();
3000 // release
3001 if( done ) done->release();
3003 // copy
3004 // memcpy( (void *)*(reg_sp+1), *obj, sizeof(t_CKUINT) );
3005 // push the reference value to reg stack
3006 push_( reg_sp, (t_CKUINT)*obj );
3012 //-----------------------------------------------------------------------------
3013 // name: execute()
3014 // desc: assign string
3015 //-----------------------------------------------------------------------------
3016 void Chuck_Instr_Assign_String::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3018 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3019 Chuck_String * lhs = NULL;
3020 Chuck_String ** rhs_ptr = NULL;
3022 // pop word from reg stack
3023 pop_( reg_sp, 2 );
3024 // the previous reference
3025 rhs_ptr = (Chuck_String **)(*(reg_sp+1));
3026 // copy popped value into memory
3027 lhs = (Chuck_String *)(*(reg_sp));
3028 // release any previous reference
3029 if( *rhs_ptr )
3031 if( lhs ) (*rhs_ptr)->str = lhs->str;
3032 else
3034 // release reference
3035 (*rhs_ptr)->release();
3036 (*rhs_ptr) = NULL;
3039 else
3041 // if left is not null, yes
3042 if( lhs != NULL )
3044 (*rhs_ptr) = (Chuck_String *)instantiate_and_initialize_object( &t_string, shred );
3045 // add ref
3046 (*rhs_ptr)->add_ref();
3047 (*rhs_ptr)->str = lhs->str;
3049 //EM_error2( 0, "internal error: somehow the type checker has allowed NULL strings" );
3050 //EM_error2( 0, "we are sorry for the inconvenience but..." );
3051 //EM_error2( 0, "we have to crash now. Thanks." );
3052 //assert( FALSE );
3055 // copy
3056 // memcpy( (void *)*(reg_sp+1), *obj, sizeof(t_CKUINT) );
3057 // push the reference value to reg stack
3058 push_( reg_sp, (t_CKUINT)*rhs_ptr );
3064 //-----------------------------------------------------------------------------
3065 // name: execute()
3066 // desc: release one reference on object
3067 //-----------------------------------------------------------------------------
3068 void Chuck_Instr_Chuck_Release_Object::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3070 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
3071 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3072 Chuck_VM_Object * obj = NULL;
3074 // pop word from reg stack
3075 pop_( reg_sp, 1 );
3076 // copy popped value into mem stack
3077 obj = *( (Chuck_VM_Object **)(mem_sp + *(reg_sp)) );
3078 // release
3079 obj->release();
3085 //-----------------------------------------------------------------------------
3086 // name: execute()
3087 // desc: ...
3088 //-----------------------------------------------------------------------------
3089 void Chuck_Instr_Func_To_Code::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3091 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3093 // get func
3094 Chuck_Func * func = (Chuck_Func *)*(reg_sp-1);
3095 // make sure
3096 assert( func != NULL );
3097 // code
3098 *(reg_sp-1) = (t_CKUINT)func->code;
3104 //-----------------------------------------------------------------------------
3105 // name: execute()
3106 // desc: ...
3107 //-----------------------------------------------------------------------------
3108 void Chuck_Instr_Func_Call::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3110 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3111 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3113 // pop word
3114 pop_( reg_sp, 2 );
3115 // get the function to be called as code
3116 Chuck_VM_Code * func = (Chuck_VM_Code *)*reg_sp;
3117 // get the local stack depth - caller local variables
3118 t_CKUINT local_depth = *(reg_sp+1);
3119 // convert to number of 4-byte words, extra partial word counts as additional word
3120 local_depth = ( local_depth >> 2 ) + ( local_depth & 0x3 ? 1 : 0 );
3121 // get the stack depth of the callee function args
3122 t_CKUINT stack_depth = ( func->stack_depth >> 2 ) + ( func->stack_depth & 0x3 ? 1 : 0 );
3123 // get the previous stack depth - caller function args
3124 t_CKUINT prev_stack = ( *(mem_sp-1) >> 2 ) + ( *(mem_sp-1) & 0x3 ? 1 : 0 );
3126 // jump the sp
3127 mem_sp += prev_stack + local_depth;
3128 // push the prev stack
3129 push_( mem_sp, prev_stack + local_depth );
3130 // push the current function
3131 push_( mem_sp, (t_CKUINT)shred->code );
3132 // push the pc
3133 push_( mem_sp, (t_CKUINT)(shred->pc + 1) );
3134 // push the stack depth
3135 push_( mem_sp, stack_depth );
3136 // set the pc to 0
3137 shred->next_pc = 0;
3138 // set the code
3139 shred->code = func;
3140 // set the instruction to the function instruction
3141 shred->instr = func->instr;
3143 // if there are arguments to be passed
3144 if( stack_depth )
3146 // pop the arguments, by number of words
3147 pop_( reg_sp, stack_depth );
3149 // make copies
3150 t_CKUINT * mem_sp2 = (t_CKUINT *)mem_sp;
3151 t_CKUINT * reg_sp2 = (t_CKUINT *)reg_sp;
3153 // need this
3154 if( func->need_this )
3156 // copy this from end of arguments to the front
3157 *mem_sp2++ = *(reg_sp2 + stack_depth - 1);
3158 // one less word to copy
3159 stack_depth--;
3162 // push the arguments
3163 for( t_CKUINT i = 0; i < stack_depth; i++ )
3164 *mem_sp2++ = *reg_sp2++;
3167 // detect overflow/underflow
3168 if( overflow_( shred->mem ) ) goto error_overflow;
3170 return;
3172 error_overflow:
3174 handle_overflow( shred, vm );
3180 //-----------------------------------------------------------------------------
3181 // name: execute()
3182 // desc: imported member function call with return
3183 //-----------------------------------------------------------------------------
3184 void Chuck_Instr_Func_Call_Member::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3186 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3187 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3188 Chuck_DL_Return retval;
3190 // pop word
3191 pop_( reg_sp, 2 );
3192 // get the function to be called as code
3193 Chuck_VM_Code * func = (Chuck_VM_Code *)*reg_sp;
3194 // get the function to be called
3195 // MOVED TO BELOW: f_mfun f = (f_mfun)func->native_func;
3196 // get the local stack depth - caller local variables
3197 t_CKUINT local_depth = *(reg_sp+1);
3198 // convert to number of 4-byte words, extra partial word counts as additional word
3199 local_depth = ( local_depth >> 2 ) + ( local_depth & 0x3 ? 1 : 0 );
3200 // get the stack depth of the callee function args
3201 t_CKUINT stack_depth = ( func->stack_depth >> 2 ) + ( func->stack_depth & 0x3 ? 1 : 0 );
3202 // UNUSED: get the previous stack depth - caller function args
3203 // UNUSED: t_CKUINT prev_stack = ( *(mem_sp-1) >> 2 ) + ( *(mem_sp-1) & 0x3 ? 1 : 0 );
3204 // the amount to push in 4-byte words
3205 t_CKUINT push = local_depth;
3206 // push the mem stack passed the current function variables and arguments
3207 mem_sp += push;
3209 // pass args
3210 if( stack_depth )
3212 // pop the arguments for pass to callee function
3213 reg_sp -= stack_depth;
3215 // make copies
3216 t_CKUINT * reg_sp2 = reg_sp;
3217 t_CKUINT * mem_sp2 = mem_sp;
3219 // need this
3220 if( func->need_this )
3222 // copy this from end of arguments to the front
3223 *mem_sp2++ = *(reg_sp2 + stack_depth - 1);
3224 // one less word to copy
3225 stack_depth--;
3227 // copy to args
3228 for( t_CKUINT i = 0; i < stack_depth; i++ )
3229 *mem_sp2++ = *reg_sp2++;
3232 // detect overflow/underflow
3233 if( overflow_( shred->mem ) ) goto error_overflow;
3235 // check the type
3236 if( func->native_func_type == Chuck_VM_Code::NATIVE_CTOR )
3238 // cast to right type
3239 f_ctor f = (f_ctor)func->native_func;
3240 // call
3241 f( (Chuck_Object *)(*mem_sp), mem_sp + 1, shred );
3243 else
3245 // cast to right type
3246 f_mfun f = (f_mfun)func->native_func;
3247 // call the function
3248 f( (Chuck_Object *)(*mem_sp), mem_sp + 1, &retval, shred );
3250 // pop (TODO: check if this is right)
3251 mem_sp -= push;
3253 // push the return
3254 if( m_val == 4 ) // ISSUE: 64-bit
3256 // push the return args
3257 push_( reg_sp, retval.v_uint );
3259 else if( m_val == 8 ) // ISSUE: 64-bit
3261 // push the return args
3262 t_CKFLOAT *& sp_double = (t_CKFLOAT *&)reg_sp;
3263 push_( sp_double, retval.v_float );
3265 else if( m_val == 16 ) // ISSUE: 64-bit
3267 // push the return args
3268 t_CKCOMPLEX *& sp_complex = (t_CKCOMPLEX *&)reg_sp;
3269 // TODO: polar same?
3270 push_( sp_complex, retval.v_complex );
3272 else if( m_val == 0 ) { }
3273 else assert( FALSE );
3275 return;
3277 error_overflow:
3279 handle_overflow( shred, vm );
3285 //-----------------------------------------------------------------------------
3286 // name: execute()
3287 // desc: imported static function call with return
3288 //-----------------------------------------------------------------------------
3289 void Chuck_Instr_Func_Call_Static::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3291 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3292 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3293 Chuck_DL_Return retval;
3295 // pop word
3296 pop_( reg_sp, 2 );
3297 // get the function to be called as code
3298 Chuck_VM_Code * func = (Chuck_VM_Code *)*reg_sp;
3299 // get the function to be called
3300 f_sfun f = (f_sfun)func->native_func;
3301 // get the local stack depth - caller local variables
3302 t_CKUINT local_depth = *(reg_sp+1);
3303 // convert to number of 4-byte words, extra partial word counts as additional word
3304 local_depth = ( local_depth >> 2 ) + ( local_depth & 0x3 ? 1 : 0 );
3305 // get the stack depth of the callee function args
3306 t_CKUINT stack_depth = ( func->stack_depth >> 2 ) + ( func->stack_depth & 0x3 ? 1 : 0 );
3307 // UNUSED: get the previous stack depth - caller function args
3308 // UNUSED: t_CKUINT prev_stack = ( *(mem_sp-1) >> 2 ) + ( *(mem_sp-1) & 0x3 ? 1 : 0 );
3309 // the amount to push in 4-byte words
3310 t_CKUINT push = local_depth;
3311 // push the mem stack passed the current function variables and arguments
3312 mem_sp += push;
3314 // pass args
3315 if( stack_depth )
3317 // pop the arguments for pass to callee function
3318 reg_sp -= stack_depth;
3320 // make copies
3321 t_CKUINT * reg_sp2 = reg_sp;
3322 t_CKUINT * mem_sp2 = mem_sp;
3324 // need this
3325 if( func->need_this )
3327 // copy this from end of arguments to the front
3328 *mem_sp2++ = *(reg_sp2 + stack_depth - 1);
3329 // advance reg pointer
3330 reg_sp2++;
3331 // one less word to copy
3332 stack_depth--;
3334 // copy to args
3335 for( t_CKUINT i = 0; i < stack_depth; i++ )
3336 *mem_sp2++ = *reg_sp2++;
3339 // detect overflow/underflow
3340 if( overflow_( shred->mem ) ) goto error_overflow;
3342 // call the function
3343 f( mem_sp, &retval, shred );
3344 mem_sp -= push;
3346 // push the return
3347 if( m_val == 4 ) // ISSUE: 64-bit
3349 // push the return args
3350 push_( reg_sp, retval.v_uint );
3352 else if( m_val == 8 ) // ISSUE: 64-bit
3354 // push the return args
3355 t_CKFLOAT *& sp_double = (t_CKFLOAT *&)reg_sp;
3356 push_( sp_double, retval.v_float );
3358 else if( m_val == 16 ) // ISSUE: 64-bit
3360 // push the return args
3361 t_CKCOMPLEX *& sp_complex = (t_CKCOMPLEX *&)reg_sp;
3362 // TODO: polar same?
3363 push_( sp_complex, retval.v_complex );
3365 else if( m_val == 0 ) { }
3366 else assert( FALSE );
3368 return;
3370 error_overflow:
3372 handle_overflow( shred, vm );
3378 //-----------------------------------------------------------------------------
3379 // name: execute()
3380 // desc: ...
3381 //-----------------------------------------------------------------------------
3382 void Chuck_Instr_Func_Return::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3384 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3385 // UNUSED: t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3387 // pop pc
3388 pop_( mem_sp, 2 );
3389 shred->next_pc = *mem_sp;
3390 // pop the code
3391 pop_( mem_sp, 1 );
3392 Chuck_VM_Code * func = (Chuck_VM_Code *)*mem_sp;
3393 // pop the prev_stack
3394 pop_( mem_sp, 1 );
3395 // jump the prev stack
3396 mem_sp -= *(mem_sp);
3398 // set the shred
3399 shred->code = func;
3400 shred->instr = func->instr;
3406 //-----------------------------------------------------------------------------
3407 // name: execute()
3408 // desc: ...
3409 //-----------------------------------------------------------------------------
3410 void Chuck_Instr_Spork::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3412 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3413 t_CKUINT this_ptr = 0;
3415 // pop the stack
3416 pop_( reg_sp, 1 );
3417 // get the code
3418 Chuck_VM_Code * code = *(Chuck_VM_Code **)reg_sp;
3419 // spork it
3420 Chuck_VM_Shred * sh = vm->spork( code, shred );
3421 // pop the stack
3422 pop_( reg_sp, 1 );
3423 // get the func
3424 Chuck_Func * func = (Chuck_Func *)(*reg_sp);
3425 // need this?
3426 if( func->is_member )
3428 // pop the stack
3429 pop_( reg_sp, 1 );
3430 // get this
3431 this_ptr = *reg_sp;
3433 // copy args
3434 if( m_val )
3436 pop_( shred->reg->sp, m_val );
3437 memcpy( sh->reg->sp, shred->reg->sp, m_val );
3438 sh->reg->sp += m_val;
3440 // copy this, if need
3441 if( func->is_member )
3443 push_( (t_CKUINT*&)sh->reg->sp, this_ptr );
3445 // copy func
3446 push_( (t_CKUINT*&)sh->reg->sp, (t_CKUINT)func );
3447 // push the stack
3448 push_( reg_sp, (t_CKUINT)sh );
3454 //-----------------------------------------------------------------------------
3455 // name: execute()
3456 // desc: ...
3457 //-----------------------------------------------------------------------------
3458 void Chuck_Instr_Time_Advance::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3460 t_CKTIME *& sp = (t_CKTIME *&)shred->reg->sp;
3462 // pop word from reg stack
3463 pop_( sp, 1 );
3465 if( *sp < shred->now )
3467 // we have a problem
3468 fprintf( stderr,
3469 "[chuck](VM): DestTimeNegativeException: '%.6f' in shred[id=%d:%s], PC=[%d]\n",
3470 *sp, shred->xid, shred->name.c_str(), shred->pc );
3471 // do something!
3472 shred->is_running = FALSE;
3473 shred->is_done = TRUE;
3475 return;
3478 // shredule the shred
3479 vm->shreduler()->shredule( shred, *sp );
3480 // suspend
3481 shred->is_running = FALSE;
3483 // track time advance
3484 CK_TRACK( Chuck_Stats::instance()->advance_time( shred, *sp ) );
3486 push_( sp, *sp );
3492 //-----------------------------------------------------------------------------
3493 // name: execute()
3494 // desc: ...
3495 //-----------------------------------------------------------------------------
3496 void Chuck_Instr_Event_Wait::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3498 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
3500 // pop word from reg stack
3501 pop_( sp, 1 );
3503 Chuck_Event * event = (Chuck_Event *)(*sp);
3505 // check for null
3506 if( !event ) goto null_pointer;
3508 // wait
3509 event->wait( shred, vm );
3511 return;
3513 null_pointer:
3514 // we have a problem
3515 fprintf( stderr,
3516 "[chuck](VM): NullPointerException: (null Event wait) in shred[id=%d:%s], PC=[%d]\n",
3517 shred->xid, shred->name.c_str(), shred->pc );
3518 goto done;
3520 done:
3521 // do something!
3522 shred->is_running = FALSE;
3523 shred->is_done = TRUE;
3529 //-----------------------------------------------------------------------------
3530 // name: Chuck_Instr_Array_Init()
3531 // desc: ...
3532 //-----------------------------------------------------------------------------
3533 Chuck_Instr_Array_Init::Chuck_Instr_Array_Init( Chuck_Type * t, t_CKINT length )
3535 // set
3536 m_length = length;
3537 // copy
3538 m_type_ref = t;
3539 // TODO: do this? remember?
3540 // m_type_ref->add_ref();
3541 // type
3542 m_param_str = new char[64];
3543 // obj
3544 m_is_obj = isobj( m_type_ref );
3545 const char * str = m_type_ref->c_name();
3546 t_CKUINT len = strlen( str );
3547 // copy
3548 if( len < 45 )
3549 strcpy( m_param_str, str );
3550 else
3552 strncpy( m_param_str, str, 45 );
3553 strcpy( m_param_str + 45, "..." );
3556 // append length
3557 char buffer[16];
3558 sprintf( buffer, "[%ld]", m_length );
3559 strcat( m_param_str, buffer );
3565 //-----------------------------------------------------------------------------
3566 // name: ~Chuck_Instr_Array_Init()
3567 // desc: ...
3568 //-----------------------------------------------------------------------------
3569 Chuck_Instr_Array_Init::~Chuck_Instr_Array_Init()
3571 // delete
3572 delete [] m_param_str;
3573 m_param_str = NULL;
3574 // release
3575 //m_type_ref->release();
3576 m_type_ref = NULL;
3582 //-----------------------------------------------------------------------------
3583 // name: execute()
3584 // desc: ...
3585 //-----------------------------------------------------------------------------
3586 void Chuck_Instr_Array_Init::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3588 // reg stack pointer
3589 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3591 // allocate the array
3592 if( m_type_ref->size == 4 ) // ISSUE: 64-bit
3594 // pop the values
3595 pop_( reg_sp, m_length );
3596 // instantiate array
3597 Chuck_Array4 * array = new Chuck_Array4( m_is_obj, m_length );
3598 // problem
3599 if( !array ) goto out_of_memory;
3600 // initialize object
3601 initialize_object( array, &t_array );
3602 // set size
3603 array->set_size( m_length );
3604 // fill array
3605 for( t_CKINT i = 0; i < m_length; i++ )
3606 array->set( i, *(reg_sp + i) );
3607 // push the pointer
3608 push_( reg_sp, (t_CKUINT)array );
3610 else if( m_type_ref->size == 8 ) // ISSUE: 64-bit
3612 // pop the values
3613 pop_( reg_sp, 2 * m_length );
3614 // instantiate array
3615 Chuck_Array8 * array = new Chuck_Array8( m_length );
3616 // problem
3617 if( !array ) goto out_of_memory;
3618 // fill array
3619 t_CKFLOAT * sp = (t_CKFLOAT *)reg_sp;
3620 // intialize object
3621 initialize_object( array, &t_array );
3622 // set size
3623 array->set_size( m_length );
3624 // fill array
3625 for( t_CKINT i = 0; i < m_length; i++ )
3626 array->set( i, *(sp + i) );
3627 // push the pointer
3628 push_( reg_sp, (t_CKUINT)array );
3630 else if( m_type_ref->size == 16 ) // ISSUE: 64-bit
3632 // pop the values
3633 pop_( reg_sp, 4 * m_length );
3634 // instantiate array
3635 Chuck_Array16 * array = new Chuck_Array16( m_length );
3636 // problem
3637 if( !array ) goto out_of_memory;
3638 // fill array
3639 t_CKCOMPLEX * sp = (t_CKCOMPLEX *)reg_sp;
3640 // intialize object
3641 initialize_object( array, &t_array );
3642 // set size
3643 array->set_size( m_length );
3644 // fill array
3645 for( t_CKINT i = 0; i < m_length; i++ )
3646 array->set( i, *(sp + i) );
3647 // push the pointer
3648 push_( reg_sp, (t_CKUINT)array );
3650 else assert( FALSE );
3652 return;
3654 out_of_memory:
3656 // we have a problem
3657 fprintf( stderr,
3658 "[chuck](VM): OutOfMemory: while initializing arrays\n" );
3660 // do something!
3661 shred->is_running = FALSE;
3662 shred->is_done = TRUE;
3668 //-----------------------------------------------------------------------------
3669 // name: Chuck_Instr_Array_Alloc()
3670 // desc: ...
3671 //-----------------------------------------------------------------------------
3672 Chuck_Instr_Array_Alloc::Chuck_Instr_Array_Alloc( t_CKUINT depth, Chuck_Type * t,
3673 t_CKUINT offset, t_CKBOOL is_ref )
3675 // set
3676 m_depth = depth;
3677 // copy
3678 m_type_ref = t;
3679 // remember
3680 // m_type_ref->add_ref();
3681 // type
3682 m_param_str = new char[64];
3683 // obj
3684 m_is_obj = isobj( m_type_ref );
3685 // offset for pre constructor
3686 m_stack_offset = offset;
3687 // is object ref
3688 m_is_ref = is_ref;
3689 const char * str = m_type_ref->c_name();
3690 t_CKUINT len = strlen( str );
3691 // copy
3692 if( len < 64 )
3693 strcpy( m_param_str, str );
3694 else
3696 strncpy( m_param_str, str, 60 );
3697 strcpy( m_param_str + 60, "..." );
3704 //-----------------------------------------------------------------------------
3705 // name: ~Chuck_Instr_Array_Alloc()
3706 // desc: ...
3707 //-----------------------------------------------------------------------------
3708 Chuck_Instr_Array_Alloc::~Chuck_Instr_Array_Alloc()
3710 // delete
3711 delete [] m_param_str;
3712 m_param_str = NULL;
3713 // release
3714 //m_type_ref->release();
3715 m_type_ref = NULL;
3721 //-----------------------------------------------------------------------------
3722 // name: do_alloc_array()
3723 // desc: ...
3724 //-----------------------------------------------------------------------------
3725 Chuck_Object * do_alloc_array( t_CKINT * capacity, const t_CKINT * top,
3726 t_CKUINT size, t_CKBOOL is_obj,
3727 t_CKUINT * objs, t_CKINT & index )
3729 // not top level
3730 Chuck_Array4 * base = NULL;
3731 Chuck_Object * next = NULL;
3732 t_CKINT i = 0;
3734 // capacity
3735 if( *capacity < 0 ) goto negative_array_size;
3737 // see if top level
3738 if( capacity >= top )
3740 // check size
3741 if( size == 4 ) // ISSUE: 64-bit
3743 Chuck_Array4 * base = new Chuck_Array4( is_obj, *capacity );
3744 if( !base ) goto out_of_memory;
3746 // if object
3747 if( is_obj && objs )
3749 // loop
3750 for( i = 0; i < *capacity; i++ )
3752 // add to array for later allocation
3753 objs[index++] = base->addr( i );
3757 // initialize object
3758 initialize_object( base, &t_array );
3759 return base;
3761 else if( size == 8 ) // ISSUE: 64-bit
3763 Chuck_Array8 * base = new Chuck_Array8( *capacity );
3764 if( !base ) goto out_of_memory;
3766 // initialize object
3767 initialize_object( base, &t_array );
3768 return base;
3770 else if( size == 16 ) // ISSUE: 64-bit
3772 Chuck_Array16 * base = new Chuck_Array16( *capacity );
3773 if( !base ) goto out_of_memory;
3775 // initialize object
3776 initialize_object( base, &t_array );
3777 return base;
3780 // shouldn't get here
3781 assert( FALSE );
3784 // not top level
3785 base = new Chuck_Array4( TRUE, *capacity );
3786 if( !base ) goto out_of_memory;
3788 // allocate the next level
3789 for( i = 0; i < *capacity; i++ )
3791 // the next
3792 next = do_alloc_array( capacity+1, top, size, is_obj, objs, index );
3793 // error if NULL
3794 if( !next ) goto error;
3795 // set that, with ref count
3796 base->set( i, (t_CKUINT)next );
3799 // initialize object
3800 initialize_object( base, &t_array );
3801 return base;
3803 out_of_memory:
3804 // we have a problem
3805 fprintf( stderr,
3806 "[chuck](VM): OutOfMemory: while allocating arrays...\n" );
3807 goto error;
3809 negative_array_size:
3810 // we have a problem
3811 fprintf( stderr,
3812 "[chuck](VM): NegativeArraySize: while allocating arrays...\n" );
3813 goto error;
3815 error:
3816 // base shouldn't have been ref counted
3817 SAFE_DELETE( base );
3818 return NULL;
3824 //-----------------------------------------------------------------------------
3825 // name: execute()
3826 // desc: ...
3827 //-----------------------------------------------------------------------------
3828 void Chuck_Instr_Array_Alloc::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3830 // reg stack pointer
3831 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3832 // ref
3833 t_CKUINT ref = 0;
3834 // the total number of objects to allocate
3835 t_CKUINT num_obj = 0;
3836 // the index to pass to the arrays
3837 t_CKINT index = 0;
3838 // number
3839 t_CKFLOAT num = 1.0;
3840 // array
3841 t_CKUINT * obj_array = NULL;
3842 // size
3843 t_CKUINT obj_array_size = 0;
3845 // if need instantiation
3846 if( m_is_obj && !m_is_ref )
3848 t_CKINT * curr = (t_CKINT *)(reg_sp - m_depth);
3849 t_CKINT * top = (t_CKINT *)(reg_sp - 1);
3851 num_obj = 1;
3852 num = 1.0;
3853 // product of all dims
3854 while( curr <= top )
3856 num_obj *= *(curr);
3858 // overflow
3859 num *= (t_CKFLOAT)(*(curr));
3860 if( num > (t_CKFLOAT)INT_MAX ) goto overflow;
3862 curr++;
3865 // allocate array to hold elements, this array
3866 // is pushed on the reg stack, filled, and cleaned
3867 // during the array_post stage
3868 // ----
3869 // TODO: this scheme results in potential leak
3870 // if intermediate memory allocations fail
3871 // and the array instantiation is aborted
3872 if( num_obj > 0 )
3874 obj_array = new t_CKUINT[num_obj];
3875 if( !obj_array ) goto out_of_memory;
3876 obj_array_size = num_obj;
3879 // check to see if we need to allocate
3880 // if( num_obj > shred->obj_array_size )
3881 // {
3882 // SAFE_DELETE( shred->obj_array );
3883 // shred->obj_array_size = 0;
3884 // shred->obj_array = new t_CKUINT[num_obj];
3885 // if( !shred->obj_array ) goto out_of_memory;
3886 // shred->obj_array_size = num_obj;
3887 // }
3890 // recursively allocate
3891 ref = (t_CKUINT)do_alloc_array(
3892 (t_CKINT *)(reg_sp - m_depth),
3893 (t_CKINT *)(reg_sp - 1),
3894 m_type_ref->size,
3895 m_is_obj,
3896 obj_array, index
3899 // pop the indices - this protects the contents of the stack
3900 // do_alloc_array writes stuff to the stack
3901 pop_( reg_sp, m_depth );
3903 // make sure
3904 assert( index == (t_CKINT)num_obj );
3906 // problem
3907 if( !ref ) goto error;
3909 // push array
3910 push_( reg_sp, ref );
3912 // if need to instantiate
3913 if( m_is_obj && !m_is_ref )
3915 // push objects to instantiate
3916 push_( reg_sp, (t_CKUINT)obj_array );
3917 // push index to use
3918 push_( reg_sp, 0 );
3919 // push size
3920 push_( reg_sp, (t_CKUINT)num_obj );
3923 return;
3925 overflow:
3926 // we have a problem
3927 fprintf( stderr,
3928 "[chuck](VM): OverFlow: requested array size too big...\n" );
3929 goto error;
3931 out_of_memory:
3932 // we have a problem
3933 fprintf( stderr,
3934 "[chuck](VM): OutOfMemory: while allocating arrays...\n" );
3935 goto error;
3937 error:
3938 fprintf( stderr,
3939 "[chuck](VM): (note: in shred[id=%d:%s])\n", shred->xid, shred->name.c_str() );
3941 // done
3942 shred->is_running = FALSE;
3943 shred->is_done = TRUE;
3947 //-----------------------------------------------------------------------------
3948 // name: execute()
3949 // desc: ...
3950 //-----------------------------------------------------------------------------
3951 void Chuck_Instr_Array_Access::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3953 // reg stack pointer
3954 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
3955 // UNUSED: t_CKUINT *& reg_sp = sp;
3956 t_CKINT i = 0;
3957 t_CKUINT val = 0;
3958 t_CKFLOAT fval = 0;
3959 t_CKCOMPLEX cval;
3960 cval.re = 0;
3961 cval.im = 0;
3963 // pop
3964 pop_( sp, 2 );
3966 // check pointer
3967 if( !(*sp) ) goto null_pointer;
3969 // 4 or 8 or 16
3970 if( m_size == 4 ) // ISSUE: 64-bit
3972 // get array
3973 Chuck_Array4 * arr = (Chuck_Array4 *)(*sp);
3974 // get index
3975 i = (t_CKINT)(*(sp+1));
3976 // check if writing
3977 if( m_emit_addr ) {
3978 // get the addr
3979 val = arr->addr( i );
3980 // exception
3981 if( !val ) goto array_out_of_bound;
3982 // push the addr
3983 push_( sp, val );
3984 } else {
3985 // get the value
3986 if( !arr->get( i, &val ) )
3987 goto array_out_of_bound;
3988 // push the value
3989 push_( sp, val );
3992 else if( m_size == 8 ) // ISSUE: 64-bit
3994 // get array
3995 Chuck_Array8 * arr = (Chuck_Array8 *)(*sp);
3996 // get index
3997 i = (t_CKINT)(*(sp+1));
3998 // check if writing
3999 if( m_emit_addr ) {
4000 // get the addr
4001 val = arr->addr( i );
4002 // exception
4003 if( !val ) goto array_out_of_bound;
4004 // push the addr
4005 push_( sp, val );
4006 } else {
4007 // get the value
4008 if( !arr->get( i, &fval ) )
4009 goto array_out_of_bound;
4010 // push the value
4011 push_( ((t_CKFLOAT *&)sp), fval );
4014 else if( m_size == 16 ) // ISSUE: 64-bit
4016 // get array
4017 Chuck_Array16 * arr = (Chuck_Array16 *)(*sp);
4018 // get index
4019 i = (t_CKINT)(*(sp+1));
4020 // check if writing
4021 if( m_emit_addr ) {
4022 // get the addr
4023 val = arr->addr( i );
4024 // exception
4025 if( !val ) goto array_out_of_bound;
4026 // push the addr
4027 push_( sp, val );
4028 } else {
4029 // get the value
4030 if( !arr->get( i, &cval ) )
4031 goto array_out_of_bound;
4032 // push the value
4033 push_( ((t_CKCOMPLEX *&)sp), cval );
4036 else
4037 assert( FALSE );
4039 return;
4041 null_pointer:
4042 // we have a problem
4043 fprintf( stderr,
4044 "[chuck](VM): NullPointerException: (array access) in shred[id=%d:%s], PC=[%d]\n",
4045 shred->xid, shred->name.c_str(), shred->pc );
4046 goto done;
4048 array_out_of_bound:
4049 // we have a problem
4050 fprintf( stderr,
4051 "[chuck](VM): ArrayOutofBounds: in shred[id=%d:%s], PC=[%d], index=[%d]\n",
4052 shred->xid, shred->name.c_str(), shred->pc, i );
4053 // go to done
4054 goto done;
4056 done:
4057 // do something!
4058 shred->is_running = FALSE;
4059 shred->is_done = TRUE;
4065 //-----------------------------------------------------------------------------
4066 // name: execute()
4067 // desc: ...
4068 //-----------------------------------------------------------------------------
4069 void Chuck_Instr_Array_Map_Access::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4071 // reg stack pointer
4072 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4073 Chuck_String * key = NULL;
4074 t_CKUINT val = 0;
4075 t_CKFLOAT fval = 0;
4076 t_CKCOMPLEX cval;
4077 cval.re = 0;
4078 cval.im = 0;
4080 // pop
4081 pop_( sp, 2 );
4083 // check pointer
4084 if( !(*sp) ) goto null_pointer;
4086 // 4 or 8 or 16
4087 if( m_size == 4 ) // ISSUE: 64-bit
4089 // get array
4090 Chuck_Array4 * arr = (Chuck_Array4 *)(*sp);
4091 // get index
4092 key = (Chuck_String *)(*(sp+1));
4093 // check if writing
4094 if( m_emit_addr ) {
4095 // get the addr
4096 val = arr->addr( key->str );
4097 // exception
4098 if( !val ) goto error;
4099 // push the addr
4100 push_( sp, val );
4101 } else {
4102 // get the value
4103 if( !arr->get( key->str, &val ) )
4104 goto error;
4105 // push the value
4106 push_( sp, val );
4109 else if( m_size == 8 ) // ISSUE: 64-bit
4111 // get array
4112 Chuck_Array8 * arr = (Chuck_Array8 *)(*sp);
4113 // get index
4114 key = (Chuck_String *)(*(sp+1));
4115 // check if writing
4116 if( m_emit_addr ) {
4117 // get the addr
4118 val = arr->addr( key->str );
4119 // exception
4120 if( !val ) goto error;
4121 // push the addr
4122 push_( sp, val );
4123 } else {
4124 // get the value
4125 if( !arr->get( key->str, &fval ) )
4126 goto error;
4127 // push the value
4128 push_( ((t_CKFLOAT *&)sp), fval );
4131 else if( m_size == 16 ) // ISSUE: 64-bit
4133 // get array
4134 Chuck_Array16 * arr = (Chuck_Array16 *)(*sp);
4135 // get index
4136 key = (Chuck_String *)(*(sp+1));
4137 // check if writing
4138 if( m_emit_addr ) {
4139 // get the addr
4140 val = arr->addr( key->str );
4141 // exception
4142 if( !val ) goto error;
4143 // push the addr
4144 push_( sp, val );
4145 } else {
4146 // get the value
4147 if( !arr->get( key->str, &cval ) )
4148 goto error;
4149 // push the value
4150 push_( ((t_CKCOMPLEX *&)sp), cval );
4153 else
4154 assert( FALSE );
4156 return;
4158 null_pointer:
4159 // we have a problem
4160 fprintf( stderr,
4161 "[chuck](VM): NullPointerException: (map access) in shred[id=%d:%s], PC=[%d]\n",
4162 shred->xid, shred->name.c_str(), shred->pc );
4163 goto done;
4165 error:
4166 // we have a problem
4167 fprintf( stderr,
4168 "[chuck](VM): InternalArrayMap error: in shred[id=%d:%s], PC=[%d], index=[%s]\n",
4169 shred->xid, shred->name.c_str(), shred->pc, key->str.c_str() );
4170 goto done;
4172 done:
4173 // do something!
4174 shred->is_running = FALSE;
4175 shred->is_done = TRUE;
4181 //-----------------------------------------------------------------------------
4182 // name: execute()
4183 // desc: ...
4184 //-----------------------------------------------------------------------------
4185 void Chuck_Instr_Array_Access_Multi::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4187 // reg stack pointer
4188 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4189 t_CKINT i = 0;
4190 t_CKUINT val = 0, j;
4191 t_CKFLOAT fval = 0;
4192 t_CKCOMPLEX cval;
4193 t_CKINT * ptr = NULL;
4194 t_CKUINT index = 0;
4195 cval.re = 0;
4196 cval.im = 0;
4198 // pop all indices then array
4199 pop_( sp, m_depth + 1 );
4201 // get array
4202 Chuck_Array4 * base = (Chuck_Array4 *)(*sp);
4203 ptr = (t_CKINT *)(sp+1);
4205 // check for null
4206 if( !base ) goto null_pointer;
4208 // make sure
4209 assert( m_depth > 1 );
4210 // loop through indices
4211 for( j = 0; j < (m_depth-1); j++ )
4213 // get index
4214 i = *ptr++;
4215 // get the array
4216 if( !base->get( i, &val ) )
4217 goto array_out_of_bound;
4218 // set the array
4219 base = (Chuck_Array4 *)val;
4220 // check for null
4221 if( !base )
4223 // error
4224 index = j + 1;
4225 goto null_pointer;
4229 // 4 or 8 or 16
4230 if( m_size == 4 ) // ISSUE: 64-bit
4232 // get arry
4233 Chuck_Array4 * arr = base;
4234 // get index
4235 i = (t_CKINT)(*ptr);
4236 // check if writing
4237 if( m_emit_addr ) {
4238 // get the addr
4239 val = arr->addr( i );
4240 // exception
4241 if( !val ) goto array_out_of_bound;
4242 // push the addr
4243 push_( sp, val );
4244 } else {
4245 // get the value
4246 if( !arr->get( i, &val ) )
4247 goto array_out_of_bound;
4248 // push the value
4249 push_( sp, val );
4252 else if( m_size == 8 ) // ISSUE: 64-bit
4254 // get array
4255 Chuck_Array8 * arr = (Chuck_Array8 *)(base);
4256 // get index
4257 i = (t_CKINT)(*ptr);
4258 // check if writing
4259 if( m_emit_addr ) {
4260 // get the addr
4261 val = arr->addr( i );
4262 // exception
4263 if( !val ) goto array_out_of_bound;
4264 // push the addr
4265 push_( sp, val );
4266 } else {
4267 // get the value
4268 if( !arr->get( i, &fval ) )
4269 goto array_out_of_bound;
4270 // push the value
4271 push_( ((t_CKFLOAT *&)sp), fval );
4274 else if( m_size == 16 ) // ISSUE: 64-bit
4276 // get array
4277 Chuck_Array16 * arr = (Chuck_Array16 *)(base);
4278 // get index
4279 i = (t_CKINT)(*ptr);
4280 // check if writing
4281 if( m_emit_addr ) {
4282 // get the addr
4283 val = arr->addr( i );
4284 // exception
4285 if( !val ) goto array_out_of_bound;
4286 // push the addr
4287 push_( sp, val );
4288 } else {
4289 // get the value
4290 if( !arr->get( i, &cval ) )
4291 goto array_out_of_bound;
4292 // push the value
4293 push_( ((t_CKCOMPLEX *&)sp), cval );
4296 else
4297 assert( FALSE );
4299 return;
4301 null_pointer:
4302 // we have a problem
4303 fprintf( stderr,
4304 "[chuck](VM): NullPointerException: (array access) in shred[id=%d:%s], PC=[%d]\n",
4305 shred->xid, shred->name.c_str(), shred->pc );
4306 fprintf( stderr,
4307 "[chuck](VM): (array dimension where exception occurred: %d)\n", index );
4308 goto done;
4310 array_out_of_bound:
4311 // we have a problem
4312 fprintf( stderr,
4313 "[chuck](VM): ArrayOutofBounds: in shred[id=%d:%s], PC=[%d], index=[%d]\n",
4314 shred->xid, shred->name.c_str(), shred->pc, i );
4315 // go to done
4316 goto done;
4318 done:
4319 // do something!
4320 shred->is_running = FALSE;
4321 shred->is_done = TRUE;
4327 //-----------------------------------------------------------------------------
4328 // name: execute()
4329 // desc: ...
4330 //-----------------------------------------------------------------------------
4331 void Chuck_Instr_Array_Prepend::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4338 //-----------------------------------------------------------------------------
4339 // name: execute()
4340 // desc: ...
4341 //-----------------------------------------------------------------------------
4342 void Chuck_Instr_Array_Append::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4344 // reg stack pointer
4345 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4346 // t_CKINT i = 0;
4347 t_CKUINT val = 0;
4348 t_CKFLOAT fval = 0;
4349 t_CKCOMPLEX cval;
4350 cval.re = 0;
4351 cval.im = 0;
4353 // pop
4354 pop_( sp, 1+(m_val/4) );
4356 // check pointer
4357 if( !(*sp) ) goto null_pointer;
4359 // 4 or 8 or 16
4360 if( m_val == 4 ) // ISSUE: 64-bit
4362 // get array
4363 Chuck_Array4 * arr = (Chuck_Array4 *)(*sp);
4364 // get value
4365 val = (t_CKINT)(*(sp+1));
4366 // append
4367 arr->push_back( val );
4369 else if( m_val == 8 ) // ISSUE: 64-bit
4371 // get array
4372 Chuck_Array8 * arr = (Chuck_Array8 *)(*sp);
4373 // get value
4374 fval = (*(t_CKFLOAT *)(sp+1));
4375 // append
4376 arr->push_back( fval );
4378 else if( m_val == 16 ) // ISSUE: 64-bit
4380 // get array
4381 Chuck_Array16 * arr = (Chuck_Array16 *)(*sp);
4382 // get value
4383 cval = (*(t_CKCOMPLEX *)(sp+1));
4384 // append
4385 arr->push_back( cval );
4387 else
4388 assert( FALSE );
4390 // push array back on stack
4391 push_( sp, (*sp) );
4393 return;
4395 null_pointer:
4396 // we have a problem
4397 fprintf( stderr,
4398 "[chuck](VM): NullPointerException: (array append) in shred[id=%d:%s], PC=[%d]\n",
4399 shred->xid, shred->name.c_str(), shred->pc );
4400 goto done;
4402 done:
4403 // do something!
4404 shred->is_running = FALSE;
4405 shred->is_done = TRUE;
4411 //-----------------------------------------------------------------------------
4412 // name: execute()
4413 // desc: ...
4414 //-----------------------------------------------------------------------------
4415 void Chuck_Instr_Dot_Member_Data::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4417 // register stack pointer
4418 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4419 // the pointer
4420 t_CKUINT data;
4422 // pop the object pointer
4423 pop_( sp, 1 );
4424 // get the object pointer
4425 Chuck_Object * obj = (Chuck_Object *)(*sp);
4426 // check
4427 if( !obj ) goto error;
4428 // calculate the data pointer
4429 data = (t_CKUINT)(obj->data + m_offset);
4431 // emit addr or value
4432 if( m_emit_addr )
4434 // push the address
4435 push_( sp, data );
4437 else
4439 // 4 or 8 or 16
4440 if( m_size == 4 ) { push_( sp, *((t_CKUINT *)data) ); } // ISSUE: 64-bit
4441 else if( m_size == 8 ) { push_float( sp, *((t_CKFLOAT *)data) ); } // ISSUE: 64-bit
4442 else if( m_size == 16 ) { push_complex( sp, *((t_CKCOMPLEX *)data) ); } // ISSUE: 64-bit // TODO: polar same?
4443 else assert( FALSE );
4446 return;
4448 error:
4449 // we have a problem
4450 fprintf( stderr,
4451 "[chuck](VM): NullPointerException: shred[id=%d:%s:(%d)], PC=[%d]\n",
4452 shred->xid, shred->name.c_str(), shred->pc );
4454 // do something!
4455 shred->is_running = FALSE;
4456 shred->is_done = TRUE;
4462 //-----------------------------------------------------------------------------
4463 // name: execute()
4464 // desc: ...
4465 //-----------------------------------------------------------------------------
4466 void Chuck_Instr_Dot_Member_Func::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4468 // register stack pointer
4469 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4470 // the pointer
4471 t_CKUINT data;
4473 // pop the object pointer
4474 pop_( sp, 1 );
4475 // get the object pointer
4476 Chuck_Object * obj = (Chuck_Object *)(*sp);
4477 // check
4478 if( !obj ) goto error;
4479 // make sure we are in range
4480 assert( m_offset < obj->vtable->funcs.size() );
4481 // calculate the data pointer
4482 data = (t_CKUINT)(obj->vtable->funcs[m_offset]);
4484 // push the address
4485 push_( sp, data );
4487 return;
4489 error:
4490 // we have a problem
4491 fprintf( stderr,
4492 "[chuck](VM): NullPointerException: shred[id=%d:%s], PC=[%d]\n",
4493 shred->xid, shred->name.c_str(), shred->pc );
4495 // do something!
4496 shred->is_running = FALSE;
4497 shred->is_done = TRUE;
4503 //-----------------------------------------------------------------------------
4504 // name: execute()
4505 // desc: ...
4506 //-----------------------------------------------------------------------------
4507 void Chuck_Instr_Dot_Static_Data::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4509 // register stack pointer
4510 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4511 // the pointer
4512 t_CKUINT data;
4514 // pop the type pointer
4515 pop_( sp, 1 );
4516 // get the object pointer
4517 Chuck_Type * t_class = (Chuck_Type *)(*sp);
4518 // make sure
4519 assert( (m_offset + m_size) <= t_class->info->class_data_size );
4520 // calculate the data pointer
4521 data = (t_CKUINT)(t_class->info->class_data + m_offset);
4523 // emit addr or value
4524 if( m_emit_addr )
4526 // push the address
4527 push_( sp, data );
4529 else
4531 // 4 or 8 or 16
4532 if( m_size == 4 ) { push_( sp, *((t_CKUINT *)data) ); } // ISSUE: 64-bit
4533 else if( m_size == 8 ) { push_float( sp, *((t_CKFLOAT *)data) ); } // ISSUE: 64-bit
4534 else if( m_size == 16 ) { push_complex( sp, *((t_CKCOMPLEX *)data) ); } // ISSUE: 64-bit // TODO: polar same?
4535 else assert( FALSE );
4542 //-----------------------------------------------------------------------------
4543 // name: execute()
4544 // desc: ...
4545 //-----------------------------------------------------------------------------
4546 void Chuck_Instr_Dot_Static_Import_Data::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4548 // register stack pointer
4549 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4551 // emit addr or value
4552 if( m_emit_addr )
4554 // push the address
4555 push_( sp, (t_CKUINT)m_addr );
4557 else
4559 // 4 or 8 or 16
4560 if( m_size == 4 ) { push_( sp, *((t_CKUINT *)m_addr) ); } // ISSUE: 64-bit
4561 else if( m_size == 8 ) { push_float( sp, *((t_CKFLOAT *)m_addr) ); } // ISSUE: 64-bit
4562 else if( m_size == 16 ) { push_complex( sp, *((t_CKCOMPLEX *)m_addr) ); } // ISSUE: 64-bit // TODO: polar same?
4563 else assert( FALSE );
4570 //-----------------------------------------------------------------------------
4571 // name: execute()
4572 // desc: ...
4573 //-----------------------------------------------------------------------------
4574 void Chuck_Instr_Dot_Static_Func::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4576 // register stack pointer
4577 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4579 // pop the type pointer
4580 pop_( sp, 1 );
4582 // push the address
4583 push_( sp, (t_CKUINT)(m_func) );
4589 //-----------------------------------------------------------------------------
4590 // name: execute()
4591 // desc: ...
4592 //-----------------------------------------------------------------------------
4593 void Chuck_Instr_Dot_Cmp_First::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4595 // reg contains pointer to complex elsewhere
4596 if( m_is_mem )
4598 // stack
4599 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4600 // pop
4601 pop_( sp, 1 );
4602 // push the addr on
4603 if( m_emit_addr ) {
4604 // t_CKFLOAT a = (*(t_CKCOMPLEX **)sp)->re;
4605 push_( sp, (t_CKUINT)(&((*(t_CKCOMPLEX **)sp)->re)) );
4606 } else {
4607 push_float( sp, (*(t_CKCOMPLEX **)sp)->re );
4610 else
4612 // stack
4613 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
4614 // pop
4615 pop_( sp, 1 );
4616 // push the addr, um we can't
4617 if( m_emit_addr ) {
4618 assert( FALSE );
4619 } else {
4620 push_float( sp, sp->re );
4628 //-----------------------------------------------------------------------------
4629 // name: execute()
4630 // desc: ...
4631 //-----------------------------------------------------------------------------
4632 void Chuck_Instr_Dot_Cmp_Second::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4634 // reg contains pointer to complex elsewhere
4635 if( m_is_mem )
4637 // stack
4638 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4639 // pop
4640 pop_( sp, 1 );
4641 // push the addr on
4642 if( m_emit_addr ) {
4643 push_( sp, (t_CKUINT)(&((*(t_CKCOMPLEX **)sp)->im)) );
4644 } else {
4645 push_float( sp, (*(t_CKCOMPLEX **)sp)->im );
4648 else
4650 // stack
4651 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
4652 // pop
4653 pop_( sp, 1 );
4654 // push the addr, um we can't
4655 if( m_emit_addr ) {
4656 assert( FALSE );
4657 } else {
4658 push_float( sp, sp->im );
4666 //-----------------------------------------------------------------------------
4667 // name: execute()
4668 // desc: ...
4669 //-----------------------------------------------------------------------------
4670 void Chuck_Instr_Cast_double2int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4672 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
4673 t_CKINT *& sp_int = (t_CKINT *&)sp;
4674 pop_( sp, 1 );
4675 push_( sp_int, (t_CKINT)(*sp) );
4681 //-----------------------------------------------------------------------------
4682 // name: execute()
4683 // desc: ...
4684 //-----------------------------------------------------------------------------
4685 void Chuck_Instr_Cast_int2double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4687 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
4688 t_CKFLOAT *& sp_double = (t_CKFLOAT *&)sp;
4689 pop_( sp, 1 );
4690 push_( sp_double, (t_CKFLOAT)(*sp) );
4696 //-----------------------------------------------------------------------------
4697 // name: execute()
4698 // desc: ...
4699 //-----------------------------------------------------------------------------
4700 void Chuck_Instr_Cast_int2complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4702 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
4703 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
4704 pop_( sp, 1 );
4705 // push re and im
4706 push_( sp_float, (t_CKFLOAT)(*sp) );
4707 push_( sp_float, (t_CKFLOAT)0 );
4713 //-----------------------------------------------------------------------------
4714 // name: execute()
4715 // desc: ...
4716 //-----------------------------------------------------------------------------
4717 void Chuck_Instr_Cast_int2polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4719 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
4720 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
4721 pop_( sp, 1 );
4722 // push re and im
4723 push_( sp_float, (t_CKFLOAT)(*sp) );
4724 push_( sp_float, (t_CKFLOAT)0 );
4730 //-----------------------------------------------------------------------------
4731 // name: execute()
4732 // desc: ...
4733 //-----------------------------------------------------------------------------
4734 void Chuck_Instr_Cast_double2complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4736 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
4737 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
4738 // leave on stack and push 0
4739 push_( sp_float, (t_CKFLOAT)0 );
4745 //-----------------------------------------------------------------------------
4746 // name: execute()
4747 // desc: ...
4748 //-----------------------------------------------------------------------------
4749 void Chuck_Instr_Cast_double2polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4751 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
4752 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
4753 // leave on stack and push 0
4754 push_( sp_float, (t_CKFLOAT)0 );
4760 //-----------------------------------------------------------------------------
4761 // name: execute()
4762 // desc: ...
4763 //-----------------------------------------------------------------------------
4764 void Chuck_Instr_Cast_complex2polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4766 t_CKCOMPLEX * sp = (t_CKCOMPLEX *)shred->reg->sp;
4767 // find it
4768 sp--;
4769 t_CKPOLAR * sp_polar = (t_CKPOLAR *)sp;
4770 t_CKFLOAT modulus, phase;
4771 // leave on stack
4772 modulus = ::sqrt( sp->re*sp->re + sp->im*sp->im );
4773 phase = ::atan2( sp->im, sp->re );
4774 sp_polar->modulus = modulus;
4775 sp_polar->phase = phase;
4781 //-----------------------------------------------------------------------------
4782 // name: execute()
4783 // desc: ...
4784 //-----------------------------------------------------------------------------
4785 void Chuck_Instr_Cast_polar2complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4787 t_CKPOLAR * sp = (t_CKPOLAR *)shred->reg->sp;
4788 // find it
4789 sp--;
4790 t_CKCOMPLEX * sp_complex = (t_CKCOMPLEX *)sp;
4791 t_CKFLOAT re, im;
4792 // leave on stack
4793 re = sp->modulus * ::cos( sp->phase );
4794 im = sp->modulus * ::sin( sp->phase );
4795 sp_complex->re = re;
4796 sp_complex->im = im;
4802 //-----------------------------------------------------------------------------
4803 // name: execute()
4804 // desc: ...
4805 //-----------------------------------------------------------------------------
4806 void Chuck_Instr_Cast_object2string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4808 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4809 // pop it
4810 pop_( sp, 1 );
4811 // object
4812 Chuck_Object * obj = (Chuck_Object *)(*sp);
4813 // return
4814 Chuck_DL_Return RETURN;
4815 // get toString from it
4816 object_toString( obj, NULL, &RETURN, NULL );
4817 Chuck_String * str = RETURN.v_string;
4818 // set it
4819 push_( sp, (t_CKUINT)str );
4825 //-----------------------------------------------------------------------------
4826 // name: execute()
4827 // desc: ...
4828 //-----------------------------------------------------------------------------
4829 void Chuck_Instr_Op_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4831 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
4832 Chuck_String * lhs = NULL;
4833 Chuck_String * rhs = NULL;
4835 // pop
4836 pop_( sp, 2 );
4837 // get the string references
4838 lhs = (Chuck_String *)*sp;
4839 rhs = (Chuck_String *)*(sp + 1);
4840 // neither should be null
4841 if( !lhs || !rhs ) goto null_pointer;
4843 // look
4844 switch( m_val )
4846 case ae_op_eq:
4847 push_( sp, lhs->str == rhs->str );
4848 break;
4850 case ae_op_neq:
4851 push_( sp, lhs->str != rhs->str );
4852 break;
4854 case ae_op_lt:
4855 push_( sp, lhs->str < rhs->str );
4856 break;
4858 case ae_op_le:
4859 push_( sp, lhs->str <= rhs->str );
4860 break;
4862 case ae_op_gt:
4863 push_( sp, lhs->str > rhs->str );
4864 break;
4866 case ae_op_ge:
4867 push_( sp, lhs->str >= rhs->str );
4868 break;
4870 default:
4871 goto invalid_op;
4872 break;
4875 return;
4877 null_pointer:
4878 // we have a problem
4879 fprintf( stderr,
4880 "[chuck](VM): NullPointerException: (during string op) in shred[id=%d:%s], PC=[%d]\n",
4881 shred->xid, shred->name.c_str(), shred->pc );
4882 goto done;
4884 invalid_op:
4885 // we have a problem
4886 fprintf( stderr,
4887 "[chuck](VM): InvalidStringOpException: '%d' in shred[id=%d:%s], PC=[%d]\n",
4888 m_val, shred->xid, shred->name.c_str(), shred->pc );
4889 goto done;
4891 done:
4892 // do something!
4893 shred->is_running = FALSE;
4894 shred->is_done = TRUE;
4900 //-----------------------------------------------------------------------------
4901 // name: execute()
4902 // desc: ...
4903 //-----------------------------------------------------------------------------
4904 void Chuck_Instr_ADC::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4906 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
4907 push_( reg_sp, (t_CKUINT)vm->m_adc );
4913 //-----------------------------------------------------------------------------
4914 // name: execute()
4915 // desc: ...
4916 //-----------------------------------------------------------------------------
4917 void Chuck_Instr_DAC::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4919 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
4920 push_( reg_sp, (t_CKUINT)vm->m_dac );
4926 //-----------------------------------------------------------------------------
4927 // name: execute()
4928 // desc: ...
4929 //-----------------------------------------------------------------------------
4930 void Chuck_Instr_Bunghole::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4932 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
4933 push_( reg_sp, (t_CKUINT)vm->m_bunghole );
4939 //-----------------------------------------------------------------------------
4940 // name: Chuck_Instr_UGen_Link()
4941 // desc: ...
4942 //-----------------------------------------------------------------------------
4943 Chuck_Instr_UGen_Link::Chuck_Instr_UGen_Link( t_CKBOOL isUpChuck )
4945 m_isUpChuck = isUpChuck;
4951 //-----------------------------------------------------------------------------
4952 // name: execute()
4953 // desc: ...
4954 //-----------------------------------------------------------------------------
4955 void Chuck_Instr_UGen_Link::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4957 Chuck_UGen **& sp = (Chuck_UGen **&)shred->reg->sp;
4959 // pop
4960 pop_( sp, 2 );
4961 // check for null
4962 if( !*(sp+1) || !(*sp) ) goto null_pointer;
4963 // go for it
4964 (*(sp + 1))->add( *sp, m_isUpChuck );
4965 // push the second
4966 push_( sp, *(sp + 1) );
4968 return;
4970 null_pointer:
4971 // we have a problem
4972 fprintf( stderr,
4973 "[chuck](VM): NullPointerException: (UGen link) in shred[id=%d:%s], PC=[%d]\n",
4974 shred->xid, shred->name.c_str(), shred->pc );
4976 // do something!
4977 shred->is_running = FALSE;
4978 shred->is_done = TRUE;
4984 //-----------------------------------------------------------------------------
4985 // name: execute()
4986 // desc: ...
4987 //-----------------------------------------------------------------------------
4988 void Chuck_Instr_UGen_UnLink::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
4990 Chuck_UGen **& sp = (Chuck_UGen **&)shred->reg->sp;
4992 pop_( sp, 2 );
4993 (*(sp+1))->remove( *sp );
4994 push_( sp, *(sp + 1) );
5000 //-----------------------------------------------------------------------------
5001 // name: execute()
5002 // desc: ...
5003 //-----------------------------------------------------------------------------
5004 void Chuck_Instr_UGen_Ctrl::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5006 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5008 pop_( sp, 4 );
5009 Chuck_UGen * ugen = (Chuck_UGen *)*(sp+1);
5010 f_ctrl ctrl = (f_ctrl)*(sp+2);
5011 f_cget cget = (f_cget)*(sp+3);
5012 // set now
5013 ugen->now = shred->now;
5014 // call ctrl
5015 ctrl( ugen, (void *)sp );
5016 if( cget ) cget( ugen, (void *)sp );
5017 // push the new value
5018 push_( sp, *sp);
5024 //-----------------------------------------------------------------------------
5025 // name: execute()
5026 // desc: ...
5027 //-----------------------------------------------------------------------------
5028 void Chuck_Instr_UGen_CGet::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5030 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5032 pop_( sp, 2 );
5033 Chuck_UGen * ugen = (Chuck_UGen *)*(sp);
5034 f_cget cget = (f_cget)*(sp+1);
5035 // set now
5036 ugen->now = shred->now;
5037 // call cget
5038 cget( ugen, (void *)sp );
5039 // push the new value
5040 push_( sp, *sp);
5046 //-----------------------------------------------------------------------------
5047 // name: execute()
5048 // desc: ...
5049 //-----------------------------------------------------------------------------
5050 void Chuck_Instr_UGen_Ctrl2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5052 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5054 pop_( sp, 4 );
5055 Chuck_UGen * ugen = (Chuck_UGen *)*(sp+1);
5056 f_ctrl ctrl = (f_ctrl)*(sp+2);
5057 f_cget cget = (f_cget)*(sp+3);
5058 // set now
5059 ugen->now = shred->now;
5060 // call ctrl
5061 pop_( sp, 1 );
5062 ctrl( ugen, (void *)sp );
5063 if( cget ) cget( ugen, (void *)sp );
5064 // push the new value
5065 ((t_CKFLOAT *&)shred->reg->sp)++;
5071 //-----------------------------------------------------------------------------
5072 // name: execute()
5073 // desc: ...
5074 //-----------------------------------------------------------------------------
5075 void Chuck_Instr_UGen_CGet2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5077 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5079 pop_( sp, 2 );
5080 Chuck_UGen * ugen = (Chuck_UGen *)*(sp);
5081 f_cget cget = (f_cget)*(sp+1);
5082 // set now
5083 ugen->now = shred->now;
5084 // call cget
5085 cget( ugen, (void *)sp );
5086 // push the new value
5087 ((t_CKFLOAT *&)shred->reg->sp)++;
5093 //-----------------------------------------------------------------------------
5094 // name: execute()
5095 // desc: ...
5096 //-----------------------------------------------------------------------------
5097 void Chuck_Instr_UGen_PMsg::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5099 Chuck_UGen **& sp = (Chuck_UGen **&)shred->reg->sp;
5101 pop_( sp, 2 );
5103 // (*(sp + 1))->pmsg( shred->now, *sp );
5105 push_( sp, *(sp + 1) );
5111 //-----------------------------------------------------------------------------
5112 // name: execute()
5113 // desc: ...
5114 //-----------------------------------------------------------------------------
5115 void Chuck_Instr_Init_Loop_Counter::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5117 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
5119 // pop the value
5120 pop_( sp, 1 );
5122 // copy it
5123 (*(t_CKINT *)m_val) = *sp >= 0 ? *sp : -*sp;
5129 //-----------------------------------------------------------------------------
5130 // name: execute()
5131 // desc: ...
5132 //-----------------------------------------------------------------------------
5133 void Chuck_Instr_IO_in_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5140 //-----------------------------------------------------------------------------
5141 // name: execute()
5142 // desc: ...
5143 //-----------------------------------------------------------------------------
5144 void Chuck_Instr_IO_in_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5151 //-----------------------------------------------------------------------------
5152 // name: execute()
5153 // desc: ...
5154 //-----------------------------------------------------------------------------
5155 void Chuck_Instr_IO_in_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5162 //-----------------------------------------------------------------------------
5163 // name: execute()
5164 // desc: ...
5165 //-----------------------------------------------------------------------------
5166 void Chuck_Instr_IO_out_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5173 //-----------------------------------------------------------------------------
5174 // name: execute()
5175 // desc: ...
5176 //-----------------------------------------------------------------------------
5177 void Chuck_Instr_IO_out_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5184 //-----------------------------------------------------------------------------
5185 // name: execute()
5186 // desc: ...
5187 //-----------------------------------------------------------------------------
5188 void Chuck_Instr_IO_out_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5195 // hack
5196 Chuck_Instr_Hack::Chuck_Instr_Hack( Chuck_Type * type )
5198 this->m_type_ref = type;
5199 // this->m_type_ref->add_ref();
5202 Chuck_Instr_Hack::~Chuck_Instr_Hack()
5204 // this->m_type_ref->release();
5207 void Chuck_Instr_Hack::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5209 // look at the type
5210 if( m_type_ref->size == 4 ) // ISSUE: 64-bit
5212 t_CKINT * sp = (t_CKINT *)shred->reg->sp;
5213 if( !isa( m_type_ref, &t_string ) )
5214 // print it
5215 fprintf( stderr, "%d :(%s)\n", *(sp-1), m_type_ref->c_name() );
5216 else
5217 fprintf( stderr, "\"%s\" : (%s)\n", ((Chuck_String *)*(sp-1))->str.c_str(), m_type_ref->c_name() );
5219 else if( m_type_ref->size == 8 ) // ISSUE: 64-bit
5221 t_CKFLOAT * sp = (t_CKFLOAT *)shred->reg->sp;
5222 // print it
5223 fprintf( stderr, "%f :(%s)\n", *(sp-1), m_type_ref->c_name() );
5225 else if( m_type_ref->size == 16 ) // ISSUE: 64-bit
5227 if( m_type_ref->xid == te_complex )
5229 t_CKFLOAT * sp = (t_CKFLOAT *)shred->reg->sp;
5230 // print it
5231 fprintf( stderr, "#(%.4f,%.4f) :(%s)\n", *(sp-2), *(sp-1), m_type_ref->c_name() );
5233 else if( m_type_ref->xid == te_polar )
5235 t_CKFLOAT * sp = (t_CKFLOAT *)shred->reg->sp;
5236 // print it
5237 fprintf( stderr, "%%(%.4f,%.4f*pi) :(%s)\n", *(sp-2), *(sp-1)/ONE_PI, m_type_ref->c_name() );
5239 else
5241 fprintf( stderr, "[chuck]: internal error printing 16-byte primitive...\n" );
5244 else if( m_type_ref->size == 0 )
5246 fprintf( stderr, "... :(%s)\n", m_type_ref->c_name() );
5248 else
5249 assert( FALSE );
5251 // flush
5252 fflush( stderr );
5255 const char * Chuck_Instr_Hack::params() const
5257 static char buffer[256];
5258 sprintf( buffer, "(%s)", m_type_ref->c_name() );
5259 return buffer;
5265 // gack
5266 Chuck_Instr_Gack::Chuck_Instr_Gack( const std::vector<Chuck_Type *> & types )
5268 m_type_refs = types;
5270 // add refs
5273 Chuck_Instr_Gack::~Chuck_Instr_Gack()
5275 // release refs
5278 void Chuck_Instr_Gack::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5280 t_CKBYTE * the_sp = (t_CKBYTE *)shred->reg->sp;
5282 if( m_type_refs.size() == 1 )
5284 Chuck_Instr_Hack hack( m_type_refs[0] );
5285 hack.execute( vm, shred );
5286 return;
5289 // loop over types
5290 t_CKUINT i;
5292 // find the start of the expression
5293 for( i = 0; i < m_type_refs.size(); i++ )
5295 Chuck_Type * type = m_type_refs[i];
5296 the_sp -= type->size;
5299 // print
5300 for( i = 0; i < m_type_refs.size(); i++ )
5302 Chuck_Type * type = m_type_refs[i];
5304 // look at the type
5305 if( type->size == 4 ) // ISSUE: 64-bit
5307 t_CKINT * sp = (t_CKINT *)the_sp;
5308 if( !isa( type, &t_string ) )
5310 if( isa( type, &t_object ) )
5311 // print it
5312 fprintf( stderr, "0x%x ", *(sp) );
5313 else
5314 // print it
5315 fprintf( stderr, "%d ", *(sp) );
5317 else
5318 fprintf( stderr, "%s ", ((Chuck_String *)*(sp))->str.c_str() );
5320 the_sp += 4;
5322 else if( type->size == 8 ) // ISSUE: 64-bit
5324 t_CKFLOAT * sp = (t_CKFLOAT *)the_sp;
5325 // print it
5326 fprintf( stderr, "%f ", *(sp) );
5328 the_sp += 8;
5330 else if( type->size == 16 ) // ISSUE: 64-bit
5332 t_CKFLOAT * sp = (t_CKFLOAT *)the_sp;
5333 if( type->xid == te_complex )
5334 // print it
5335 fprintf( stderr, "#(%.4f,%.4f) ", *(sp), *(sp+1) );
5336 else if( type->xid == te_polar )
5337 // print it
5338 fprintf( stderr, "%%(%.4f,%.4f*pi) ", *(sp), *(sp+1)/ONE_PI );
5340 the_sp += 16;
5342 else if( type->size == 0 )
5344 fprintf( stderr, "... " );
5346 else
5347 assert( FALSE );
5350 fprintf( stderr, "\n" );
5352 // flush
5353 fflush( stderr );
5356 const char * Chuck_Instr_Gack::params() const
5358 static char buffer[256];
5359 sprintf( buffer, "( many types )" );
5360 return buffer;