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 //-----------------------------------------------------------------------------
38 #include "chuck_instr.h"
40 #include "chuck_ugen.h"
41 #include "chuck_bbq.h"
43 #include "chuck_type.h"
49 #define push_( sp, val ) *(sp) = (val); (sp)++
50 #define push_uint( sp, val ) *((uint*&)sp) = val; ((uint*&)sp)++
51 #define pop_( sp, n ) sp -= (n)
52 #define val_( sp ) *(sp)
57 //-----------------------------------------------------------------------------
60 //-----------------------------------------------------------------------------
61 const char * Chuck_Instr::name() const
63 return typeid(*this).name();
69 //-----------------------------------------------------------------------------
72 //-----------------------------------------------------------------------------
73 void Chuck_Instr_Add_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
75 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
77 push_( sp
, val_(sp
) + val_(sp
+1) );
83 //-----------------------------------------------------------------------------
86 //-----------------------------------------------------------------------------
87 void Chuck_Instr_Inc_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
89 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
90 sint
*& reg_sp
= (sint
*&)shred
->reg
->sp
;
92 // pop word from reg stack
96 // copy value into mem stack
97 *( (sint
*)(mem_sp
+ *(reg_sp
)) ) = *(reg_sp
-1);
104 //-----------------------------------------------------------------------------
105 // name: class Chuck_Instr_Dec_int
107 //-----------------------------------------------------------------------------
108 void Chuck_Instr_Dec_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
110 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
111 sint
*& reg_sp
= (sint
*&)shred
->reg
->sp
;
113 // pop word from reg stack
117 // copy value into mem stack
118 *( (sint
*)(mem_sp
+ *(reg_sp
)) ) = *(reg_sp
-1);
124 //-----------------------------------------------------------------------------
127 //-----------------------------------------------------------------------------
128 void Chuck_Instr_Complement_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
130 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
131 (*(sp
-1)) = ~(*(sp
-1));
137 //-----------------------------------------------------------------------------
140 //-----------------------------------------------------------------------------
141 void Chuck_Instr_Mod_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
143 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
145 push_( sp
, val_(sp
) % val_(sp
+1) );
151 //-----------------------------------------------------------------------------
154 //-----------------------------------------------------------------------------
155 void Chuck_Instr_Minus_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
157 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
159 push_( sp
, val_(sp
) - val_(sp
+1) );
165 //-----------------------------------------------------------------------------
168 //-----------------------------------------------------------------------------
169 void Chuck_Instr_Times_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
171 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
173 push_( sp
, val_(sp
) * val_(sp
+1) );
179 //-----------------------------------------------------------------------------
182 //-----------------------------------------------------------------------------
183 void Chuck_Instr_Divide_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
185 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
187 push_( sp
, val_(sp
) / val_(sp
+1) );
194 //-----------------------------------------------------------------------------
197 //-----------------------------------------------------------------------------
198 void Chuck_Instr_Add_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
200 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
202 push_( sp
, val_(sp
) + val_(sp
+1) );
208 //-----------------------------------------------------------------------------
211 //-----------------------------------------------------------------------------
212 void Chuck_Instr_Inc_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
214 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
215 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
217 // pop word from reg stack
221 // copy value into mem stack
222 *( (uint
*)(mem_sp
+ *(reg_sp
)) ) = *(reg_sp
-1);
229 //-----------------------------------------------------------------------------
232 //-----------------------------------------------------------------------------
233 void Chuck_Instr_Dec_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
235 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
236 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
238 // pop word from reg stack
242 // copy value into mem stack
243 *( (uint
*)(mem_sp
+ *(reg_sp
)) ) = *(reg_sp
-1);
249 //-----------------------------------------------------------------------------
252 //-----------------------------------------------------------------------------
253 void Chuck_Instr_Complement_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
255 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
262 //-----------------------------------------------------------------------------
265 //-----------------------------------------------------------------------------
266 void Chuck_Instr_Mod_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
268 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
270 push_( sp
, val_(sp
) % val_(sp
+1) );
276 //-----------------------------------------------------------------------------
279 //-----------------------------------------------------------------------------
280 void Chuck_Instr_Minus_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
282 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
284 push_( sp
, val_(sp
) - val_(sp
+1) );
290 //-----------------------------------------------------------------------------
293 //-----------------------------------------------------------------------------
294 void Chuck_Instr_Times_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
296 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
298 push_( sp
, val_(sp
) * val_(sp
+1) );
304 //-----------------------------------------------------------------------------
307 //-----------------------------------------------------------------------------
308 void Chuck_Instr_Divide_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
310 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
312 push_( sp
, val_(sp
) / val_(sp
+1) );
319 //-----------------------------------------------------------------------------
322 //-----------------------------------------------------------------------------
323 void Chuck_Instr_Add_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
325 float *& sp
= (float *&)shred
->reg
->sp
;
327 push_( sp
, val_(sp
) + val_(sp
+1) );
333 //-----------------------------------------------------------------------------
336 //-----------------------------------------------------------------------------
337 void Chuck_Instr_Minus_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
339 float *& sp
= (float *&)shred
->reg
->sp
;
341 push_( sp
, val_(sp
) - val_(sp
+1) );
347 //-----------------------------------------------------------------------------
350 //-----------------------------------------------------------------------------
351 void Chuck_Instr_Times_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
353 float *& sp
= (float *&)shred
->reg
->sp
;
355 push_( sp
, val_(sp
) * val_(sp
+1) );
361 //-----------------------------------------------------------------------------
364 //-----------------------------------------------------------------------------
365 void Chuck_Instr_Divide_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
367 float *& sp
= (float *&)shred
->reg
->sp
;
369 push_( sp
, val_(sp
) / val_(sp
+1) );
376 //-----------------------------------------------------------------------------
379 //-----------------------------------------------------------------------------
380 void Chuck_Instr_Mod_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
382 float *& sp
= (float *&)shred
->reg
->sp
;
384 push_( sp
, (float)fmod( val_(sp
), val_(sp
+1) ) );
390 //-----------------------------------------------------------------------------
393 //-----------------------------------------------------------------------------
394 void Chuck_Instr_Add_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
396 double *& sp
= (double *&)shred
->reg
->sp
;
398 push_( sp
, val_(sp
) + val_(sp
+1) );
404 //-----------------------------------------------------------------------------
407 //-----------------------------------------------------------------------------
408 void Chuck_Instr_Minus_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
410 double *& sp
= (double *&)shred
->reg
->sp
;
412 push_( sp
, val_(sp
) - val_(sp
+1) );
418 //-----------------------------------------------------------------------------
421 //-----------------------------------------------------------------------------
422 void Chuck_Instr_Times_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
424 double *& sp
= (double *&)shred
->reg
->sp
;
426 push_( sp
, val_(sp
) * val_(sp
+1) );
432 //-----------------------------------------------------------------------------
435 //-----------------------------------------------------------------------------
436 void Chuck_Instr_Divide_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
438 double *& sp
= (double *&)shred
->reg
->sp
;
440 push_( sp
, val_(sp
) / val_(sp
+1) );
447 //-----------------------------------------------------------------------------
450 //-----------------------------------------------------------------------------
451 void Chuck_Instr_Mod_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
453 double *& sp
= (double *&)shred
->reg
->sp
;
455 push_( sp
, fmod( val_(sp
), val_(sp
+1) ) );
461 //-----------------------------------------------------------------------------
464 //-----------------------------------------------------------------------------
465 void Chuck_Instr_Reg_Push_Imm::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
467 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
469 // push val into reg stack
470 push_( reg_sp
, m_val
);
476 //-----------------------------------------------------------------------------
479 //-----------------------------------------------------------------------------
480 void Chuck_Instr_Reg_Push_Imm2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
482 double *& reg_sp
= (double *&)shred
->reg
->sp
;
484 // push val into reg stack
485 push_( reg_sp
, m_val
);
491 //-----------------------------------------------------------------------------
494 //-----------------------------------------------------------------------------
495 void Chuck_Instr_Reg_Push_Now::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
497 t_CKTIME
*& reg_sp
= (t_CKTIME
*&)shred
->reg
->sp
;
499 // push val into reg stack
500 push_( reg_sp
, shred
->now
);
506 //-----------------------------------------------------------------------------
509 //-----------------------------------------------------------------------------
510 void Chuck_Instr_Reg_Push_Start::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
512 t_CKTIME
*& reg_sp
= (t_CKTIME
*&)shred
->reg
->sp
;
514 // push val into reg stack
515 push_( reg_sp
, shred
->start
);
521 //-----------------------------------------------------------------------------
524 //-----------------------------------------------------------------------------
525 void Chuck_Instr_Reg_Push_Maybe::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
527 t_CKINT
*& reg_sp
= (t_CKINT
*&)shred
->reg
->sp
;
529 // push val into reg stack
530 float num
= (float)rand() / (float)RAND_MAX
;
531 push_( reg_sp
, num
> .5 );
537 //-----------------------------------------------------------------------------
540 //-----------------------------------------------------------------------------
541 void Chuck_Instr_Reg_Push_Deref::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
545 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
546 push_( reg_sp
, *((uint
*)m_val
) );
550 double *& reg_sp
= (double *&)shred
->reg
->sp
;
551 push_( reg_sp
, *((double *)m_val
) );
558 //-----------------------------------------------------------------------------
561 //-----------------------------------------------------------------------------
562 void Chuck_Instr_Reg_Push_Mem::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
564 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
565 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
567 // push mem stack content into reg stack
568 push_( reg_sp
, *((uint
*)(mem_sp
+ m_val
)) );
574 //-----------------------------------------------------------------------------
577 //-----------------------------------------------------------------------------
578 void Chuck_Instr_Reg_Push_Mem2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
580 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
581 double *& reg_sp
= (double *&)shred
->reg
->sp
;
583 // push mem stack content into reg stack
584 push_( reg_sp
, *((double *)(mem_sp
+ m_val
)) );
590 //-----------------------------------------------------------------------------
593 //-----------------------------------------------------------------------------
594 void Chuck_Instr_Reg_Pop_Mem::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
596 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
597 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
599 // pop word from reg stack
601 // copy popped value into mem stack
602 *((uint
*)(mem_sp
+ *(reg_sp
+1) )) = *reg_sp
;
608 //-----------------------------------------------------------------------------
611 //-----------------------------------------------------------------------------
612 void Chuck_Instr_Reg_Pop_Word::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
614 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
616 // pop word from reg stack
623 //-----------------------------------------------------------------------------
626 //-----------------------------------------------------------------------------
627 void Chuck_Instr_Reg_Pop_Word2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
629 double *& reg_sp
= (double *&)shred
->reg
->sp
;
631 // pop word from reg stack
638 //-----------------------------------------------------------------------------
641 //-----------------------------------------------------------------------------
642 void Chuck_Instr_Mem_Push_Imm::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
644 uint
*& mem_sp
= (uint
*&)shred
->mem
->sp
;
646 // pop word from reg stack
647 push_( mem_sp
, m_val
);
653 //-----------------------------------------------------------------------------
656 //-----------------------------------------------------------------------------
657 void Chuck_Instr_Mem_Push_Imm2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
659 double *& mem_sp
= (double *&)shred
->mem
->sp
;
661 // pop word from reg stack
662 push_( mem_sp
, m_val
);
668 //-----------------------------------------------------------------------------
671 //-----------------------------------------------------------------------------
672 void Chuck_Instr_Mem_Pop_Word::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
674 uint
*& mem_sp
= (uint
*&)shred
->mem
->sp
;
676 // pop word from reg stack
683 //-----------------------------------------------------------------------------
686 //-----------------------------------------------------------------------------
687 void Chuck_Instr_Mem_Pop_Word2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
689 double *& mem_sp
= (double *&)shred
->mem
->sp
;
691 // pop word from reg stack
698 //-----------------------------------------------------------------------------
701 //-----------------------------------------------------------------------------
702 void Chuck_Instr_Branch_Lt_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
704 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
706 if( val_(sp
) < val_(sp
+1) )
707 shred
->next_pc
= m_jmp
;
713 //-----------------------------------------------------------------------------
716 //-----------------------------------------------------------------------------
717 void Chuck_Instr_Branch_Gt_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
719 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
721 if( val_(sp
) > val_(sp
+1) )
722 shred
->next_pc
= m_jmp
;
728 //-----------------------------------------------------------------------------
731 //-----------------------------------------------------------------------------
732 void Chuck_Instr_Branch_Le_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
734 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
736 if( val_(sp
) <= val_(sp
+1) )
737 shred
->next_pc
= m_jmp
;
743 //-----------------------------------------------------------------------------
746 //-----------------------------------------------------------------------------
747 void Chuck_Instr_Branch_Ge_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
749 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
751 if( val_(sp
) >= val_(sp
+1) )
752 shred
->next_pc
= m_jmp
;
758 //-----------------------------------------------------------------------------
761 //-----------------------------------------------------------------------------
762 void Chuck_Instr_Branch_Eq_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
764 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
766 if( val_(sp
) == val_(sp
+1) )
767 shred
->next_pc
= m_jmp
;
773 //-----------------------------------------------------------------------------
776 //-----------------------------------------------------------------------------
777 void Chuck_Instr_Branch_Neq_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
779 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
781 if( val_(sp
) != val_(sp
+1) )
782 shred
->next_pc
= m_jmp
;
788 //-----------------------------------------------------------------------------
791 //-----------------------------------------------------------------------------
792 void Chuck_Instr_Not_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
794 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
795 (*(sp
-1)) = !(*(sp
-1));
801 //-----------------------------------------------------------------------------
804 //-----------------------------------------------------------------------------
805 void Chuck_Instr_Negate_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
807 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
808 (*(sp
-1)) = -(*(sp
-1));
814 //-----------------------------------------------------------------------------
817 //-----------------------------------------------------------------------------
818 void Chuck_Instr_Negate_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
820 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
821 sint
*& sp_int
= (sint
*&)shred
->reg
->sp
;
822 (*(sp_int
-1)) = -((sint
)(*(sp
-1)));
828 //-----------------------------------------------------------------------------
831 //-----------------------------------------------------------------------------
832 void Chuck_Instr_Negate_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
834 float *& sp
= (float *&)shred
->reg
->sp
;
835 (*(sp
-1)) = -(*(sp
-1));
841 //-----------------------------------------------------------------------------
844 //-----------------------------------------------------------------------------
845 void Chuck_Instr_Negate_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
847 double *& sp
= (double *&)shred
->reg
->sp
;
848 (*(sp
-1)) = -(*(sp
-1));
854 //-----------------------------------------------------------------------------
857 //-----------------------------------------------------------------------------
858 void Chuck_Instr_Branch_Lt_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
860 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
862 if( val_(sp
) < val_(sp
+1) )
863 shred
->next_pc
= m_jmp
;
869 //-----------------------------------------------------------------------------
872 //-----------------------------------------------------------------------------
873 void Chuck_Instr_Branch_Gt_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
875 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
877 if( val_(sp
) > val_(sp
+1) )
878 shred
->next_pc
= m_jmp
;
884 //-----------------------------------------------------------------------------
887 //-----------------------------------------------------------------------------
888 void Chuck_Instr_Branch_Le_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
890 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
892 if( val_(sp
) <= val_(sp
+1) )
893 shred
->next_pc
= m_jmp
;
899 //-----------------------------------------------------------------------------
902 //-----------------------------------------------------------------------------
903 void Chuck_Instr_Branch_Ge_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
905 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
907 if( val_(sp
) >= val_(sp
+1) )
908 shred
->next_pc
= m_jmp
;
914 //-----------------------------------------------------------------------------
917 //-----------------------------------------------------------------------------
918 void Chuck_Instr_Branch_Eq_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
920 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
922 if( val_(sp
) == val_(sp
+1) )
923 shred
->next_pc
= m_jmp
;
929 //-----------------------------------------------------------------------------
932 //-----------------------------------------------------------------------------
933 void Chuck_Instr_Branch_Neq_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
935 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
937 if( val_(sp
) != val_(sp
+1) )
938 shred
->next_pc
= m_jmp
;
944 //-----------------------------------------------------------------------------
947 //-----------------------------------------------------------------------------
948 void Chuck_Instr_Branch_Lt_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
950 float *& sp
= (float *&)shred
->reg
->sp
;
952 if( val_(sp
) < val_(sp
+1) )
953 shred
->next_pc
= m_jmp
;
959 //-----------------------------------------------------------------------------
962 //-----------------------------------------------------------------------------
963 void Chuck_Instr_Branch_Gt_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
965 float *& sp
= (float *&)shred
->reg
->sp
;
967 if( val_(sp
) > val_(sp
+1) )
968 shred
->next_pc
= m_jmp
;
974 //-----------------------------------------------------------------------------
977 //-----------------------------------------------------------------------------
978 void Chuck_Instr_Branch_Le_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
980 float *& sp
= (float *&)shred
->reg
->sp
;
982 if( val_(sp
) <= val_(sp
+1) )
983 shred
->next_pc
= m_jmp
;
989 //-----------------------------------------------------------------------------
992 //-----------------------------------------------------------------------------
993 void Chuck_Instr_Branch_Ge_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
995 float *& sp
= (float *&)shred
->reg
->sp
;
997 if( val_(sp
) >= val_(sp
+1) )
998 shred
->next_pc
= m_jmp
;
1004 //-----------------------------------------------------------------------------
1007 //-----------------------------------------------------------------------------
1008 void Chuck_Instr_Branch_Eq_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1010 float *& sp
= (float *&)shred
->reg
->sp
;
1012 if( val_(sp
) == val_(sp
+1) )
1013 shred
->next_pc
= m_jmp
;
1019 //-----------------------------------------------------------------------------
1022 //-----------------------------------------------------------------------------
1023 void Chuck_Instr_Branch_Neq_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1025 float *& sp
= (float *&)shred
->reg
->sp
;
1027 if( val_(sp
) != val_(sp
+1) )
1028 shred
->next_pc
= m_jmp
;
1034 //-----------------------------------------------------------------------------
1037 //-----------------------------------------------------------------------------
1038 void Chuck_Instr_Branch_Lt_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1040 double *& sp
= (double *&)shred
->reg
->sp
;
1042 if( val_(sp
) < val_(sp
+1) )
1043 shred
->next_pc
= m_jmp
;
1049 //-----------------------------------------------------------------------------
1052 //-----------------------------------------------------------------------------
1053 void Chuck_Instr_Branch_Gt_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1055 double *& sp
= (double *&)shred
->reg
->sp
;
1057 if( val_(sp
) > val_(sp
+1) )
1058 shred
->next_pc
= m_jmp
;
1064 //-----------------------------------------------------------------------------
1067 //-----------------------------------------------------------------------------
1068 void Chuck_Instr_Branch_Le_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1070 double *& sp
= (double *&)shred
->reg
->sp
;
1072 if( val_(sp
) <= val_(sp
+1) )
1073 shred
->next_pc
= m_jmp
;
1079 //-----------------------------------------------------------------------------
1082 //-----------------------------------------------------------------------------
1083 void Chuck_Instr_Branch_Ge_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1085 double *& sp
= (double *&)shred
->reg
->sp
;
1087 if( val_(sp
) >= val_(sp
+1) )
1088 shred
->next_pc
= m_jmp
;
1094 //-----------------------------------------------------------------------------
1097 //-----------------------------------------------------------------------------
1098 void Chuck_Instr_Branch_Eq_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1100 double *& sp
= (double *&)shred
->reg
->sp
;
1102 if( val_(sp
) == val_(sp
+1) )
1103 shred
->next_pc
= m_jmp
;
1109 //-----------------------------------------------------------------------------
1112 //-----------------------------------------------------------------------------
1113 void Chuck_Instr_Branch_Neq_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1115 double *& sp
= (double *&)shred
->reg
->sp
;
1117 if( val_(sp
) != val_(sp
+1) )
1118 shred
->next_pc
= m_jmp
;
1124 //-----------------------------------------------------------------------------
1127 //-----------------------------------------------------------------------------
1128 void Chuck_Instr_Binary_And::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1130 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1132 push_( sp
, val_(sp
) & val_(sp
+1) );
1138 //-----------------------------------------------------------------------------
1141 //-----------------------------------------------------------------------------
1142 void Chuck_Instr_Binary_Or::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1144 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1146 push_( sp
, val_(sp
) | val_(sp
+1) );
1152 //-----------------------------------------------------------------------------
1155 //-----------------------------------------------------------------------------
1156 void Chuck_Instr_Binary_Xor::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1158 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1160 push_( sp
, val_(sp
) ^ val_(sp
+1) );
1166 //-----------------------------------------------------------------------------
1169 //-----------------------------------------------------------------------------
1170 void Chuck_Instr_Binary_Shift_Right::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1172 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1174 push_( sp
, val_(sp
) >> val_(sp
+1) );
1180 //-----------------------------------------------------------------------------
1183 //-----------------------------------------------------------------------------
1184 void Chuck_Instr_Binary_Shift_Left::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1186 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1188 push_( sp
, val_(sp
) << val_(sp
+1) );
1194 //-----------------------------------------------------------------------------
1197 //-----------------------------------------------------------------------------
1198 void Chuck_Instr_Lt_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1200 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
1202 push_( sp
, val_(sp
) < val_(sp
+1) );
1208 //-----------------------------------------------------------------------------
1211 //-----------------------------------------------------------------------------
1212 void Chuck_Instr_Gt_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1214 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
1216 push_( sp
, val_(sp
) > val_(sp
+1) );
1222 //-----------------------------------------------------------------------------
1225 //-----------------------------------------------------------------------------
1226 void Chuck_Instr_Le_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1228 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
1230 push_( sp
, val_(sp
) <= val_(sp
+1) );
1236 //-----------------------------------------------------------------------------
1239 //-----------------------------------------------------------------------------
1240 void Chuck_Instr_Ge_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1242 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
1244 push_( sp
, val_(sp
) >= val_(sp
+1) );
1250 //-----------------------------------------------------------------------------
1253 //-----------------------------------------------------------------------------
1254 void Chuck_Instr_Eq_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1256 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
1258 push_( sp
, val_(sp
) == val_(sp
+1) );
1264 //-----------------------------------------------------------------------------
1267 //-----------------------------------------------------------------------------
1268 void Chuck_Instr_Neq_int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1270 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
1272 push_( sp
, val_(sp
) != val_(sp
+1) );
1278 //-----------------------------------------------------------------------------
1281 //-----------------------------------------------------------------------------
1282 void Chuck_Instr_Lt_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1284 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1286 push_( sp
, val_(sp
) < val_(sp
+1) );
1292 //-----------------------------------------------------------------------------
1295 //-----------------------------------------------------------------------------
1296 void Chuck_Instr_Gt_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1298 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1300 push_( sp
, val_(sp
) > val_(sp
+1) );
1306 //-----------------------------------------------------------------------------
1309 //-----------------------------------------------------------------------------
1310 void Chuck_Instr_Le_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1312 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1314 push_( sp
, val_(sp
) <= val_(sp
+1) );
1320 //-----------------------------------------------------------------------------
1323 //-----------------------------------------------------------------------------
1324 void Chuck_Instr_Ge_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1326 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1328 push_( sp
, val_(sp
) >= val_(sp
+1) );
1333 //-----------------------------------------------------------------------------
1336 //-----------------------------------------------------------------------------
1337 void Chuck_Instr_Eq_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1339 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1341 push_( sp
, val_(sp
) == val_(sp
+1) );
1347 //-----------------------------------------------------------------------------
1350 //-----------------------------------------------------------------------------
1351 void Chuck_Instr_Neq_uint::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1353 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1355 push_( sp
, val_(sp
) != val_(sp
+1) );
1361 //-----------------------------------------------------------------------------
1364 //-----------------------------------------------------------------------------
1365 void Chuck_Instr_Lt_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1367 float *& sp
= (float *&)shred
->reg
->sp
;
1369 push_uint( sp
, val_(sp
) < val_(sp
+1) );
1375 //-----------------------------------------------------------------------------
1378 //-----------------------------------------------------------------------------
1379 void Chuck_Instr_Gt_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1381 float *& sp
= (float *&)shred
->reg
->sp
;
1383 push_uint( sp
, val_(sp
) > val_(sp
+1) );
1389 //-----------------------------------------------------------------------------
1392 //-----------------------------------------------------------------------------
1393 void Chuck_Instr_Le_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1395 float *& sp
= (float *&)shred
->reg
->sp
;
1397 push_uint( sp
, val_(sp
) <= val_(sp
+1) );
1403 //-----------------------------------------------------------------------------
1406 //-----------------------------------------------------------------------------
1407 void Chuck_Instr_Ge_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1409 float *& sp
= (float *&)shred
->reg
->sp
;
1411 push_uint( sp
, val_(sp
) >= val_(sp
+1) );
1416 //-----------------------------------------------------------------------------
1419 //-----------------------------------------------------------------------------
1420 void Chuck_Instr_Eq_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1422 float *& sp
= (float *&)shred
->reg
->sp
;
1424 push_uint( sp
, val_(sp
) == val_(sp
+1) );
1430 //-----------------------------------------------------------------------------
1433 //-----------------------------------------------------------------------------
1434 void Chuck_Instr_Neq_single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1436 float *& sp
= (float *&)shred
->reg
->sp
;
1438 push_uint( sp
, val_(sp
) != val_(sp
+1) );
1444 //-----------------------------------------------------------------------------
1447 //-----------------------------------------------------------------------------
1448 void Chuck_Instr_Lt_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1450 double *& sp
= (double *&)shred
->reg
->sp
;
1452 push_uint( sp
, val_(sp
) < val_(sp
+1) );
1458 //-----------------------------------------------------------------------------
1461 //-----------------------------------------------------------------------------
1462 void Chuck_Instr_Gt_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1464 double *& sp
= (double *&)shred
->reg
->sp
;
1466 push_uint( sp
, val_(sp
) > val_(sp
+1) );
1472 //-----------------------------------------------------------------------------
1475 //-----------------------------------------------------------------------------
1476 void Chuck_Instr_Le_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1478 double *& sp
= (double *&)shred
->reg
->sp
;
1480 push_uint( sp
, val_(sp
) <= val_(sp
+1) );
1486 //-----------------------------------------------------------------------------
1489 //-----------------------------------------------------------------------------
1490 void Chuck_Instr_Ge_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1492 double *& sp
= (double *&)shred
->reg
->sp
;
1494 push_uint( sp
, val_(sp
) >= val_(sp
+1) );
1499 //-----------------------------------------------------------------------------
1502 //-----------------------------------------------------------------------------
1503 void Chuck_Instr_Eq_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1505 double *& sp
= (double *&)shred
->reg
->sp
;
1507 push_uint( sp
, val_(sp
) == val_(sp
+1) );
1513 //-----------------------------------------------------------------------------
1516 //-----------------------------------------------------------------------------
1517 void Chuck_Instr_Neq_double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1519 double *& sp
= (double *&)shred
->reg
->sp
;
1521 push_uint( sp
, val_(sp
) != val_(sp
+1) );
1527 //-----------------------------------------------------------------------------
1530 //-----------------------------------------------------------------------------
1531 void Chuck_Instr_And::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1533 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1535 push_( sp
, val_(sp
) && val_(sp
+1) );
1541 //-----------------------------------------------------------------------------
1544 //-----------------------------------------------------------------------------
1545 void Chuck_Instr_Or::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1547 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
1549 push_( sp
, val_(sp
) || val_(sp
+1) );
1555 //-----------------------------------------------------------------------------
1558 //-----------------------------------------------------------------------------
1559 void Chuck_Instr_Goto::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1561 shred
->next_pc
= m_jmp
;
1567 //-----------------------------------------------------------------------------
1570 //-----------------------------------------------------------------------------
1571 void Chuck_Instr_Nop::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1579 //-----------------------------------------------------------------------------
1582 //-----------------------------------------------------------------------------
1583 void Chuck_Instr_EOC::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1586 shred
->is_done
= TRUE
;
1587 shred
->is_running
= FALSE
;
1593 //-----------------------------------------------------------------------------
1596 //-----------------------------------------------------------------------------
1597 void Chuck_Instr_Chuck_Assign::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1599 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
1600 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1602 // pop word from reg stack
1604 // copy popped value into mem stack
1605 *( (uint
*)(mem_sp
+ *(reg_sp
+1)) ) = *reg_sp
;
1607 push_( reg_sp
, *reg_sp
);
1613 //-----------------------------------------------------------------------------
1616 //-----------------------------------------------------------------------------
1617 void Chuck_Instr_Chuck_Assign2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1619 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
1620 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1622 // pop word from reg stack
1624 // copy popped value into mem stack
1625 *( (double *)(mem_sp
+ *(reg_sp
+2)) ) = *(double *)reg_sp
;
1627 double *& sp_double
= (double *&)reg_sp
;
1628 push_( sp_double
, *sp_double
);
1634 //-----------------------------------------------------------------------------
1637 //-----------------------------------------------------------------------------
1638 void Chuck_Instr_Chuck_Assign_Deref::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1640 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1642 // pop word from reg stack
1644 // copy popped value into mem stack
1645 *( (uint
*)(*(reg_sp
+1)) ) = *reg_sp
;
1647 push_( reg_sp
, *reg_sp
);
1653 //-----------------------------------------------------------------------------
1656 //-----------------------------------------------------------------------------
1657 void Chuck_Instr_Chuck_Assign_Deref2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1659 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1661 // pop word from reg stack
1663 // copy popped value into mem stack
1664 *( (double *)(*(reg_sp
+2)) ) = *(double *)reg_sp
;
1666 double *& sp_double
= (double *&)reg_sp
;
1667 push_( sp_double
, *sp_double
);
1673 //-----------------------------------------------------------------------------
1676 //-----------------------------------------------------------------------------
1677 void Chuck_Instr_Chuck_Assign_Object::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1679 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
1680 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1682 // pop word from reg stack
1684 // release any previous reference
1685 Chuck_VM_Object
** obj
= (Chuck_VM_Object
**)(mem_sp
+ *(reg_sp
+1));
1686 // if( *obj ) (*obj)->release();
1687 // copy popped value into mem stack
1688 *obj
= *(Chuck_VM_Object
**)reg_sp
;
1690 (*(Chuck_VM_Object
**)reg_sp
)->add_ref();
1692 push_( reg_sp
, *reg_sp
);
1698 //-----------------------------------------------------------------------------
1701 //-----------------------------------------------------------------------------
1702 void Chuck_Instr_Chuck_Release_Object::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1704 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
1705 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1706 Chuck_VM_Object
* obj
= NULL
;
1708 // pop word from reg stack
1710 // copy popped value into mem stack
1711 obj
= *( (Chuck_VM_Object
**)(mem_sp
+ *(reg_sp
)) );
1719 //-----------------------------------------------------------------------------
1722 //-----------------------------------------------------------------------------
1723 void Chuck_Instr_Chuck_Assign_Object_Deref::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1725 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1727 // pop word from reg stack
1729 // copy popped value into mem stack
1730 *( (uint
*)(*(reg_sp
+1)) ) = *reg_sp
;
1732 ( *((Chuck_VM_Object
**)reg_sp
) )->add_ref();
1734 push_( reg_sp
, *reg_sp
);
1740 //-----------------------------------------------------------------------------
1743 //-----------------------------------------------------------------------------
1744 void Chuck_Instr_Chuck_Assign_Object2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1746 BYTE__
*& mem_sp
= (BYTE__
*&)shred
->mem
->sp
;
1747 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1749 // pop word from reg stack
1751 // copy popped value into mem stack
1752 *( (uint
*)(mem_sp
+ *reg_sp
) ) = *(reg_sp
+1);
1754 ( *((Chuck_VM_Object
**)(reg_sp
+1)) )->add_ref();
1756 push_( reg_sp
, *(reg_sp
+1) );
1762 //-----------------------------------------------------------------------------
1765 //-----------------------------------------------------------------------------
1766 void Chuck_Instr_Func_Call::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1768 uint
*& mem_sp
= (uint
*&)shred
->mem
->sp
;
1769 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1773 Chuck_VM_Code
* func
= (Chuck_VM_Code
*)*reg_sp
;
1774 uint local_depth
= *(reg_sp
+1);
1775 local_depth
= ( local_depth
>> 2 ) + ( local_depth
& 0x3 ? 1 : 0 );
1776 uint stack_depth
= ( func
->stack_depth
>> 2 ) + ( func
->stack_depth
& 0x3 ? 1 : 0 );
1777 uint prev_stack
= ( *(mem_sp
-1) >> 2 ) + ( *(mem_sp
-1) & 0x3 ? 1 : 0 );
1780 mem_sp
+= prev_stack
+ local_depth
;
1781 // push the prev stack
1782 push_( mem_sp
, prev_stack
+ local_depth
);
1783 // push the current function
1784 push_( mem_sp
, (uint
)shred
->code
);
1786 push_( mem_sp
, (uint
)(shred
->pc
+ 1) );
1787 // push the stack depth
1788 push_( mem_sp
, stack_depth
);
1793 shred
->instr
= func
->instr
;
1797 BYTE__
*& mem_sp2
= (BYTE__
*&)mem_sp
;
1798 BYTE__
*& reg_sp2
= (BYTE__
*&)reg_sp
;
1800 // pop the arguments
1801 pop_( reg_sp2
, stack_depth
<< 2 );
1802 // push the arguments
1803 memcpy( mem_sp2
, reg_sp2
, stack_depth
<< 2 );
1810 //-----------------------------------------------------------------------------
1813 //-----------------------------------------------------------------------------
1814 void Chuck_Instr_Func_Call2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1816 uint
*& mem_sp
= (uint
*&)shred
->mem
->sp
;
1817 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1818 Chuck_DL_Return retval
;
1821 f_ck_func f
= (f_ck_func
)(*(reg_sp
+1));
1822 uint stack_size
= ((*reg_sp
) >> 2) + ( *reg_sp
& 0x3 ? 1 : 0 );
1823 uint local_depth
= *(reg_sp
+2) + *(mem_sp
-1);
1824 uint push
= ((local_depth
) >> 2) + ( local_depth
& 0x3 ? 1 : 0 );
1825 reg_sp
-= stack_size
;
1828 uint
* mem
= mem_sp
;
1830 for( uint i
= 0; i
< stack_size
; i
++ )
1832 // call the function
1833 f( mem_sp
, &retval
);
1835 // push the return args
1836 push_( reg_sp
, retval
.v_uint
);
1842 //-----------------------------------------------------------------------------
1845 //-----------------------------------------------------------------------------
1846 void Chuck_Instr_Func_Call3::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1848 uint
*& mem_sp
= (uint
*&)shred
->mem
->sp
;
1849 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1850 Chuck_DL_Return retval
;
1853 f_ck_func f
= (f_ck_func
)(*(reg_sp
+1));
1854 uint stack_size
= ((*reg_sp
) >> 2) + ( *reg_sp
& 0x3 ? 1 : 0 );
1855 uint local_depth
= *(reg_sp
+2) + *(mem_sp
-1);
1856 uint push
= (local_depth
>> 2) + ( local_depth
& 0x3 ? 1 : 0 );
1857 reg_sp
-= stack_size
;
1860 uint
* mem
= mem_sp
;
1862 for( uint i
= 0; i
< stack_size
; i
++ )
1864 // call the function
1865 f( mem_sp
, &retval
);
1867 // push the return args
1868 double *& sp_double
= (double *&)reg_sp
;
1869 push_( sp_double
, retval
.v_float
);
1875 //-----------------------------------------------------------------------------
1878 //-----------------------------------------------------------------------------
1879 void Chuck_Instr_Func_Call0::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1881 uint
*& mem_sp
= (uint
*&)shred
->mem
->sp
;
1882 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1883 Chuck_DL_Return retval
;
1886 f_ck_func f
= (f_ck_func
)(*(reg_sp
+1));
1887 uint stack_size
= ((*reg_sp
) >> 2) + ( *reg_sp
& 0x3 ? 1 : 0 );
1888 uint local_depth
= *(reg_sp
+2) + *(mem_sp
-1);
1889 uint push
= (local_depth
>> 2) + ( local_depth
& 0x3 ? 1 : 0 );
1890 reg_sp
-= stack_size
;
1893 uint
* mem
= mem_sp
;
1895 for( uint i
= 0; i
< stack_size
; i
++ )
1897 // call the function
1898 f( mem_sp
, &retval
);
1900 // push the return args
1901 // push_( reg_sp, retval.v_uint );
1907 //-----------------------------------------------------------------------------
1910 //-----------------------------------------------------------------------------
1911 void Chuck_Instr_Func_Return::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1913 uint
*& mem_sp
= (uint
*&)shred
->mem
->sp
;
1914 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1918 shred
->next_pc
= *mem_sp
;
1921 Chuck_VM_Code
* func
= (Chuck_VM_Code
*)*mem_sp
;
1922 // pop the prev_stack
1924 // jump the prev stack
1925 mem_sp
-= *(mem_sp
);
1929 shred
->instr
= func
->instr
;
1935 //-----------------------------------------------------------------------------
1938 //-----------------------------------------------------------------------------
1939 void Chuck_Instr_Spork::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1941 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
1946 Chuck_VM_Code
* code
= *(Chuck_VM_Code
**)reg_sp
;
1948 Chuck_VM_Shred
* sh
= vm
->spork( code
, shred
);
1952 pop_( shred
->reg
->sp
, m_val
);
1953 memcpy( sh
->reg
->sp
, shred
->reg
->sp
, m_val
);
1954 sh
->reg
->sp
+= m_val
;
1957 push_( reg_sp
, sh
->id
);
1963 //-----------------------------------------------------------------------------
1966 //-----------------------------------------------------------------------------
1967 void Chuck_Instr_Time_Advance::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
1969 t_CKTIME
*& sp
= (t_CKTIME
*&)shred
->reg
->sp
;
1971 // pop word from reg stack
1974 if( *sp
< shred
->now
)
1976 // we have a problem
1978 "[chuck](VM): Exception DestTimeNegative: '%.6f'\n", *sp
);
1980 shred
->is_running
= FALSE
;
1985 // shredule the shred
1986 vm
->shreduler()->shredule( shred
, *sp
);
1988 shred
->is_running
= FALSE
;
1996 //-----------------------------------------------------------------------------
1999 //-----------------------------------------------------------------------------
2000 void Chuck_Instr_Add_dur_time::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2002 t_CKTIME
*& p
= (t_CKTIME
*&)shred
->reg
->sp
;
2006 t_CKDUR
*& sp
= (t_CKDUR
*&)shred
->reg
->sp
;
2010 push_( sp
, (t_CKTIME
)( d
+ (t_CKDUR
)t
) );
2015 //-----------------------------------------------------------------------------
2018 //-----------------------------------------------------------------------------
2019 void Chuck_Instr_Midi_Out::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2021 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2024 pop_( sp
, m_val
? 1 : 0 );
2026 // send the word as midi msg
2027 MidiOut
* out
= vm
->bbq()->midi_out( m_val
? *(sp
) : 0 );
2028 if( !out
&& vm
->bbq()->out_count( m_val
? *(sp
) : 0 ) < 2 )
2029 fprintf( stderr
, "[chuck](VM): cannot open MIDI output device # '%i'...\n",
2030 m_val
? *(sp
) : 0 );
2033 push_( sp
, (uint
)out
);
2039 //-----------------------------------------------------------------------------
2042 //-----------------------------------------------------------------------------
2043 void Chuck_Instr_Midi_Out_Go::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2046 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2051 uint v
= *( m_val
? sp
+1 : sp
);
2052 msg
.data
[0] = (v
>> 16) & 0xff;
2053 msg
.data
[1] = (v
>> 8) & 0xff;
2054 msg
.data
[2] = (v
) & 0xff;
2056 // send the word as midi msg
2057 MidiOut
* out
= *(MidiOut
**)( m_val
? (sp
) : sp
+1 );
2058 if( out
) out
->send( &msg
);
2061 push_( sp
, (uint
)out
);
2067 //-----------------------------------------------------------------------------
2070 //-----------------------------------------------------------------------------
2071 void Chuck_Instr_Midi_In::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2073 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2075 if( m_val
) pop_( sp
, 1 );
2076 MidiIn
* in
= vm
->bbq()->midi_in( m_val
? *(sp
) : 0 );
2077 if( !in
&& vm
->bbq()->in_count( m_val
? *(sp
) : 0 ) < 2 )
2079 fprintf( stderr
, "[chuck](VM): cannot open MIDI input device '%i'...\n",
2080 m_val
? *(sp
) : 0 );
2083 push_( sp
, (uint
)in
);
2089 //-----------------------------------------------------------------------------
2092 //-----------------------------------------------------------------------------
2093 void Chuck_Instr_Midi_In_Go::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2096 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2099 MidiIn
* in
= *(MidiIn
**)sp
;
2106 if( in
->recv( &msg
) )
2108 // msg2.data[0] = msg.data[3];
2109 // msg2.data[1] = msg.data[2];
2110 // msg2.data[2] = msg.data[1];
2111 // msg2.data[3] = msg.data[0];
2112 push_( sp
, *((uint
*)&msg
) );
2123 //-----------------------------------------------------------------------------
2126 //-----------------------------------------------------------------------------
2127 void Chuck_Instr_ADC::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2129 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
2130 push_( reg_sp
, (uint
)vm
->m_adc
);
2136 //-----------------------------------------------------------------------------
2139 //-----------------------------------------------------------------------------
2140 void Chuck_Instr_DAC::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2142 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
2143 push_( reg_sp
, (uint
)vm
->m_dac
);
2149 //-----------------------------------------------------------------------------
2152 //-----------------------------------------------------------------------------
2153 void Chuck_Instr_Bunghole::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2155 uint
*& reg_sp
= (uint
*&)shred
->reg
->sp
;
2156 push_( reg_sp
, (uint
)vm
->m_bunghole
);
2162 //-----------------------------------------------------------------------------
2165 //-----------------------------------------------------------------------------
2166 void Chuck_Instr_UGen_Link::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2168 Chuck_UGen
**& sp
= (Chuck_UGen
**&)shred
->reg
->sp
;
2171 (*(sp
+ 1))->add( *sp
);
2172 push_( sp
, *(sp
+ 1) );
2178 //-----------------------------------------------------------------------------
2181 //-----------------------------------------------------------------------------
2182 void Chuck_Instr_UGen_UnLink::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2184 Chuck_UGen
**& sp
= (Chuck_UGen
**&)shred
->reg
->sp
;
2187 (*(sp
+1))->remove( *sp
);
2188 push_( sp
, *(sp
+ 1) );
2194 //-----------------------------------------------------------------------------
2197 //-----------------------------------------------------------------------------
2198 void Chuck_Instr_UGen_Alloc::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2200 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2201 Chuck_UGen_Info
* info
= NULL
;
2202 Chuck_UGen
* ugen
= NULL
;
2205 info
= (Chuck_UGen_Info
*)*(sp
);
2206 ugen
= new Chuck_UGen
;
2207 // copy the info over
2208 ugen
->ctor
= info
->ctor
;
2209 ugen
->dtor
= info
->dtor
;
2210 ugen
->tick
= info
->tick
;
2211 ugen
->pmsg
= info
->pmsg
;
2212 ugen
->m_max_src
= info
->max_src
;
2213 // call the constructor
2214 ugen
->state
= ugen
->ctor
? ugen
->ctor( shred
->now
) : NULL
;
2216 // setup the reference with the shred
2217 ugen
->shred
= shred
;
2219 push_( sp
, (uint
)ugen
);
2225 //-----------------------------------------------------------------------------
2228 //-----------------------------------------------------------------------------
2229 void Chuck_Instr_UGen_DeAlloc::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2236 //-----------------------------------------------------------------------------
2239 //-----------------------------------------------------------------------------
2240 void Chuck_Instr_UGen_Ctrl::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2242 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2245 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
+1);
2246 f_ctrl ctrl
= (f_ctrl
)*(sp
+2);
2247 f_cget cget
= (f_cget
)*(sp
+3);
2249 ctrl( shred
->now
, ugen
->state
, (void *)sp
);
2250 if( cget
) cget( shred
->now
, ugen
->state
, (void *)sp
);
2251 // push the new value
2258 //-----------------------------------------------------------------------------
2261 //-----------------------------------------------------------------------------
2262 void Chuck_Instr_UGen_CGet::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2264 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2267 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
);
2268 f_cget cget
= (f_cget
)*(sp
+1);
2270 cget( shred
->now
, ugen
->state
, (void *)sp
);
2271 // push the new value
2278 //-----------------------------------------------------------------------------
2281 //-----------------------------------------------------------------------------
2282 void Chuck_Instr_UGen_Ctrl2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2284 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2287 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
+1);
2288 f_ctrl ctrl
= (f_ctrl
)*(sp
+2);
2289 f_cget cget
= (f_cget
)*(sp
+3);
2292 ctrl( shred
->now
, ugen
->state
, (void *)sp
);
2293 if( cget
) cget( shred
->now
, ugen
->state
, (void *)sp
);
2294 // push the new value
2295 ((double *&)shred
->reg
->sp
)++;
2301 //-----------------------------------------------------------------------------
2304 //-----------------------------------------------------------------------------
2305 void Chuck_Instr_UGen_CGet2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2307 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2310 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
);
2311 f_cget cget
= (f_cget
)*(sp
+1);
2313 cget( shred
->now
, ugen
->state
, (void *)sp
);
2314 // push the new value
2315 ((double *&)shred
->reg
->sp
)++;
2321 //-----------------------------------------------------------------------------
2324 //-----------------------------------------------------------------------------
2325 void Chuck_Instr_UGen_PMsg::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2327 Chuck_UGen
**& sp
= (Chuck_UGen
**&)shred
->reg
->sp
;
2331 // (*(sp + 1))->pmsg( shred->now, *sp );
2333 push_( sp
, *(sp
+ 1) );
2339 //-----------------------------------------------------------------------------
2342 //-----------------------------------------------------------------------------
2343 void Chuck_Instr_UGen_Ctrl_Op::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2345 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2348 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
+1);
2349 ugen
->m_op
= *(sint
*)sp
;
2350 // push the new value
2357 //-----------------------------------------------------------------------------
2360 //-----------------------------------------------------------------------------
2361 void Chuck_Instr_UGen_CGet_Op::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2363 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2366 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
);
2367 // push the new value
2368 push_( sp
, ugen
->m_op
);
2374 //-----------------------------------------------------------------------------
2377 //-----------------------------------------------------------------------------
2378 void Chuck_Instr_UGen_Ctrl_Gain::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2380 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2382 // HACK: this won't work for 64-bit long
2383 ((Chuck_UGen
*)*(sp
-3))->m_gain
= (float)*(double *)(sp
-5);
2386 // push the new value
2387 ((double *&)shred
->reg
->sp
)++;
2393 //-----------------------------------------------------------------------------
2396 //-----------------------------------------------------------------------------
2397 void Chuck_Instr_UGen_CGet_Gain::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2399 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2402 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
);
2403 // push the new value
2404 double *& sp_double
= (double *&)shred
->reg
->sp
;
2405 push_( sp_double
, (double)ugen
->m_gain
);
2411 //-----------------------------------------------------------------------------
2414 //-----------------------------------------------------------------------------
2415 void Chuck_Instr_UGen_CGet_Last::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2417 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2420 Chuck_UGen
* ugen
= (Chuck_UGen
*)*(sp
);
2421 // push the new value
2422 double *& sp_double
= (double *&)shred
->reg
->sp
;
2423 push_( sp_double
, (double)ugen
->m_current
);
2429 //-----------------------------------------------------------------------------
2432 //-----------------------------------------------------------------------------
2433 void Chuck_Instr_DLL_Load::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2435 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2436 sint retval
= FALSE
;
2437 Chuck_DLL
* dll
= NULL
;
2440 // load the DLL into the vm
2441 dll
= vm
->dll_load( (const char *)(*sp
) );
2442 // load the DLL into the namespace
2443 if( dll
) retval
= type_engine_add_dll( (t_Env
)vm
->get_env(), dll
,
2444 (const char *)(*(sp
+1)) );
2447 push_( sp
, (uint
)dll
);
2453 //-----------------------------------------------------------------------------
2456 //-----------------------------------------------------------------------------
2457 void Chuck_Instr_DLL_Unload::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2459 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2460 sint retval
= FALSE
;
2461 Chuck_DLL
* dll
= NULL
;
2465 dll
= (Chuck_DLL
*)(*sp
);
2466 if( dll
) retval
= vm
->dll_unload( dll
);
2469 push_( sp
, retval
);
2475 //-----------------------------------------------------------------------------
2478 //-----------------------------------------------------------------------------
2479 void Chuck_Instr_Cast_single2int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2481 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
2483 push_( sp
, (sint
)*(float *)sp
);
2489 //-----------------------------------------------------------------------------
2492 //-----------------------------------------------------------------------------
2493 void Chuck_Instr_Cast_int2single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2495 float *& sp
= (float *&)shred
->reg
->sp
;
2497 push_( sp
, (float)*(sint
*)sp
);
2503 //-----------------------------------------------------------------------------
2506 //-----------------------------------------------------------------------------
2507 void Chuck_Instr_Cast_double2int::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2509 double *& sp
= (double *&)shred
->reg
->sp
;
2510 sint
*& sp_int
= (sint
*&)sp
;
2512 push_( sp_int
, (sint
)(*sp
) );
2518 //-----------------------------------------------------------------------------
2521 //-----------------------------------------------------------------------------
2522 void Chuck_Instr_Cast_int2double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2524 sint
*& sp
= (sint
*&)shred
->reg
->sp
;
2525 double *& sp_double
= (double *&)sp
;
2527 push_( sp_double
, (double)(*sp
) );
2533 //-----------------------------------------------------------------------------
2536 //-----------------------------------------------------------------------------
2537 void Chuck_Instr_Cast_double2single::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2539 double *& sp
= (double *&)shred
->reg
->sp
;
2540 float *& sp_float
= (float *&)sp
;
2542 push_( sp_float
, (float)(*sp
) );
2548 //-----------------------------------------------------------------------------
2551 //-----------------------------------------------------------------------------
2552 void Chuck_Instr_Cast_single2double::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2554 float *& sp
= (float *&)shred
->reg
->sp
;
2555 double *& sp_double
= (double *&)sp
;
2557 push_( sp_double
, (double)(*sp
) );
2563 //-----------------------------------------------------------------------------
2566 //-----------------------------------------------------------------------------
2567 void Chuck_Instr_Print_Console::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2569 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2573 // pop word from reg stack
2595 "[chuck virtual machine]: Exception UnknownTypeToStdout '%u'\n",
2603 fprintf( stdout
, "%i\n", *((sint
*)sp
) );
2606 fprintf( stdout
, "%u\n", *((uint
*)sp
) );
2609 fprintf( stdout
, "%.6f\n", *((double *)sp
) );
2612 fprintf( stdout
, "%.6f\n", *((double *)sp
) );
2615 fprintf( stdout
, "%s\n", *((char **)sp
) );
2618 fprintf( stdout
, "dur=%.4fs\n", *((t_CKDUR
*)sp
) / (double)Digitalio::sampling_rate() );
2621 fprintf( stdout
, "time=%.4fs\n", *((t_CKTIME
*)sp
) / (double)Digitalio::sampling_rate() );
2625 // push the data back
2626 double *& sp_double
= (double *&)sp
;
2633 push_( sp_double
, *sp_double
);
2640 //-----------------------------------------------------------------------------
2643 //-----------------------------------------------------------------------------
2644 void Chuck_Instr_Print_Console2::execute( Chuck_VM
* vm
, Chuck_VM_Shred
* shred
)
2646 uint
*& sp
= (uint
*&)shred
->reg
->sp
;
2650 // pop word from reg stack
2672 "[chuck virtual machine]: Exception UnknownTypeToStdout '%u'\n",
2680 fprintf( stderr
, "%i", *((sint
*)(sp
+1)) );
2683 fprintf( stderr
, "%u", *((uint
*)(sp
+1)) );
2686 fprintf( stderr
, "%.6f", *((double *)(sp
+1)) );
2690 fprintf( stderr
, "%.6f", *((double *)(sp
+1)) );
2693 fprintf( stderr
, "%s", *((char **)(sp
+1)) );
2696 fprintf( stderr
, "%.4fs", *((t_CKDUR
*)(sp
+1)) / (double)Digitalio::sampling_rate() );
2699 fprintf( stderr
, "%.4fs", *((t_CKTIME
*)(sp
+1)) / (double)Digitalio::sampling_rate() );