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
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: chuck_instr.cpp
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 //-----------------------------------------------------------------------------
36 #include "chuck_type.h"
37 #include "chuck_lang.h"
38 #include "chuck_instr.h"
40 #include "chuck_ugen.h"
41 #include "chuck_bbq.h"
43 #include "chuck_errmsg.h"
44 #include "chuck_globals.h"
46 #include "util_string.h"
54 //-----------------------------------------------------------------------------
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
)
74 "[chuck](VM): Exception StackOverflow in shred[id=%d:%s], PC=[%d]\n",
75 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
77 shred
->is_running
= FALSE
;
78 shred
->is_done
= TRUE
;
84 //-----------------------------------------------------------------------------
87 //-----------------------------------------------------------------------------
88 void Chuck_Instr_Add_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
90 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
92 push_( sp
, val_(sp
) + val_(sp
+1) );
98 //-----------------------------------------------------------------------------
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
;
113 push_( the_sp
, **(reg_sp
) );
119 //-----------------------------------------------------------------------------
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
;
135 push_( the_sp
, **(reg_sp
) );
143 //-----------------------------------------------------------------------------
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
;
158 push_( the_sp
, **(reg_sp
) );
164 //-----------------------------------------------------------------------------
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
;
180 push_( the_sp
, **(reg_sp
) );
188 //-----------------------------------------------------------------------------
189 // name: class Chuck_Instr_Dec_int_Addr
191 //-----------------------------------------------------------------------------
192 void Chuck_Instr_Dec_int_Addr::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
195 (*((t_CKINT
*)(m_val
)))--;
201 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
217 //-----------------------------------------------------------------------------
218 void Chuck_Instr_Mod_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
220 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
222 push_( sp
, val_(sp
) % val_(sp
+1) );
228 //-----------------------------------------------------------------------------
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
;
236 push_( sp
, val_(sp
+1) % val_(sp
) );
242 //-----------------------------------------------------------------------------
245 //-----------------------------------------------------------------------------
246 void Chuck_Instr_Minus_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
248 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
250 push_( sp
, val_(sp
) - val_(sp
+1) );
256 //-----------------------------------------------------------------------------
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
;
264 push_( sp
, val_(sp
+1) - val_(sp
) );
270 //-----------------------------------------------------------------------------
273 //-----------------------------------------------------------------------------
274 void Chuck_Instr_Times_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
276 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
278 push_( sp
, val_(sp
) * val_(sp
+1) );
284 //-----------------------------------------------------------------------------
287 //-----------------------------------------------------------------------------
288 void Chuck_Instr_Divide_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
290 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
292 push_( sp
, val_(sp
) / val_(sp
+1) );
298 //-----------------------------------------------------------------------------
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
;
306 push_( sp
, val_(sp
+1) / val_(sp
) );
312 //-----------------------------------------------------------------------------
315 //-----------------------------------------------------------------------------
316 void Chuck_Instr_Add_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
318 t_CKFLOAT
*& sp
= (t_CKFLOAT
*&)shred
->reg
->sp
;
320 push_( sp
, val_(sp
) + val_(sp
+1) );
326 //-----------------------------------------------------------------------------
329 //-----------------------------------------------------------------------------
330 void Chuck_Instr_Minus_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
332 t_CKFLOAT
*& sp
= (t_CKFLOAT
*&)shred
->reg
->sp
;
334 push_( sp
, val_(sp
) - val_(sp
+1) );
340 //-----------------------------------------------------------------------------
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
;
348 push_( sp
, val_(sp
+1) - val_(sp
) );
354 //-----------------------------------------------------------------------------
357 //-----------------------------------------------------------------------------
358 void Chuck_Instr_Times_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
360 t_CKFLOAT
*& sp
= (t_CKFLOAT
*&)shred
->reg
->sp
;
362 push_( sp
, val_(sp
) * val_(sp
+1) );
368 //-----------------------------------------------------------------------------
371 //-----------------------------------------------------------------------------
372 void Chuck_Instr_Divide_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
374 t_CKFLOAT
*& sp
= (t_CKFLOAT
*&)shred
->reg
->sp
;
376 push_( sp
, val_(sp
) / val_(sp
+1) );
383 //-----------------------------------------------------------------------------
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
;
391 push_( sp
, val_(sp
+1) / val_(sp
) );
397 //-----------------------------------------------------------------------------
400 //-----------------------------------------------------------------------------
401 void Chuck_Instr_Mod_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
403 t_CKFLOAT
*& sp
= (t_CKFLOAT
*&)shred
->reg
->sp
;
405 push_( sp
, ::fmod( val_(sp
), val_(sp
+1) ) );
411 //-----------------------------------------------------------------------------
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
;
419 push_( sp
, ::fmod( val_(sp
+1), val_(sp
) ) );
425 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
513 // complex division -> * complex conjugate of divisor
514 denom
= (sp
+1)->re
*(sp
+1)->re
+ (sp
+1)->im
*(sp
+1)->im
;
516 re
= sp
->re
*(sp
+1)->re
+ sp
->im
*(sp
+1)->im
;
517 im
= sp
->im
*(sp
+1)->re
- sp
->re
*(sp
+1)->im
;
519 push_( sp_float
, re
/denom
);
520 push_( sp_float
, im
/denom
);
527 //-----------------------------------------------------------------------------
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
;
539 // complex division -> * complex conjugate of divisor
540 denom
= sp
->re
*sp
->re
+ sp
->im
*sp
->im
;
542 re
= sp
->re
*(sp
+1)->re
+ sp
->im
*(sp
+1)->im
;
543 im
= (sp
+1)->im
*sp
->re
- (sp
+1)->re
*sp
->im
;
545 push_( sp_float
, re
/denom
);
546 push_( sp_float
, im
/denom
);
552 //-----------------------------------------------------------------------------
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
;
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
);
568 push_( sp_float
, ::hypot( a
.re
, a
.im
) );
569 push_( sp_float
, ::atan2( a
.im
, a
.re
) );
575 //-----------------------------------------------------------------------------
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
;
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
);
591 push_( sp_float
, ::hypot( a
.re
, a
.im
) );
592 push_( sp_float
, ::atan2( a
.im
, a
.re
) );
598 //-----------------------------------------------------------------------------
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
;
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
);
614 push_( sp_float
, ::hypot( a
.re
, a
.im
) );
615 push_( sp_float
, ::atan2( a
.im
, a
.re
) );
621 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
687 temp
= **(t_CKINT
**)(sp
+1) += val_(sp
);
694 //-----------------------------------------------------------------------------
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
;
702 temp
= **(t_CKINT
**)(sp
+1) %= val_(sp
);
709 //-----------------------------------------------------------------------------
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
;
717 temp
= **(t_CKINT
**)(sp
+1) -= val_(sp
);
724 //-----------------------------------------------------------------------------
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
;
732 temp
= **(t_CKINT
**)(sp
+1) *= val_(sp
);
739 //-----------------------------------------------------------------------------
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
;
747 temp
= **(t_CKINT
**)(sp
+1) /= val_(sp
);
753 //-----------------------------------------------------------------------------
756 //-----------------------------------------------------------------------------
757 void Chuck_Instr_Add_double_Assign::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
760 t_CKBYTE
*& sp
= (t_CKBYTE
*&)shred
->reg
->sp
;
761 // pop value + pointer
762 pop_( sp
, sz_FLOAT
+ sz_UINT
);
764 temp
= **(t_CKFLOAT
**)(sp
+sz_FLOAT
) += val_((t_CKFLOAT
*&)sp
);
766 push_( (t_CKFLOAT
*&)sp
, temp
);
772 //-----------------------------------------------------------------------------
775 //-----------------------------------------------------------------------------
776 void Chuck_Instr_Minus_double_Assign::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
779 t_CKBYTE
*& sp
= (t_CKBYTE
*&)shred
->reg
->sp
;
780 // pop value + pointer
781 pop_( sp
, sz_FLOAT
+ sz_UINT
);
783 temp
= **(t_CKFLOAT
**)(sp
+sz_FLOAT
) -= val_((t_CKFLOAT
*&)sp
);
785 push_( (t_CKFLOAT
*&)sp
, temp
);
791 //-----------------------------------------------------------------------------
794 //-----------------------------------------------------------------------------
795 void Chuck_Instr_Times_double_Assign::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
798 t_CKBYTE
*& sp
= (t_CKBYTE
*&)shred
->reg
->sp
;
799 // pop value + pointer
800 pop_( sp
, sz_FLOAT
+ sz_UINT
);
802 temp
= **(t_CKFLOAT
**)(sp
+sz_FLOAT
) *= val_((t_CKFLOAT
*&)sp
);
804 push_( (t_CKFLOAT
*&)sp
, temp
);
810 //-----------------------------------------------------------------------------
813 //-----------------------------------------------------------------------------
814 void Chuck_Instr_Divide_double_Assign::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
817 t_CKBYTE
*& sp
= (t_CKBYTE
*&)shred
->reg
->sp
;
818 // pop value + pointer
819 pop_( sp
, sz_FLOAT
+ sz_UINT
);
821 temp
= **(t_CKFLOAT
**)(sp
+sz_FLOAT
) /= val_((t_CKFLOAT
*&)sp
);
823 push_( (t_CKFLOAT
*&)sp
, temp
);
829 //-----------------------------------------------------------------------------
832 //-----------------------------------------------------------------------------
833 void Chuck_Instr_Mod_double_Assign::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
836 t_CKBYTE
*& sp
= (t_CKBYTE
*&)shred
->reg
->sp
;
837 // pop value + pointer
838 pop_( sp
, sz_FLOAT
+ sz_UINT
);
840 temp
= ::fmod( **(t_CKFLOAT
**)(sp
+sz_FLOAT
), val_((t_CKFLOAT
*&)sp
) );
841 **(t_CKFLOAT
**)(sp
+sz_FLOAT
) = temp
;
843 push_( (t_CKFLOAT
*&)sp
, temp
);
849 //-----------------------------------------------------------------------------
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
;
857 // pop value + pointer
858 pop_( sp
, sz_COMPLEX
+ sz_UINT
);
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
;
864 push_( (t_CKCOMPLEX
*&)sp
, temp
);
870 //-----------------------------------------------------------------------------
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
;
878 // pop value + pointer
879 pop_( sp
, sz_COMPLEX
+ sz_UINT
);
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
;
885 push_( (t_CKCOMPLEX
*&)sp
, temp
);
891 //-----------------------------------------------------------------------------
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
);
902 a
= **(t_CKCOMPLEX
**)(sp
+sz_COMPLEX
);
903 b
= *(t_CKCOMPLEX
*&)sp
;
905 temp
.re
= a
.re
* b
.re
- a
.im
* b
.im
;
906 temp
.im
= a
.re
* b
.im
+ a
.im
* b
.re
;
908 (*(t_CKCOMPLEX
**)(sp
+sz_COMPLEX
))->re
= temp
.re
;
909 (*(t_CKCOMPLEX
**)(sp
+sz_COMPLEX
))->im
= temp
.im
;
911 push_( (t_CKCOMPLEX
*&)sp
, temp
);
917 //-----------------------------------------------------------------------------
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
;
926 // pop value + pointer
927 pop_( sp
, sz_COMPLEX
+ sz_UINT
);
929 a
= **(t_CKCOMPLEX
**)(sp
+sz_COMPLEX
);
930 b
= *(t_CKCOMPLEX
*&)sp
;
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
;
938 (*(t_CKCOMPLEX
**)(sp
+sz_COMPLEX
))->re
= temp
.re
;
939 (*(t_CKCOMPLEX
**)(sp
+sz_COMPLEX
))->im
= temp
.im
;
941 push_( (t_CKCOMPLEX
*&)sp
, temp
);
947 //-----------------------------------------------------------------------------
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
);
959 pa
= *(t_CKPOLAR
**)(sp
+sz_POLAR
);
960 pb
= (t_CKPOLAR
*&)sp
;
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
);
967 temp
.re
= a
.re
+ b
.re
;
968 temp
.im
= a
.im
+ b
.im
;
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
);
973 push_( (t_CKPOLAR
*&)sp
, result
);
979 //-----------------------------------------------------------------------------
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
);
991 pa
= *(t_CKPOLAR
**)(sp
+sz_POLAR
);
992 pb
= (t_CKPOLAR
*&)sp
;
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
);
999 temp
.re
= a
.re
- b
.re
;
1000 temp
.im
= a
.im
- b
.im
;
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
);
1005 push_( (t_CKPOLAR
*&)sp
, result
);
1011 //-----------------------------------------------------------------------------
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
;
1019 // pop value + pointer
1020 pop_( sp
, sz_POLAR
+ sz_UINT
);
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
;
1026 push_( (t_CKPOLAR
*&)sp
, temp
);
1032 //-----------------------------------------------------------------------------
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
;
1040 // pop value + pointer
1041 pop_( sp
, sz_POLAR
+ sz_UINT
);
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
;
1047 push_( (t_CKPOLAR
*&)sp
, temp
);
1053 //-----------------------------------------------------------------------------
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
1067 lhs
= (Chuck_String
*)(*(reg_sp
));
1069 rhs
= (Chuck_String
*)(*(reg_sp
+1));
1071 // make sure no null
1072 if( !rhs
|| !lhs
) goto null_pointer
;
1075 result
= (Chuck_String
*)instantiate_and_initialize_object( &t_string
, shred
);
1078 result
->str
= lhs
->str
+ rhs
->str
;
1080 // push the reference value to reg stack
1081 push_( reg_sp
, (t_CKUINT
)(result
) );
1086 // we have a problem
1088 "[chuck](VM): NullPointerException: (string + string) in shred[id=%d:%s], PC=[%d]\n",
1089 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1094 shred
->is_running
= FALSE
;
1095 shred
->is_done
= TRUE
;
1101 //-----------------------------------------------------------------------------
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
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
;
1122 (*rhs_ptr
)->str
+= lhs
->str
;
1124 // push the reference value to reg stack
1125 push_( reg_sp
, (t_CKUINT
)(*rhs_ptr
) );
1130 // we have a problem
1132 "[chuck](VM): NullPointerException: (string + string) in shred[id=%d:%s], PC=[%d]\n",
1133 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1138 shred
->is_running
= FALSE
;
1139 shred
->is_done
= TRUE
;
1145 //-----------------------------------------------------------------------------
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
;
1154 Chuck_String
* result
= NULL
;
1156 // pop word from reg stack
1159 lhs
= (Chuck_String
*)(*(reg_sp
));
1161 rhs
= (*(t_CKINT
*)(reg_sp
+1));
1163 // make sure no null
1164 if( !lhs
) goto null_pointer
;
1167 result
= (Chuck_String
*)instantiate_and_initialize_object( &t_string
, shred
);
1170 result
->str
= lhs
->str
+ ::itoa(rhs
);
1172 // push the reference value to reg stack
1173 push_( reg_sp
, (t_CKUINT
)(result
) );
1178 // we have a problem
1180 "[chuck](VM): NullPointerException: (string + int) in shred[id=%d:%s], PC=[%d]\n",
1181 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1186 shred
->is_running
= FALSE
;
1187 shred
->is_done
= TRUE
;
1193 //-----------------------------------------------------------------------------
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
;
1202 Chuck_String
* result
= NULL
;
1204 // pop word from reg stack
1207 lhs
= (Chuck_String
*)(*(reg_sp
));
1209 rhs
= (*(t_CKFLOAT
*)(reg_sp
+1));
1211 // make sure no null
1212 if( !lhs
) goto null_pointer
;
1215 result
= (Chuck_String
*)instantiate_and_initialize_object( &t_string
, shred
);
1218 result
->str
= lhs
->str
+ ::ftoa(rhs
, 4);
1220 // push the reference value to reg stack
1221 push_( reg_sp
, (t_CKUINT
)(result
) );
1226 // we have a problem
1228 "[chuck](VM): NullPointerException: (string + float) in shred[id=%d:%s], PC=[%d]\n",
1229 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1234 shred
->is_running
= FALSE
;
1235 shred
->is_done
= TRUE
;
1241 //-----------------------------------------------------------------------------
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
;
1249 Chuck_String
* rhs
= NULL
;
1250 Chuck_String
* result
= NULL
;
1252 // pop word from reg stack
1255 lhs
= (*(t_CKINT
*)(reg_sp
));
1257 rhs
= (Chuck_String
*)(*(reg_sp
+1));
1259 // make sure no null
1260 if( !rhs
) goto null_pointer
;
1263 result
= (Chuck_String
*)instantiate_and_initialize_object( &t_string
, shred
);
1266 result
->str
= ::itoa(lhs
) + rhs
->str
;
1268 // push the reference value to reg stack
1269 push_( reg_sp
, (t_CKUINT
)(result
) );
1274 // we have a problem
1276 "[chuck](VM): NullPointerException: (int + string) in shred[id=%d:%s], PC=[%d]\n",
1277 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1282 shred
->is_running
= FALSE
;
1283 shred
->is_done
= TRUE
;
1289 //-----------------------------------------------------------------------------
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
;
1297 Chuck_String
* rhs
= NULL
;
1298 Chuck_String
* result
= NULL
;
1300 // pop word from reg stack
1303 lhs
= (*(t_CKFLOAT
*)(reg_sp
));
1305 rhs
= (Chuck_String
*)(*(reg_sp
+2));
1307 // make sure no null
1308 if( !rhs
) goto null_pointer
;
1311 result
= (Chuck_String
*)instantiate_and_initialize_object( &t_string
, shred
);
1314 result
->str
= ::ftoa(lhs
, 4) + rhs
->str
;
1316 // push the reference value to reg stack
1317 push_( reg_sp
, (t_CKUINT
)(result
) );
1322 // we have a problem
1324 "[chuck](VM): NullPointerException: (int + string) in shred[id=%d:%s], PC=[%d]\n",
1325 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1330 shred
->is_running
= FALSE
;
1331 shred
->is_done
= TRUE
;
1337 //-----------------------------------------------------------------------------
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
;
1345 Chuck_String
** rhs_ptr
= NULL
;
1347 // pop word from reg stack
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
;
1358 (*rhs_ptr
)->str
+= ::itoa(lhs
);
1360 // push the reference value to reg stack
1361 push_( reg_sp
, (t_CKUINT
)(*rhs_ptr
) );
1366 // we have a problem
1368 "[chuck](VM): NullPointerException: () in shred[id=%d:%s], PC=[%d]\n",
1369 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1374 shred
->is_running
= FALSE
;
1375 shred
->is_done
= TRUE
;
1381 //-----------------------------------------------------------------------------
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
;
1389 Chuck_String
** rhs_ptr
= NULL
;
1391 // pop word from reg stack
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
;
1402 (*rhs_ptr
)->str
+= ::ftoa(lhs
, 4);
1404 // push the reference value to reg stack
1405 push_( reg_sp
, (t_CKUINT
)(*rhs_ptr
) );
1410 // we have a problem
1412 "[chuck](VM): NullPointerException: (string + string) in shred[id=%d:%s], PC=[%d]\n",
1413 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
1418 shred
->is_running
= FALSE
;
1419 shred
->is_done
= TRUE
;
1425 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
) );
1591 t_CKFLOAT
*& reg_sp
= (t_CKFLOAT
*&)shred
->reg
->sp
;
1592 push_( reg_sp
, *((t_CKFLOAT
*)m_val
) );
1599 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
1674 // copy popped value into mem stack
1675 *((t_CKUINT
*)(mem_sp
+ *(reg_sp
+1) )) = *reg_sp
;
1681 //-----------------------------------------------------------------------------
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
1696 //-----------------------------------------------------------------------------
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
1711 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
);
1741 //-----------------------------------------------------------------------------
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
);
1756 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
1801 //-----------------------------------------------------------------------------
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
1816 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
;
1839 if( val_(sp
) < val_(sp
+1) )
1840 shred
->next_pc
= m_jmp
;
1846 //-----------------------------------------------------------------------------
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
;
1854 if( val_(sp
) > val_(sp
+1) )
1855 shred
->next_pc
= m_jmp
;
1861 //-----------------------------------------------------------------------------
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
;
1869 if( val_(sp
) <= val_(sp
+1) )
1870 shred
->next_pc
= m_jmp
;
1876 //-----------------------------------------------------------------------------
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
;
1884 if( val_(sp
) >= val_(sp
+1) )
1885 shred
->next_pc
= m_jmp
;
1891 //-----------------------------------------------------------------------------
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
;
1899 if( val_(sp
) == val_(sp
+1) )
1900 shred
->next_pc
= m_jmp
;
1906 //-----------------------------------------------------------------------------
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
;
1914 if( val_(sp
) != val_(sp
+1) )
1915 shred
->next_pc
= m_jmp
;
1921 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
;
1968 if( val_(sp
) < val_(sp
+1) )
1969 shred
->next_pc
= m_jmp
;
1975 //-----------------------------------------------------------------------------
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
;
1983 if( val_(sp
) > val_(sp
+1) )
1984 shred
->next_pc
= m_jmp
;
1990 //-----------------------------------------------------------------------------
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
;
1998 if( val_(sp
) <= val_(sp
+1) )
1999 shred
->next_pc
= m_jmp
;
2005 //-----------------------------------------------------------------------------
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
;
2013 if( val_(sp
) >= val_(sp
+1) )
2014 shred
->next_pc
= m_jmp
;
2020 //-----------------------------------------------------------------------------
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
;
2028 if( val_(sp
) == val_(sp
+1) )
2029 shred
->next_pc
= m_jmp
;
2035 //-----------------------------------------------------------------------------
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
;
2043 if( val_(sp
) != val_(sp
+1) )
2044 shred
->next_pc
= m_jmp
;
2050 //-----------------------------------------------------------------------------
2053 //-----------------------------------------------------------------------------
2054 void Chuck_Instr_Binary_And::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2056 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
2058 push_( sp
, val_(sp
) & val_(sp
+1) );
2064 //-----------------------------------------------------------------------------
2067 //-----------------------------------------------------------------------------
2068 void Chuck_Instr_Binary_Or::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2070 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
2072 push_( sp
, val_(sp
) | val_(sp
+1) );
2078 //-----------------------------------------------------------------------------
2081 //-----------------------------------------------------------------------------
2082 void Chuck_Instr_Binary_Xor::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2084 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
2086 push_( sp
, val_(sp
) ^ val_(sp
+1) );
2092 //-----------------------------------------------------------------------------
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
;
2100 push_( sp
, val_(sp
) >> val_(sp
+1) );
2106 //-----------------------------------------------------------------------------
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
;
2114 push_( sp
, val_(sp
+1) >> val_(sp
) );
2120 //-----------------------------------------------------------------------------
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
;
2128 push_( sp
, val_(sp
) << val_(sp
+1) );
2134 //-----------------------------------------------------------------------------
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
;
2142 push_( sp
, val_(sp
+1) << val_(sp
) );
2148 //-----------------------------------------------------------------------------
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
;
2156 temp
= **(t_CKINT
**)(sp
+1) &= val_(sp
);
2163 //-----------------------------------------------------------------------------
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
;
2171 temp
= **(t_CKINT
**)(sp
+1) |= val_(sp
);
2178 //-----------------------------------------------------------------------------
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
;
2186 temp
= **(t_CKINT
**)(sp
+1) ^= val_(sp
);
2193 //-----------------------------------------------------------------------------
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
;
2201 temp
= **(t_CKINT
**)(sp
+1) >>= val_(sp
);
2208 //-----------------------------------------------------------------------------
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
;
2216 temp
= **(t_CKINT
**)(sp
+1) <<= val_(sp
);
2223 //-----------------------------------------------------------------------------
2226 //-----------------------------------------------------------------------------
2227 void Chuck_Instr_Lt_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2229 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
2231 push_( sp
, val_(sp
) < val_(sp
+1) );
2237 //-----------------------------------------------------------------------------
2240 //-----------------------------------------------------------------------------
2241 void Chuck_Instr_Gt_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2243 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
2245 push_( sp
, val_(sp
) > val_(sp
+1) );
2251 //-----------------------------------------------------------------------------
2254 //-----------------------------------------------------------------------------
2255 void Chuck_Instr_Le_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2257 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
2259 push_( sp
, val_(sp
) <= val_(sp
+1) );
2265 //-----------------------------------------------------------------------------
2268 //-----------------------------------------------------------------------------
2269 void Chuck_Instr_Ge_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2271 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
2273 push_( sp
, val_(sp
) >= val_(sp
+1) );
2279 //-----------------------------------------------------------------------------
2282 //-----------------------------------------------------------------------------
2283 void Chuck_Instr_Eq_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2285 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
2287 push_( sp
, val_(sp
) == val_(sp
+1) );
2293 //-----------------------------------------------------------------------------
2296 //-----------------------------------------------------------------------------
2297 void Chuck_Instr_Neq_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2299 t_CKINT
*& sp
= (t_CKINT
*&)shred
->reg
->sp
;
2301 push_( sp
, val_(sp
) != val_(sp
+1) );
2307 //-----------------------------------------------------------------------------
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
;
2316 push_( sp_uint
, val_(sp
) < val_(sp
+1) );
2322 //-----------------------------------------------------------------------------
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
;
2331 push_( sp_uint
, val_(sp
) > val_(sp
+1) );
2337 //-----------------------------------------------------------------------------
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
;
2346 push_( sp_uint
, val_(sp
) <= val_(sp
+1) );
2352 //-----------------------------------------------------------------------------
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
;
2361 push_( sp_uint
, val_(sp
) >= val_(sp
+1) );
2367 //-----------------------------------------------------------------------------
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
;
2376 push_( sp_uint
, val_(sp
) == val_(sp
+1) );
2382 //-----------------------------------------------------------------------------
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
;
2391 push_( sp_uint
, val_(sp
) != val_(sp
+1) );
2397 //-----------------------------------------------------------------------------
2400 //-----------------------------------------------------------------------------
2401 void Chuck_Instr_And::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2403 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
2405 push_( sp
, val_(sp
) && val_(sp
+1) );
2411 //-----------------------------------------------------------------------------
2414 //-----------------------------------------------------------------------------
2415 void Chuck_Instr_Or::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2417 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
2419 push_( sp
, val_(sp
) || val_(sp
+1) );
2425 //-----------------------------------------------------------------------------
2428 //-----------------------------------------------------------------------------
2429 void Chuck_Instr_Goto::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2431 shred
->next_pc
= m_jmp
;
2437 //-----------------------------------------------------------------------------
2440 //-----------------------------------------------------------------------------
2441 void Chuck_Instr_Nop::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2449 //-----------------------------------------------------------------------------
2452 //-----------------------------------------------------------------------------
2453 void Chuck_Instr_EOC::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2456 shred
->is_done
= TRUE
;
2457 shred
->is_running
= FALSE
;
2463 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
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 //-----------------------------------------------------------------------------
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
;
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()
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
;
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
);
2604 g_func_call
.execute( vm
, shred
);
2610 //-----------------------------------------------------------------------------
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()
2625 //-----------------------------------------------------------------------------
2626 t_CKBOOL
initialize_object( Chuck_Object
* object
, Chuck_Type
* type
)
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();
2642 object
->size
= type
->obj_size
;
2646 // check to ensure enough memory
2647 object
->data
= new t_CKBYTE
[object
->size
];
2648 if( !object
->data
) goto out_of_memory
;
2650 memset( object
->data
, 0, object
->size
);
2652 else object
->data
= NULL
;
2655 if( type
->ugen_info
)
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
);
2673 ugen
->m_multi_chan
[i
] = (Chuck_UGen
*)obj
;
2674 // additional reference count
2675 ugen
->m_multi_chan
[i
]->add_ref();
2677 ugen
->m_multi_chan
[i
]->owner
= ugen
;
2681 // TODO: alloc channels for uana
2688 // we have a problem
2690 "[chuck](VM): OutOfMemory: while instantiating object '%s'\n",
2694 if( object
) SAFE_DELETE( object
->vtable
);
2703 //-----------------------------------------------------------------------------
2704 // name: instantiate_and_initialize_object()
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
;
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
;
2731 Chuck_UGen
* ugen
= NULL
;
2733 if( type
->ugen_info
->tock
!= NULL
)
2736 object
= ugen
= uana
= new Chuck_UAna
;
2737 ugen
->alloc_v( vm_ref
->shreduler()->m_max_block_size
);
2741 object
= ugen
= new Chuck_UGen
;
2742 ugen
->alloc_v( vm_ref
->shreduler()->m_max_block_size
);
2747 ugen
->shred
= shred
;
2752 // check to see enough memory
2753 if( !object
) goto out_of_memory
;
2756 if( !initialize_object( object
, type
) ) goto error
;
2762 // we have a problem
2764 "[chuck](VM): OutOfMemory: while instantiating object '%s'\n",
2770 SAFE_DELETE( object
);
2779 //-----------------------------------------------------------------------------
2780 // name: instantiate_object()
2782 //-----------------------------------------------------------------------------
2783 inline void instantiate_object( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
,
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 );
2803 shred
->is_running
= FALSE
;
2804 shred
->is_done
= TRUE
;
2810 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
2825 //-----------------------------------------------------------------------------
2826 const char * Chuck_Instr_Instantiate_Object::params() const
2828 static char buffer
[256];
2829 sprintf( buffer
, "%s", this->type
->c_name() );
2836 //-----------------------------------------------------------------------------
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]" );
2850 //-----------------------------------------------------------------------------
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
;
2864 instantiate_object( vm
, shred
, type
);
2871 //-----------------------------------------------------------------------------
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
;
2883 Chuck_Object
* obj
= (Chuck_Object
*)(*(reg_sp
));
2886 t_CKUINT
* array
= (t_CKUINT
*)(*(reg_sp
-3));
2887 // get the object pointer
2888 Chuck_Object
** dest
= (Chuck_Object
**)(array
[*(reg_sp
-2)]);
2893 // increment the index
2894 (*(reg_sp
-2))++; //= (*(reg_sp-2)) + 1;
2897 shred
->next_pc
= m_val
;
2903 //-----------------------------------------------------------------------------
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
2914 // clean up the array
2915 t_CKUINT
* arr
= (t_CKUINT
*)*reg_sp
;
2916 SAFE_DELETE_ARRAY( arr
);
2922 //-----------------------------------------------------------------------------
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
2932 // copy popped value into mem stack
2933 *((t_CKUINT
*)(*(reg_sp
+1))) = *reg_sp
;
2935 push_( reg_sp
, *reg_sp
);
2941 //-----------------------------------------------------------------------------
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
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 //-----------------------------------------------------------------------------
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
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 //-----------------------------------------------------------------------------
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
2992 // the previous reference
2993 obj
= (Chuck_VM_Object
**)(*(reg_sp
+1));
2994 // save the reference (release should come after, in case same object)
2996 // copy popped value into memory
2997 *obj
= (Chuck_VM_Object
*)(*(reg_sp
));
2999 if( *obj
) (*obj
)->add_ref();
3001 if( done
) done
->release();
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 //-----------------------------------------------------------------------------
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
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
3031 if( lhs
) (*rhs_ptr
)->str
= lhs
->str
;
3034 // release reference
3035 (*rhs_ptr
)->release();
3041 // if left is not null, yes
3044 (*rhs_ptr
) = (Chuck_String
*)instantiate_and_initialize_object( &t_string
, shred
);
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." );
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 //-----------------------------------------------------------------------------
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
3076 // copy popped value into mem stack
3077 obj
= *( (Chuck_VM_Object
**)(mem_sp
+ *(reg_sp
)) );
3085 //-----------------------------------------------------------------------------
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
;
3094 Chuck_Func
* func
= (Chuck_Func
*)*(reg_sp
-1);
3096 assert( func
!= NULL
);
3098 *(reg_sp
-1) = (t_CKUINT
)func
->code
;
3104 //-----------------------------------------------------------------------------
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
;
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 );
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
);
3133 push_( mem_sp
, (t_CKUINT
)(shred
->pc
+ 1) );
3134 // push the stack depth
3135 push_( mem_sp
, stack_depth
);
3140 // set the instruction to the function instruction
3141 shred
->instr
= func
->instr
;
3143 // if there are arguments to be passed
3146 // pop the arguments, by number of words
3147 pop_( reg_sp
, stack_depth
);
3150 t_CKUINT
* mem_sp2
= (t_CKUINT
*)mem_sp
;
3151 t_CKUINT
* reg_sp2
= (t_CKUINT
*)reg_sp
;
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
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
;
3174 handle_overflow( shred
, vm
);
3180 //-----------------------------------------------------------------------------
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
;
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
3212 // pop the arguments for pass to callee function
3213 reg_sp
-= stack_depth
;
3216 t_CKUINT
* reg_sp2
= reg_sp
;
3217 t_CKUINT
* mem_sp2
= mem_sp
;
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
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
;
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
;
3241 f( (Chuck_Object
*)(*mem_sp
), mem_sp
+ 1, shred
);
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)
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
);
3279 handle_overflow( shred
, vm
);
3285 //-----------------------------------------------------------------------------
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
;
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
3317 // pop the arguments for pass to callee function
3318 reg_sp
-= stack_depth
;
3321 t_CKUINT
* reg_sp2
= reg_sp
;
3322 t_CKUINT
* mem_sp2
= mem_sp
;
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
3331 // one less word to copy
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
);
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
);
3372 handle_overflow( shred
, vm
);
3378 //-----------------------------------------------------------------------------
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;
3389 shred
->next_pc
= *mem_sp
;
3392 Chuck_VM_Code
* func
= (Chuck_VM_Code
*)*mem_sp
;
3393 // pop the prev_stack
3395 // jump the prev stack
3396 mem_sp
-= *(mem_sp
);
3400 shred
->instr
= func
->instr
;
3406 //-----------------------------------------------------------------------------
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;
3418 Chuck_VM_Code
* code
= *(Chuck_VM_Code
**)reg_sp
;
3420 Chuck_VM_Shred
* sh
= vm
->spork( code
, shred
);
3424 Chuck_Func
* func
= (Chuck_Func
*)(*reg_sp
);
3426 if( func
->is_member
)
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
);
3446 push_( (t_CKUINT
*&)sh
->reg
->sp
, (t_CKUINT
)func
);
3448 push_( reg_sp
, (t_CKUINT
)sh
);
3454 //-----------------------------------------------------------------------------
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
3465 if( *sp
< shred
->now
)
3467 // we have a problem
3469 "[chuck](VM): DestTimeNegativeException: '%.6f' in shred[id=%d:%s], PC=[%d]\n",
3470 *sp
, shred
->xid
, shred
->name
.c_str(), shred
->pc
);
3472 shred
->is_running
= FALSE
;
3473 shred
->is_done
= TRUE
;
3478 // shredule the shred
3479 vm
->shreduler()->shredule( shred
, *sp
);
3481 shred
->is_running
= FALSE
;
3483 // track time advance
3484 CK_TRACK( Chuck_Stats::instance()->advance_time( shred
, *sp
) );
3492 //-----------------------------------------------------------------------------
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
3503 Chuck_Event
* event
= (Chuck_Event
*)(*sp
);
3506 if( !event
) goto null_pointer
;
3509 event
->wait( shred
, vm
);
3514 // we have a problem
3516 "[chuck](VM): NullPointerException: (null Event wait) in shred[id=%d:%s], PC=[%d]\n",
3517 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
3522 shred
->is_running
= FALSE
;
3523 shred
->is_done
= TRUE
;
3529 //-----------------------------------------------------------------------------
3530 // name: Chuck_Instr_Array_Init()
3532 //-----------------------------------------------------------------------------
3533 Chuck_Instr_Array_Init::Chuck_Instr_Array_Init( Chuck_Type
* t
, t_CKINT length
)
3539 // TODO: do this? remember?
3540 // m_type_ref->add_ref();
3542 m_param_str
= new char[64];
3544 m_is_obj
= isobj( m_type_ref
);
3545 const char * str
= m_type_ref
->c_name();
3546 t_CKUINT len
= strlen( str
);
3549 strcpy( m_param_str
, str
);
3552 strncpy( m_param_str
, str
, 45 );
3553 strcpy( m_param_str
+ 45, "..." );
3558 sprintf( buffer
, "[%ld]", m_length
);
3559 strcat( m_param_str
, buffer
);
3565 //-----------------------------------------------------------------------------
3566 // name: ~Chuck_Instr_Array_Init()
3568 //-----------------------------------------------------------------------------
3569 Chuck_Instr_Array_Init::~Chuck_Instr_Array_Init()
3572 delete [] m_param_str
;
3575 //m_type_ref->release();
3582 //-----------------------------------------------------------------------------
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
3595 pop_( reg_sp
, m_length
);
3596 // instantiate array
3597 Chuck_Array4
* array
= new Chuck_Array4( m_is_obj
, m_length
);
3599 if( !array
) goto out_of_memory
;
3600 // initialize object
3601 initialize_object( array
, &t_array
);
3603 array
->set_size( m_length
);
3605 for( t_CKINT i
= 0; i
< m_length
; i
++ )
3606 array
->set( i
, *(reg_sp
+ i
) );
3608 push_( reg_sp
, (t_CKUINT
)array
);
3610 else if( m_type_ref
->size
== 8 ) // ISSUE: 64-bit
3613 pop_( reg_sp
, 2 * m_length
);
3614 // instantiate array
3615 Chuck_Array8
* array
= new Chuck_Array8( m_length
);
3617 if( !array
) goto out_of_memory
;
3619 t_CKFLOAT
* sp
= (t_CKFLOAT
*)reg_sp
;
3621 initialize_object( array
, &t_array
);
3623 array
->set_size( m_length
);
3625 for( t_CKINT i
= 0; i
< m_length
; i
++ )
3626 array
->set( i
, *(sp
+ i
) );
3628 push_( reg_sp
, (t_CKUINT
)array
);
3630 else if( m_type_ref
->size
== 16 ) // ISSUE: 64-bit
3633 pop_( reg_sp
, 4 * m_length
);
3634 // instantiate array
3635 Chuck_Array16
* array
= new Chuck_Array16( m_length
);
3637 if( !array
) goto out_of_memory
;
3639 t_CKCOMPLEX
* sp
= (t_CKCOMPLEX
*)reg_sp
;
3641 initialize_object( array
, &t_array
);
3643 array
->set_size( m_length
);
3645 for( t_CKINT i
= 0; i
< m_length
; i
++ )
3646 array
->set( i
, *(sp
+ i
) );
3648 push_( reg_sp
, (t_CKUINT
)array
);
3650 else assert( FALSE
);
3656 // we have a problem
3658 "[chuck](VM): OutOfMemory: while initializing arrays\n" );
3661 shred
->is_running
= FALSE
;
3662 shred
->is_done
= TRUE
;
3668 //-----------------------------------------------------------------------------
3669 // name: Chuck_Instr_Array_Alloc()
3671 //-----------------------------------------------------------------------------
3672 Chuck_Instr_Array_Alloc::Chuck_Instr_Array_Alloc( t_CKUINT depth
, Chuck_Type
* t
,
3673 t_CKUINT offset
, t_CKBOOL is_ref
)
3680 // m_type_ref->add_ref();
3682 m_param_str
= new char[64];
3684 m_is_obj
= isobj( m_type_ref
);
3685 // offset for pre constructor
3686 m_stack_offset
= offset
;
3689 const char * str
= m_type_ref
->c_name();
3690 t_CKUINT len
= strlen( str
);
3693 strcpy( m_param_str
, str
);
3696 strncpy( m_param_str
, str
, 60 );
3697 strcpy( m_param_str
+ 60, "..." );
3704 //-----------------------------------------------------------------------------
3705 // name: ~Chuck_Instr_Array_Alloc()
3707 //-----------------------------------------------------------------------------
3708 Chuck_Instr_Array_Alloc::~Chuck_Instr_Array_Alloc()
3711 delete [] m_param_str
;
3714 //m_type_ref->release();
3721 //-----------------------------------------------------------------------------
3722 // name: do_alloc_array()
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
)
3730 Chuck_Array4
* base
= NULL
;
3731 Chuck_Object
* next
= NULL
;
3735 if( *capacity
< 0 ) goto negative_array_size
;
3738 if( capacity
>= top
)
3741 if( size
== 4 ) // ISSUE: 64-bit
3743 Chuck_Array4
* base
= new Chuck_Array4( is_obj
, *capacity
);
3744 if( !base
) goto out_of_memory
;
3747 if( is_obj
&& objs
)
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
);
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
);
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
);
3780 // shouldn't get here
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
++ )
3792 next
= do_alloc_array( capacity
+1, top
, size
, is_obj
, objs
, index
);
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
);
3804 // we have a problem
3806 "[chuck](VM): OutOfMemory: while allocating arrays...\n" );
3809 negative_array_size
:
3810 // we have a problem
3812 "[chuck](VM): NegativeArraySize: while allocating arrays...\n" );
3816 // base shouldn't have been ref counted
3817 SAFE_DELETE( base
);
3824 //-----------------------------------------------------------------------------
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
;
3834 // the total number of objects to allocate
3835 t_CKUINT num_obj
= 0;
3836 // the index to pass to the arrays
3839 t_CKFLOAT num
= 1.0;
3841 t_CKUINT
* obj_array
= NULL
;
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);
3853 // product of all dims
3854 while( curr
<= top
)
3859 num
*= (t_CKFLOAT
)(*(curr
));
3860 if( num
> (t_CKFLOAT
)INT_MAX
) goto overflow
;
3865 // allocate array to hold elements, this array
3866 // is pushed on the reg stack, filled, and cleaned
3867 // during the array_post stage
3869 // TODO: this scheme results in potential leak
3870 // if intermediate memory allocations fail
3871 // and the array instantiation is aborted
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 )
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;
3890 // recursively allocate
3891 ref
= (t_CKUINT
)do_alloc_array(
3892 (t_CKINT
*)(reg_sp
- m_depth
),
3893 (t_CKINT
*)(reg_sp
- 1),
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
);
3904 assert( index
== (t_CKINT
)num_obj
);
3907 if( !ref
) goto error
;
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
3920 push_( reg_sp
, (t_CKUINT
)num_obj
);
3926 // we have a problem
3928 "[chuck](VM): OverFlow: requested array size too big...\n" );
3932 // we have a problem
3934 "[chuck](VM): OutOfMemory: while allocating arrays...\n" );
3939 "[chuck](VM): (note: in shred[id=%d:%s])\n", shred
->xid
, shred
->name
.c_str() );
3942 shred
->is_running
= FALSE
;
3943 shred
->is_done
= TRUE
;
3947 //-----------------------------------------------------------------------------
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;
3967 if( !(*sp
) ) goto null_pointer
;
3970 if( m_size
== 4 ) // ISSUE: 64-bit
3973 Chuck_Array4
* arr
= (Chuck_Array4
*)(*sp
);
3975 i
= (t_CKINT
)(*(sp
+1));
3979 val
= arr
->addr( i
);
3981 if( !val
) goto array_out_of_bound
;
3986 if( !arr
->get( i
, &val
) )
3987 goto array_out_of_bound
;
3992 else if( m_size
== 8 ) // ISSUE: 64-bit
3995 Chuck_Array8
* arr
= (Chuck_Array8
*)(*sp
);
3997 i
= (t_CKINT
)(*(sp
+1));
4001 val
= arr
->addr( i
);
4003 if( !val
) goto array_out_of_bound
;
4008 if( !arr
->get( i
, &fval
) )
4009 goto array_out_of_bound
;
4011 push_( ((t_CKFLOAT
*&)sp
), fval
);
4014 else if( m_size
== 16 ) // ISSUE: 64-bit
4017 Chuck_Array16
* arr
= (Chuck_Array16
*)(*sp
);
4019 i
= (t_CKINT
)(*(sp
+1));
4023 val
= arr
->addr( i
);
4025 if( !val
) goto array_out_of_bound
;
4030 if( !arr
->get( i
, &cval
) )
4031 goto array_out_of_bound
;
4033 push_( ((t_CKCOMPLEX
*&)sp
), cval
);
4042 // we have a problem
4044 "[chuck](VM): NullPointerException: (array access) in shred[id=%d:%s], PC=[%d]\n",
4045 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4049 // we have a problem
4051 "[chuck](VM): ArrayOutofBounds: in shred[id=%d:%s], PC=[%d], index=[%d]\n",
4052 shred
->xid
, shred
->name
.c_str(), shred
->pc
, i
);
4058 shred
->is_running
= FALSE
;
4059 shred
->is_done
= TRUE
;
4065 //-----------------------------------------------------------------------------
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
;
4084 if( !(*sp
) ) goto null_pointer
;
4087 if( m_size
== 4 ) // ISSUE: 64-bit
4090 Chuck_Array4
* arr
= (Chuck_Array4
*)(*sp
);
4092 key
= (Chuck_String
*)(*(sp
+1));
4096 val
= arr
->addr( key
->str
);
4098 if( !val
) goto error
;
4103 if( !arr
->get( key
->str
, &val
) )
4109 else if( m_size
== 8 ) // ISSUE: 64-bit
4112 Chuck_Array8
* arr
= (Chuck_Array8
*)(*sp
);
4114 key
= (Chuck_String
*)(*(sp
+1));
4118 val
= arr
->addr( key
->str
);
4120 if( !val
) goto error
;
4125 if( !arr
->get( key
->str
, &fval
) )
4128 push_( ((t_CKFLOAT
*&)sp
), fval
);
4131 else if( m_size
== 16 ) // ISSUE: 64-bit
4134 Chuck_Array16
* arr
= (Chuck_Array16
*)(*sp
);
4136 key
= (Chuck_String
*)(*(sp
+1));
4140 val
= arr
->addr( key
->str
);
4142 if( !val
) goto error
;
4147 if( !arr
->get( key
->str
, &cval
) )
4150 push_( ((t_CKCOMPLEX
*&)sp
), cval
);
4159 // we have a problem
4161 "[chuck](VM): NullPointerException: (map access) in shred[id=%d:%s], PC=[%d]\n",
4162 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4166 // we have a problem
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() );
4174 shred
->is_running
= FALSE
;
4175 shred
->is_done
= TRUE
;
4181 //-----------------------------------------------------------------------------
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
;
4190 t_CKUINT val
= 0, j
;
4193 t_CKINT
* ptr
= NULL
;
4198 // pop all indices then array
4199 pop_( sp
, m_depth
+ 1 );
4202 Chuck_Array4
* base
= (Chuck_Array4
*)(*sp
);
4203 ptr
= (t_CKINT
*)(sp
+1);
4206 if( !base
) goto null_pointer
;
4209 assert( m_depth
> 1 );
4210 // loop through indices
4211 for( j
= 0; j
< (m_depth
-1); j
++ )
4216 if( !base
->get( i
, &val
) )
4217 goto array_out_of_bound
;
4219 base
= (Chuck_Array4
*)val
;
4230 if( m_size
== 4 ) // ISSUE: 64-bit
4233 Chuck_Array4
* arr
= base
;
4235 i
= (t_CKINT
)(*ptr
);
4239 val
= arr
->addr( i
);
4241 if( !val
) goto array_out_of_bound
;
4246 if( !arr
->get( i
, &val
) )
4247 goto array_out_of_bound
;
4252 else if( m_size
== 8 ) // ISSUE: 64-bit
4255 Chuck_Array8
* arr
= (Chuck_Array8
*)(base
);
4257 i
= (t_CKINT
)(*ptr
);
4261 val
= arr
->addr( i
);
4263 if( !val
) goto array_out_of_bound
;
4268 if( !arr
->get( i
, &fval
) )
4269 goto array_out_of_bound
;
4271 push_( ((t_CKFLOAT
*&)sp
), fval
);
4274 else if( m_size
== 16 ) // ISSUE: 64-bit
4277 Chuck_Array16
* arr
= (Chuck_Array16
*)(base
);
4279 i
= (t_CKINT
)(*ptr
);
4283 val
= arr
->addr( i
);
4285 if( !val
) goto array_out_of_bound
;
4290 if( !arr
->get( i
, &cval
) )
4291 goto array_out_of_bound
;
4293 push_( ((t_CKCOMPLEX
*&)sp
), cval
);
4302 // we have a problem
4304 "[chuck](VM): NullPointerException: (array access) in shred[id=%d:%s], PC=[%d]\n",
4305 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4307 "[chuck](VM): (array dimension where exception occurred: %d)\n", index
);
4311 // we have a problem
4313 "[chuck](VM): ArrayOutofBounds: in shred[id=%d:%s], PC=[%d], index=[%d]\n",
4314 shred
->xid
, shred
->name
.c_str(), shred
->pc
, i
);
4320 shred
->is_running
= FALSE
;
4321 shred
->is_done
= TRUE
;
4327 //-----------------------------------------------------------------------------
4330 //-----------------------------------------------------------------------------
4331 void Chuck_Instr_Array_Prepend::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4338 //-----------------------------------------------------------------------------
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
;
4354 pop_( sp
, 1+(m_val
/4) );
4357 if( !(*sp
) ) goto null_pointer
;
4360 if( m_val
== 4 ) // ISSUE: 64-bit
4363 Chuck_Array4
* arr
= (Chuck_Array4
*)(*sp
);
4365 val
= (t_CKINT
)(*(sp
+1));
4367 arr
->push_back( val
);
4369 else if( m_val
== 8 ) // ISSUE: 64-bit
4372 Chuck_Array8
* arr
= (Chuck_Array8
*)(*sp
);
4374 fval
= (*(t_CKFLOAT
*)(sp
+1));
4376 arr
->push_back( fval
);
4378 else if( m_val
== 16 ) // ISSUE: 64-bit
4381 Chuck_Array16
* arr
= (Chuck_Array16
*)(*sp
);
4383 cval
= (*(t_CKCOMPLEX
*)(sp
+1));
4385 arr
->push_back( cval
);
4390 // push array back on stack
4396 // we have a problem
4398 "[chuck](VM): NullPointerException: (array append) in shred[id=%d:%s], PC=[%d]\n",
4399 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4404 shred
->is_running
= FALSE
;
4405 shred
->is_done
= TRUE
;
4411 //-----------------------------------------------------------------------------
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
;
4422 // pop the object pointer
4424 // get the object pointer
4425 Chuck_Object
* obj
= (Chuck_Object
*)(*sp
);
4427 if( !obj
) goto error
;
4428 // calculate the data pointer
4429 data
= (t_CKUINT
)(obj
->data
+ m_offset
);
4431 // emit addr or value
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
);
4449 // we have a problem
4451 "[chuck](VM): NullPointerException: shred[id=%d:%s:(%d)], PC=[%d]\n",
4452 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4455 shred
->is_running
= FALSE
;
4456 shred
->is_done
= TRUE
;
4462 //-----------------------------------------------------------------------------
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
;
4473 // pop the object pointer
4475 // get the object pointer
4476 Chuck_Object
* obj
= (Chuck_Object
*)(*sp
);
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
]);
4490 // we have a problem
4492 "[chuck](VM): NullPointerException: shred[id=%d:%s], PC=[%d]\n",
4493 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4496 shred
->is_running
= FALSE
;
4497 shred
->is_done
= TRUE
;
4503 //-----------------------------------------------------------------------------
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
;
4514 // pop the type pointer
4516 // get the object pointer
4517 Chuck_Type
* t_class
= (Chuck_Type
*)(*sp
);
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
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 //-----------------------------------------------------------------------------
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
4555 push_( sp
, (t_CKUINT
)m_addr
);
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 //-----------------------------------------------------------------------------
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
4583 push_( sp
, (t_CKUINT
)(m_func
) );
4589 //-----------------------------------------------------------------------------
4592 //-----------------------------------------------------------------------------
4593 void Chuck_Instr_Dot_Cmp_First::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4595 // reg contains pointer to complex elsewhere
4599 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
4604 // t_CKFLOAT a = (*(t_CKCOMPLEX **)sp)->re;
4605 push_( sp
, (t_CKUINT
)(&((*(t_CKCOMPLEX
**)sp
)->re
)) );
4607 push_float( sp
, (*(t_CKCOMPLEX
**)sp
)->re
);
4613 t_CKCOMPLEX
*& sp
= (t_CKCOMPLEX
*&)shred
->reg
->sp
;
4616 // push the addr, um we can't
4620 push_float( sp
, sp
->re
);
4628 //-----------------------------------------------------------------------------
4631 //-----------------------------------------------------------------------------
4632 void Chuck_Instr_Dot_Cmp_Second::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4634 // reg contains pointer to complex elsewhere
4638 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
4643 push_( sp
, (t_CKUINT
)(&((*(t_CKCOMPLEX
**)sp
)->im
)) );
4645 push_float( sp
, (*(t_CKCOMPLEX
**)sp
)->im
);
4651 t_CKCOMPLEX
*& sp
= (t_CKCOMPLEX
*&)shred
->reg
->sp
;
4654 // push the addr, um we can't
4658 push_float( sp
, sp
->im
);
4666 //-----------------------------------------------------------------------------
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
;
4675 push_( sp_int
, (t_CKINT
)(*sp
) );
4681 //-----------------------------------------------------------------------------
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
;
4690 push_( sp_double
, (t_CKFLOAT
)(*sp
) );
4696 //-----------------------------------------------------------------------------
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
;
4706 push_( sp_float
, (t_CKFLOAT
)(*sp
) );
4707 push_( sp_float
, (t_CKFLOAT
)0 );
4713 //-----------------------------------------------------------------------------
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
;
4723 push_( sp_float
, (t_CKFLOAT
)(*sp
) );
4724 push_( sp_float
, (t_CKFLOAT
)0 );
4730 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
4763 //-----------------------------------------------------------------------------
4764 void Chuck_Instr_Cast_complex2polar::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4766 t_CKCOMPLEX
* sp
= (t_CKCOMPLEX
*)shred
->reg
->sp
;
4769 t_CKPOLAR
* sp_polar
= (t_CKPOLAR
*)sp
;
4770 t_CKFLOAT modulus
, phase
;
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 //-----------------------------------------------------------------------------
4784 //-----------------------------------------------------------------------------
4785 void Chuck_Instr_Cast_polar2complex::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4787 t_CKPOLAR
* sp
= (t_CKPOLAR
*)shred
->reg
->sp
;
4790 t_CKCOMPLEX
* sp_complex
= (t_CKCOMPLEX
*)sp
;
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 //-----------------------------------------------------------------------------
4805 //-----------------------------------------------------------------------------
4806 void Chuck_Instr_Cast_object2string::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4808 t_CKUINT
*& sp
= (t_CKUINT
*&)shred
->reg
->sp
;
4812 Chuck_Object
* obj
= (Chuck_Object
*)(*sp
);
4814 Chuck_DL_Return RETURN
;
4815 // get toString from it
4816 object_toString( obj
, NULL
, &RETURN
, NULL
);
4817 Chuck_String
* str
= RETURN
.v_string
;
4819 push_( sp
, (t_CKUINT
)str
);
4825 //-----------------------------------------------------------------------------
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
;
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
;
4847 push_( sp
, lhs
->str
== rhs
->str
);
4851 push_( sp
, lhs
->str
!= rhs
->str
);
4855 push_( sp
, lhs
->str
< rhs
->str
);
4859 push_( sp
, lhs
->str
<= rhs
->str
);
4863 push_( sp
, lhs
->str
> rhs
->str
);
4867 push_( sp
, lhs
->str
>= rhs
->str
);
4878 // we have a problem
4880 "[chuck](VM): NullPointerException: (during string op) in shred[id=%d:%s], PC=[%d]\n",
4881 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4885 // we have a problem
4887 "[chuck](VM): InvalidStringOpException: '%d' in shred[id=%d:%s], PC=[%d]\n",
4888 m_val
, shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4893 shred
->is_running
= FALSE
;
4894 shred
->is_done
= TRUE
;
4900 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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()
4942 //-----------------------------------------------------------------------------
4943 Chuck_Instr_UGen_Link::Chuck_Instr_UGen_Link( t_CKBOOL isUpChuck
)
4945 m_isUpChuck
= isUpChuck
;
4951 //-----------------------------------------------------------------------------
4954 //-----------------------------------------------------------------------------
4955 void Chuck_Instr_UGen_Link::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4957 Chuck_UGen
**& sp
= (Chuck_UGen
**&)shred
->reg
->sp
;
4962 if( !*(sp
+1) || !(*sp
) ) goto null_pointer
;
4964 (*(sp
+ 1))->add( *sp
, m_isUpChuck
);
4966 push_( sp
, *(sp
+ 1) );
4971 // we have a problem
4973 "[chuck](VM): NullPointerException: (UGen link) in shred[id=%d:%s], PC=[%d]\n",
4974 shred
->xid
, shred
->name
.c_str(), shred
->pc
);
4977 shred
->is_running
= FALSE
;
4978 shred
->is_done
= TRUE
;
4984 //-----------------------------------------------------------------------------
4987 //-----------------------------------------------------------------------------
4988 void Chuck_Instr_UGen_UnLink::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
4990 Chuck_UGen
**& sp
= (Chuck_UGen
**&)shred
->reg
->sp
;
4993 (*(sp
+1))->remove( *sp
);
4994 push_( sp
, *(sp
+ 1) );
5000 //-----------------------------------------------------------------------------
5003 //-----------------------------------------------------------------------------
5004 void Chuck_Instr_UGen_Ctrl::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5006 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5009 Chuck_UGen * ugen = (Chuck_UGen *)*(sp+1);
5010 f_ctrl ctrl = (f_ctrl)*(sp+2);
5011 f_cget cget = (f_cget)*(sp+3);
5013 ugen->now = shred->now;
5015 ctrl( ugen, (void *)sp );
5016 if( cget ) cget( ugen, (void *)sp );
5017 // push the new value
5024 //-----------------------------------------------------------------------------
5027 //-----------------------------------------------------------------------------
5028 void Chuck_Instr_UGen_CGet::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5030 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5033 Chuck_UGen * ugen = (Chuck_UGen *)*(sp);
5034 f_cget cget = (f_cget)*(sp+1);
5036 ugen->now = shred->now;
5038 cget( ugen, (void *)sp );
5039 // push the new value
5046 //-----------------------------------------------------------------------------
5049 //-----------------------------------------------------------------------------
5050 void Chuck_Instr_UGen_Ctrl2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5052 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5055 Chuck_UGen * ugen = (Chuck_UGen *)*(sp+1);
5056 f_ctrl ctrl = (f_ctrl)*(sp+2);
5057 f_cget cget = (f_cget)*(sp+3);
5059 ugen->now = shred->now;
5062 ctrl( ugen, (void *)sp );
5063 if( cget ) cget( ugen, (void *)sp );
5064 // push the new value
5065 ((t_CKFLOAT *&)shred->reg->sp)++;
5071 //-----------------------------------------------------------------------------
5074 //-----------------------------------------------------------------------------
5075 void Chuck_Instr_UGen_CGet2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
5077 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
5080 Chuck_UGen * ugen = (Chuck_UGen *)*(sp);
5081 f_cget cget = (f_cget)*(sp+1);
5083 ugen->now = shred->now;
5085 cget( ugen, (void *)sp );
5086 // push the new value
5087 ((t_CKFLOAT *&)shred->reg->sp)++;
5093 //-----------------------------------------------------------------------------
5096 //-----------------------------------------------------------------------------
5097 void Chuck_Instr_UGen_PMsg::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
5099 Chuck_UGen
**& sp
= (Chuck_UGen
**&)shred
->reg
->sp
;
5103 // (*(sp + 1))->pmsg( shred->now, *sp );
5105 push_( sp
, *(sp
+ 1) );
5111 //-----------------------------------------------------------------------------
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
;
5123 (*(t_CKINT
*)m_val
) = *sp
>= 0 ? *sp
: -*sp
;
5129 //-----------------------------------------------------------------------------
5132 //-----------------------------------------------------------------------------
5133 void Chuck_Instr_IO_in_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
5140 //-----------------------------------------------------------------------------
5143 //-----------------------------------------------------------------------------
5144 void Chuck_Instr_IO_in_float::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
5151 //-----------------------------------------------------------------------------
5154 //-----------------------------------------------------------------------------
5155 void Chuck_Instr_IO_in_string::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
5162 //-----------------------------------------------------------------------------
5165 //-----------------------------------------------------------------------------
5166 void Chuck_Instr_IO_out_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
5173 //-----------------------------------------------------------------------------
5176 //-----------------------------------------------------------------------------
5177 void Chuck_Instr_IO_out_float::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
5184 //-----------------------------------------------------------------------------
5187 //-----------------------------------------------------------------------------
5188 void Chuck_Instr_IO_out_string::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
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
)
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
) )
5215 fprintf( stderr
, "%d :(%s)\n", *(sp
-1), m_type_ref
->c_name() );
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
;
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
;
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
;
5237 fprintf( stderr
, "%%(%.4f,%.4f*pi) :(%s)\n", *(sp
-2), *(sp
-1)/ONE_PI
, m_type_ref
->c_name() );
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() );
5255 const char * Chuck_Instr_Hack::params() const
5257 static char buffer
[256];
5258 sprintf( buffer
, "(%s)", m_type_ref
->c_name() );
5266 Chuck_Instr_Gack::Chuck_Instr_Gack( const std::vector
<Chuck_Type
*> & types
)
5268 m_type_refs
= types
;
5273 Chuck_Instr_Gack::~Chuck_Instr_Gack()
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
);
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
;
5300 for( i
= 0; i
< m_type_refs
.size(); i
++ )
5302 Chuck_Type
* type
= m_type_refs
[i
];
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
) )
5312 fprintf( stderr
, "0x%x ", *(sp
) );
5315 fprintf( stderr
, "%d ", *(sp
) );
5318 fprintf( stderr
, "%s ", ((Chuck_String
*)*(sp
))->str
.c_str() );
5322 else if( type
->size
== 8 ) // ISSUE: 64-bit
5324 t_CKFLOAT
* sp
= (t_CKFLOAT
*)the_sp
;
5326 fprintf( stderr
, "%f ", *(sp
) );
5330 else if( type
->size
== 16 ) // ISSUE: 64-bit
5332 t_CKFLOAT
* sp
= (t_CKFLOAT
*)the_sp
;
5333 if( type
->xid
== te_complex
)
5335 fprintf( stderr
, "#(%.4f,%.4f) ", *(sp
), *(sp
+1) );
5336 else if( type
->xid
== te_polar
)
5338 fprintf( stderr
, "%%(%.4f,%.4f*pi) ", *(sp
), *(sp
+1)/ONE_PI
);
5342 else if( type
->size
== 0 )
5344 fprintf( stderr
, "... " );
5350 fprintf( stderr
, "\n" );
5356 const char * Chuck_Instr_Gack::params() const
5358 static char buffer
[256];
5359 sprintf( buffer
, "( many types )" );