root/lang/cplusplus/minipy/trunk/tivi.cpp @ 31007

Revision 15031, 25.8 kB (checked in by hayamiz, 5 years ago)

lang/cplusplus/minipy/trunk: マルチスレッド,mutex,cond var実装完了.サンプルとしてhttpサーバーも実装

Line 
1#include "tivi.hpp"
2
3#define TIVI_GOTO(addr) (program_counter = (addr))
4
5#define TIVI_FETCH() (inst = insns[PC].type)
6#define TIVI_FETCH_OPERAND() (py_val_t)(insns[PC].operand)
7#define TIVI_FETCH_SRCPOS() (*insns[PC].p)
8
9#define TIVI_LREF(offset) (this->machine_stack[FP + (offset) + 2])
10#define TIVI_GREF(operand) (this->globals[(int)(operand)])
11#define TIVI_LSET(offset, value) TIVI_LREF(offset) = (value)
12#define TIVI_STACK(offset_from_top) (this->machine_stack[SP - 1 - (offset_from_top)])
13
14#define TIVI_PUSH() (this->machine_stack[SP++] = VAL)
15#define TIVI_POP() (VAL = this->machine_stack[--SP])
16#define TIVI_PUSHI(arg) (this->machine_stack[SP++] = (py_val_t)arg)
17
18#define TIVI_EXIT() goto loop_exit;
19
20#define TIVI_SET_ARGS(var, arity)                                     \
21    (var)[arity] = NULL;                                              \
22    for (int i = 0;i < arity;i++){                                    \
23        (var)[i] = (this->machine_stack[ARGP + i]);                   \
24    }
25
26Tivi::Tivi(){
27    this->machine_stack = new py_val_t[MAX_STACK_SIZE];
28    this->vmasm = new vm_assembler();
29    this->trans = new Translator();
30
31    this->is_thread = false;
32   
33    SP = 0;
34    TIVI_PUSHI(NULL); // frame pointer
35    TIVI_PUSHI(NULL); // debug info
36    FP = 0;
37    VAL = NULL;
38    PC = 0;
39    ENV = new VmEnv();
40    ENV->up = NULL;
41    ENV->argp = 2;
42
43    this->bootstrap();
44}
45
46void Tivi::bootstrap(){
47#include "bootstrap.inc"
48}
49
50Tivi::~Tivi(){
51    delete[](this->machine_stack);
52}
53
54void Tivi::load_file(const string & filename){
55    Parser parser(filename);
56    vector<Stm*> stms = parser.file_input();
57
58    this->trans->compile_file(stms, *this->vmasm, this->genv);
59
60    // construct genv_rev, and modify byte code to use genv_rev
61    presetup();
62    this->globals = new py_val_t[this->genv.size()];
63    for (uint i = 0; i < this->genv.size();i++){
64        this->globals[i] = this->genv.lookup_sym(this->genv_rev[i]);
65    }
66
67    this->insns_size = this->vmasm->insns.size();
68}
69
70Tivi * Tivi::fork(Tivi * parent){
71    Tivi * ret = new Tivi();
72    ret->globals = parent->globals;
73    ret->genv_rev = parent->genv_rev;
74    ret->insns = parent->insns;
75    ret->insns_size = parent->insns_size;
76
77    return ret;
78}
79
80void Tivi::runtime_error(const string & msg, ConsStack<Stack_trace_entry*> * bt, int program_counter){
81    SrcPos p = *this->vmasm->insns[PC].p;
82    cerr << "Tivi runtime error (lifetime: " << lifetime << ") :::" << endl
83         << "  " << msg << " at " << p.filename << ":" << p.line_no << endl
84         << "----" << endl;
85
86    if (bt != NULL){
87        cerr << "* Backtrace *" << endl;
88        while(bt != NULL){
89            cerr << "-- " << bt->car()->name
90                 << " at " << bt->car()->call_site.filename
91                 << ":" << bt->car()->call_site.line_no << endl;
92            bt = bt->pop();
93        }
94    }
95   
96    exit(1);
97}
98
99void Tivi::presetup(){
100    uint size = this->vmasm->insns.size();
101
102    this->insns = new tivi_insn[size];
103    this->genv_rev = new symbol_t[this->genv.size()];
104
105    map<symbol_t, int> sym_to_index;
106
107    int gvar_index = 0;
108    for (uint i = 0; i < size; i++){
109        vm_inst & insn = this->vmasm->insns[i];
110        this->insns[i].p = (SrcPos *)insn.p;
111        switch (this->insns[i].type = insn.type){
112        case VM_GREF:
113        case VM_GREF_PUSH:
114        case VM_GSET:
115        case VM_GINC:
116        case VM_GREF_CALL:
117            if (sym_to_index.find((symbol_t) insn.operand) == sym_to_index.end()){
118                this->insns[i].operand = (void*) gvar_index;
119                sym_to_index[(symbol_t) insn.operand] = gvar_index;
120                this->genv_rev[gvar_index] = (symbol_t)insn.operand;
121                gvar_index++;
122            } else {
123                this->insns[i].operand = (void *)sym_to_index[(symbol_t) insn.operand];
124            }
125            break;
126        default:
127            this->insns[i].operand = insn.operand;
128            break;
129        }
130    }
131}
132
133
134
135void Tivi::run(int entry_point, ConsStack<Stack_trace_entry*> * bt){
136    srand((unsigned) time(NULL));
137
138    register int pc_limit = this->insns_size;
139    // py_val_t op;
140    symbol_t sym;
141    int num;
142    py_val_t a1, a2;
143    py_val_t a[4];
144    register py_val_t f = NULL;
145    register int numarg;
146
147
148// #undef __GNUC__
149#ifdef __GNUC__
150
151#define SWITCH(var) goto *gototable[PC];
152#define CASE(var) var##_CASE:
153#define BREAK
154
155#define TIVI_NEXTI() (PC++) ; TIVI_NEXT()
156#define TIVI_NEXT() goto main_loop
157
158#include "dispatchtable.inc"
159    void * gototable[pc_limit];
160    for(int i = 0; i < pc_limit; i++){
161        gototable[i] = dispatchtable[this->insns[i].type];
162    }
163#else
164
165#define SWITCH(var) switch(var)
166#define CASE(var) case (var):
167#define BREAK break
168#define TIVI_NEXTI() (PC++); TIVI_NEXT()
169#define TIVI_NEXT() goto main_loop
170   
171#endif
172
173       
174#ifndef RELEASE_BUILD
175    lifetime = 0;
176#endif
177
178    TIVI_GOTO(entry_point);
179
180main_loop:
181    if (PC >= pc_limit) {
182        if (this->is_thread){
183            cerr << "[thread exited by PC limit]" << endl;
184        }
185        return;
186    }
187
188#ifndef RELEASE_BUILD
189    lifetime++;
190#endif
191
192    // cerr << "lifetime: " << lifetime++ << endl;
193
194    SWITCH(TIVI_FETCH()){
195    CASE(VM_NOP)
196    {
197        // no operand
198        TIVI_NEXTI();
199    }
200    BREAK;
201    CASE(VM_END)
202    {
203        TIVI_EXIT();
204    }
205    BREAK;
206    CASE(VM_IMMVAL)
207    {
208        // one operand
209        VAL = TIVI_FETCH_OPERAND();
210        TIVI_NEXTI();
211    }
212    BREAK;
213    CASE(VM_IMMVAL_NUM)
214    {
215        // one operand
216        VAL = TIVI_FETCH_OPERAND();
217        TIVI_NEXTI();
218    }
219    BREAK;
220    CASE(VM_IMMVAL_CHAR)
221    {
222        // one operand
223        VAL = TIVI_FETCH_OPERAND();
224        TIVI_NEXTI();
225    }
226    BREAK;
227    CASE(VM_PUSH)
228    {
229        // no operand
230        TIVI_PUSH();
231
232        TIVI_NEXTI();
233    }
234    BREAK;
235    CASE(VM_POP)
236    {
237        // no operand
238        TIVI_POP();
239        TIVI_NEXTI();
240    }
241    BREAK;
242    CASE(VM_PUSHI)
243    {
244        // one operand
245        TIVI_PUSHI(TIVI_FETCH_OPERAND());
246        TIVI_NEXTI();
247    }
248    BREAK;
249    CASE(VM_PUSHI_NUM)
250    {
251        // one operand
252        TIVI_PUSHI(TIVI_FETCH_OPERAND());
253        TIVI_NEXTI();
254    }
255    BREAK;
256    CASE(VM_PUSHI_CHAR)
257    {
258        // one operand
259        TIVI_PUSHI(TIVI_FETCH_OPERAND());
260        TIVI_NEXTI();
261    }
262    BREAK;
263    CASE(VM_LREF)
264    {
265        // one operand
266        num = (int)TIVI_FETCH_OPERAND();
267        VAL = TIVI_LREF(num);
268        TIVI_NEXTI();
269    }
270    BREAK;
271    CASE(VM_LREF_PUSH)
272    {
273        // one operand
274        num = (int)TIVI_FETCH_OPERAND();
275        TIVI_PUSHI(TIVI_LREF(num));
276        TIVI_NEXTI();
277    }
278    BREAK;
279    CASE(VM_LREF_LOOK)
280    {
281        runtime_error("VM_LREF_LOOK is obsolete", bt, PC);
282        // one operand
283        TIVI_NEXTI();
284    }
285    BREAK;
286    CASE(VM_LSET)
287    {
288        // one operand
289        num = (int)TIVI_FETCH_OPERAND();
290        TIVI_LSET(num, VAL);
291        TIVI_NEXTI();
292    }
293    BREAK;
294    CASE(VM_LINC)
295    {
296        // one operand
297        num = (int)TIVI_FETCH_OPERAND();
298        TIVI_LSET(num, (py_val_t)(((int)TIVI_LREF(num)) + 2));
299        TIVI_NEXTI();
300    }
301    BREAK;
302    CASE(VM_LDEFUN)
303    {
304        // one operand
305        TIVI_PUSHI(TIVI_FETCH_OPERAND());
306        TIVI_NEXTI();
307    }
308    BREAK;
309    CASE(VM_GREF)
310    {
311        // one operand
312        VAL = TIVI_GREF(TIVI_FETCH_OPERAND());
313        TIVI_NEXTI();
314    }
315    BREAK;
316    CASE(VM_GREF_PUSH)
317    {
318        // one operand
319        TIVI_PUSHI(TIVI_GREF(TIVI_FETCH_OPERAND()));
320        TIVI_NEXTI();
321    }
322    BREAK;
323    CASE(VM_GSET)
324    {
325        // one operand
326        TIVI_GREF(TIVI_FETCH_OPERAND()) = VAL;
327        TIVI_NEXTI();
328    }
329    BREAK;
330    CASE(VM_GINC)
331    {
332        // one operand
333        TIVI_GREF(TIVI_FETCH_OPERAND())
334            = (py_val_t)((int)TIVI_GREF(TIVI_FETCH_OPERAND()) + 2);
335        TIVI_NEXTI();
336    }
337    BREAK;
338    CASE(VM_GDEFUN)
339    {
340        // one operand
341        TIVI_NEXTI();
342    }
343    BREAK;
344    CASE(VM_ADD2)
345    CASE(VM_ADD2_NUM)
346    CASE(VM_ADD2_STR)
347    {
348        // no operand
349        a[2] = NULL;
350
351        a[1] = VAL;
352        a[0] = TIVI_POP();
353
354        VAL = native::add(bt, TIVI_FETCH_SRCPOS(), a);
355        TIVI_NEXTI();
356    }
357    BREAK;
358    CASE(VM_SUB2)
359    CASE(VM_SUB2_NUM)
360    {
361        // no operand
362        a[2] = NULL;
363
364        a[1] = VAL;
365        a[0] = TIVI_POP();
366
367        VAL = native::sub(bt, TIVI_FETCH_SRCPOS(), a);
368        TIVI_NEXTI();
369    }
370    BREAK;
371    CASE(VM_MUL2)
372    CASE(VM_MUL2_NUM)
373    {
374        // no operand
375        a[2] = NULL;
376
377        a[1] = VAL;
378        a[0] = TIVI_POP();
379
380        VAL = native::mul(bt, TIVI_FETCH_SRCPOS(), a);
381       
382        TIVI_NEXTI();
383    }
384    BREAK;
385    CASE(VM_DIV2)
386    CASE(VM_DIV2_NUM)
387    {
388        // no operand
389        a[2] = NULL;
390
391        a[1] = VAL;
392        a[0] = TIVI_POP();
393
394        VAL = native::div(bt, TIVI_FETCH_SRCPOS(), a);
395        TIVI_NEXTI();
396    }
397    BREAK;
398    CASE(VM_AND2)
399    {
400        // no operand
401       
402        a2 = VAL;
403        a1 = TIVI_POP();
404
405        if(Py_val::is_false(a1)){
406            VAL = Py_val::mk_int(0);
407        } else {
408            if(Py_val::is_false(a2)){
409                VAL = Py_val::mk_int(0);
410            } else {
411                VAL = Py_val::mk_int(1);
412            }
413        }
414       
415        TIVI_NEXTI();
416    }
417    BREAK;
418    CASE(VM_OR2)
419    {
420        // no operand
421        a2 = VAL;
422        a1 = TIVI_POP();
423
424        if(Py_val::is_false(a1)){
425            if(Py_val::is_false(a2)){
426                VAL = Py_val::mk_int(0);
427            } else {
428                VAL = Py_val::mk_int(1);
429            }
430        } else {
431            VAL = Py_val::mk_int(1);
432        }
433        TIVI_NEXTI();
434    }
435    BREAK;
436    CASE(VM_NOT)
437    {
438        // no operand
439        if (Py_val::is_false(VAL)) {
440            VAL = Py_val::mk_int(1);
441        } else {
442            VAL = Py_val::mk_int(0);
443        }
444        TIVI_NEXTI();
445    }
446    BREAK;
447    CASE(VM_BITAND2)
448    {
449        // no operand
450        a2 = VAL;
451        a1 = TIVI_POP();
452
453        if (!Py_val::is_int(a1) || !Py_val::is_int(a2)){
454            runtime_error("type error : & (and) requires integer", bt, PC);
455        }
456
457        VAL = Py_val::mk_int(getint(a1)
458                             & getint(a2));
459       
460        TIVI_NEXTI();
461    }
462    BREAK;
463    CASE(VM_BITOR2)
464    {
465        // no operand
466        a2 = VAL;
467        a1 = TIVI_POP();
468
469        if (!Py_val::is_int(a1) || !Py_val::is_int(a2)){
470            runtime_error("type error : << (shift) requires integer", bt, PC);
471        }
472
473        VAL = Py_val::mk_int(getint(a1)
474                             | getint(a2));
475       
476        TIVI_NEXTI();
477    }
478    BREAK;
479    CASE(VM_BITXOR2)
480    {
481        // no operand
482        a2 = VAL;
483        a1 = TIVI_POP();
484
485        if (!Py_val::is_int(a1) || !Py_val::is_int(a2)){
486            runtime_error("type error : << (shift) requires integer", bt, PC);
487        }
488
489        VAL = Py_val::mk_int(getint(a1)
490                             ^ getint(a2));
491       
492        TIVI_NEXTI();
493    }
494    BREAK;
495    CASE(VM_BITINV)
496    {
497        // no operand
498        a1 = VAL;
499
500        if (!Py_val::is_int(a1)){
501            runtime_error("type error : ~ (bit inv) requires integer", bt, PC);
502        }
503
504        VAL = Py_val::mk_int(- getint(a1) - 1);
505       
506        TIVI_NEXTI();
507    }
508    BREAK;
509    CASE(VM_RSHIFT2)
510    {
511        // no operand
512        a2 = VAL;
513        a1 = TIVI_POP();
514
515        if (!Py_val::is_int(a1) || !Py_val::is_int(a2)){
516            runtime_error("type error : << (shift) requires integer", bt, PC);
517        }
518
519        VAL = Py_val::mk_int(getint(a1) >> getint(a2));
520       
521        TIVI_NEXTI();
522    }
523    BREAK;
524    CASE(VM_LSHIFT2)
525    {
526        // no operand
527        a2 = VAL;
528        a1 = TIVI_POP();
529
530        if (!Py_val::is_int(a1) || !Py_val::is_int(a2)){
531            runtime_error("type error : << (shift) requires integer", bt, PC);
532        }
533
534        VAL = Py_val::mk_int(getint(a1) << getint(a2));
535       
536        TIVI_NEXTI();
537    }
538    BREAK;
539    CASE(VM_EQL2)
540    {
541        // no operand
542        a2 = VAL;
543        a1 = TIVI_POP();
544
545        if (Py_val::compare(a1, a2) == 0){
546            VAL = mkint(1);
547        } else {
548            VAL = mkint(0);
549        }
550       
551        TIVI_NEXTI();
552    }
553    BREAK;
554    CASE(VM_NEQL2)
555    {
556        // no operand
557        a2 = VAL;
558        a1 = TIVI_POP();
559
560        if (Py_val::compare(a1, a2) != 0){
561            VAL = mkint(1);
562        } else {
563            VAL = mkint(0);
564        }
565
566        TIVI_NEXTI();
567    }
568    BREAK;
569    CASE(VM_NUMLT2)
570    {
571        // no operand
572        a2 = VAL;
573        a1 = TIVI_POP();
574
575        if (Py_val::compare(a1, a2) < 0){
576            VAL = mkint(1);
577        } else {
578            VAL = mkint(0);
579        }
580
581        TIVI_NEXTI();
582    }
583    BREAK;
584    CASE(VM_NUMLEQ2)
585    {
586        // no operand
587        a2 = VAL;
588        a1 = TIVI_POP();
589
590        if (Py_val::compare(a1, a2) <= 0){
591            VAL = mkint(1);
592        } else {
593            VAL = mkint(0);
594        }
595       
596        TIVI_NEXTI();
597    }
598    BREAK;
599    CASE(VM_NUMGT2)
600    {
601        // no operand
602        a2 = VAL;
603        a1 = TIVI_POP();
604
605        if (Py_val::compare(a1, a2) > 0){
606            VAL = mkint(1);
607        } else {
608            VAL = mkint(0);
609        }
610       
611        TIVI_NEXTI();
612    }
613    BREAK;
614    CASE(VM_NUMGEQ2)
615    {
616        // no operand
617        a2 = VAL;
618        a1 = TIVI_POP();
619
620        if (Py_val::compare(a1, a2) >= 0){
621            VAL = mkint(1);
622        } else {
623            VAL = mkint(0);
624        }
625       
626        TIVI_NEXTI();
627    }
628    BREAK;
629    CASE(VM_IS2)
630    {
631        // no operand
632        a2 = VAL;
633        a1 = TIVI_POP();
634
635        a[2] = NULL;
636
637        a[0] = a1;
638        a[1] = a2;
639       
640        if (Py_val::is_int(a1) && Py_val::is_int(a2) && a1 == a2){
641            VAL = Py_val::mk_int(1);
642        } else if (Py_val::is_float(a1) && Py_val::is_float(a2)
643                   && a1->u.f == a2->u.f) {
644            VAL = Py_val::mk_int(1);
645        } else if (Py_val::is_string(a1) && Py_val::is_string(a2)) {
646            VAL = native::eq_string(bt, TIVI_FETCH_SRCPOS(), a);
647        } else {
648            VAL = Py_val::mk_int(a1 == a2);
649        }
650        TIVI_NEXTI();
651    }
652    BREAK;
653    CASE(VM_IN2)
654    {
655        // no operand
656        a[2] = NULL;
657
658        a[1] = VAL;
659        a[0] = TIVI_POP();
660
661        VAL = native::contains(bt, TIVI_FETCH_SRCPOS(), a);
662        TIVI_NEXTI();
663    }
664    BREAK;
665    CASE(VM_GOTO)
666    {
667        // one operand
668        num = (int)TIVI_FETCH_OPERAND();
669        TIVI_GOTO(num);
670        TIVI_NEXT();
671    }
672    BREAK;
673    CASE(VM_GOTOIF)
674    {
675        // one operand
676        cerr << "not implemented @ " << __FILE__ << ":" << __LINE__ << endl; exit(1);
677        TIVI_NEXTI();
678    }
679    BREAK;
680    CASE(VM_GOTOIFNOT)
681    {
682        // one operand
683        if(Py_val::is_false(VAL)){
684            TIVI_GOTO((int)TIVI_FETCH_OPERAND());
685        } else {
686            TIVI_NEXTI();
687        }
688        TIVI_NEXT();
689    }
690    BREAK;
691    CASE(VM_PUSH_ENV)
692    {
693        TIVI_PUSHI(FP); // static link
694        TIVI_PUSHI(NULL); // debug info will be here.
695       
696        VmEnv * newenv = new VmEnv();
697        newenv->up = ENV;
698        newenv->argp = SP;
699        ENV = newenv;
700       
701        TIVI_NEXTI();
702    }
703    BREAK;
704    CASE(VM_SELF_CALL)
705    CASE(VM_VREF_CALL)
706    CASE(VM_GREF_CALL)
707    CASE(VM_LREF_CALL)
708    {
709        // one operand
710        numarg = SP - ARGP;
711
712        if (INST == VM_GREF_CALL){
713            if ((f = TIVI_GREF(TIVI_FETCH_OPERAND())) == py_val_not_found){
714                runtime_error("no such function " + *genv_rev[(int)TIVI_FETCH_OPERAND()], bt, PC);
715            }
716            bt = CONS_STACK(new Stack_trace_entry(*genv_rev[(int)this->insns[PC].operand]
717                                      , TIVI_FETCH_SRCPOS())
718                            , bt);
719        } else if (INST == VM_VREF_CALL){
720            // VREF_CALL means a function to be called is pointed by
721            // VAL register
722            f = VAL;
723            if (f->type == py_type_nfun){
724                bt = CONS_STACK(new Stack_trace_entry(*f->u.n->name, TIVI_FETCH_SRCPOS()), bt);
725            } else if (f->type == py_type_vm_ifun){
726                bt = CONS_STACK(new Stack_trace_entry(*f->u.vm_i->name, TIVI_FETCH_SRCPOS()), bt);
727            } else {
728                runtime_error("type error : no function object was called.", bt, PC);
729            }
730        } else if (INST == VM_LREF_CALL){
731            // LREF_CALL means a function to be called is pointed by
732            // a value in stack frame(local variable)
733            f = TIVI_LREF((int)TIVI_FETCH_OPERAND());
734            if (f->type == py_type_nfun){
735                bt = CONS_STACK(new Stack_trace_entry(*f->u.n->name, TIVI_FETCH_SRCPOS()), bt);
736            } else if (f->type == py_type_vm_ifun){
737                bt = CONS_STACK(new Stack_trace_entry(*f->u.vm_i->name, TIVI_FETCH_SRCPOS()), bt);
738            } else {
739                runtime_error("type error : no function object was called.", bt, PC);
740            }
741        } else if (INST == VM_SELF_CALL){
742            // SELF_CALL means a function to be called is pointed by
743            // a operand
744            f = TIVI_FETCH_OPERAND();
745            bt = CONS_STACK(new Stack_trace_entry(*f->u.vm_i->name, TIVI_FETCH_SRCPOS()), bt);
746        }
747
748        switch(f->type){
749        case py_type_vm_ifun:
750        {
751            if (f->u.vm_i->arity >= 0 && numarg != f->u.vm_i->arity){
752                stringstream ss;
753                ss << f->u.vm_i->name << " requires " << f->u.vm_i->arity
754                   << ", but got " << numarg;
755                runtime_error("wrong number of argument : " + ss.str(), bt, PC);
756            }
757
758            FP = ARGP - 2;
759            this->return_stack.push(PC+1);
760            PC = f->u.vm_i->addr;
761            SP += f->u.vm_i->locals; // align SP for local vars
762        }
763        break;
764        case py_type_nfun:
765        {
766            if (f->u.n->arity >= 0 && numarg != f->u.n->arity){
767                stringstream ss;
768                ss << f->u.vm_i->name << " requires " << f->u.vm_i->arity
769                   << ", but got " << numarg;
770                runtime_error("wrong number of argument : " + ss.str(), bt, PC);
771            }
772
773            py_val_t args[numarg + 1];
774            TIVI_SET_ARGS(args, numarg);
775            // if (lifetime > 3040000) cerr << lifetime << " " ;
776            VAL = f->u.n->f(bt, TIVI_FETCH_SRCPOS(), args);
777
778            SP = ARGP - 2;
779            ENV = ENV->up;
780
781            bt = bt->pop();
782            TIVI_NEXTI();
783        }
784        break;
785        default:
786            runtime_error("type error : " + *sym + " is not a function.", bt, PC);
787        }
788        TIVI_NEXT();
789    }
790    BREAK;
791    CASE(VM_RET)
792    {
793        // no operand
794        if (this->return_stack.size() == 0){
795            if (this->is_thread){
796                cerr << "[Success: thread exited by VM_RET]" << endl;
797                return;
798            } else {
799                runtime_error("no place to return", bt, PC);
800            }
801        }
802        VmEnv * oldenv = ENV;
803        ENV = ENV->up;
804        delete(oldenv);
805        SP = FP;
806        FP = (int)machine_stack[FP];
807       
808        PC = this->return_stack.top();
809        this->return_stack.pop();
810        TIVI_NEXT();
811    }
812    BREAK;
813    CASE(VM_MKLIST)
814    {
815        // one operand
816        num = (int)TIVI_FETCH_OPERAND();
817
818        vector<py_val_t> * tmp = new vector<py_val_t>();
819        for(int i = 0; i < num;i++){
820            py_val_t foo = TIVI_STACK(num - i - 1);
821            tmp->push_back(foo);
822        }
823        VAL = Py_val::mk_list_byptr(tmp);
824
825        SP -= num;
826       
827        TIVI_NEXTI();
828    }
829    BREAK;
830    CASE(VM_MKTUPLE)
831    {
832        // one operand
833        num = (int)TIVI_FETCH_OPERAND();
834
835        Py_tuple * tmp = new Py_tuple(num);
836        for(int i = 0; i < num;i++){
837            py_val_t foo = TIVI_STACK(num - i - 1);
838            tmp->push_back(foo);
839        }
840        VAL = Py_val::mk_newtuple(tmp);
841       
842        SP -= num;
843
844        TIVI_NEXTI();
845    }
846    BREAK;
847    CASE(VM_MKDICT)
848    {
849        // one operand
850
851        a1 = Py_val::mk_newdict();
852
853        num = (int)TIVI_FETCH_OPERAND();
854        for(int i = num;i > 0;i--){
855            Py_dict_entry* entry
856                = new Py_dict_entry(TIVI_STACK(2 * i - 1), TIVI_STACK(2 * i - 2));
857            getnewdict(a1)->set_entry(entry, bt, TIVI_FETCH_SRCPOS());
858        }
859
860        SP -= num * 2;
861
862        VAL = a1;
863
864        TIVI_NEXTI();
865    }
866    BREAK;
867    CASE(VM_LEN)
868    {
869        a[1] = NULL;
870        a[0] = VAL;
871        VAL = native::len(bt, TIVI_FETCH_SRCPOS(), a);
872        TIVI_NEXTI();
873    }
874    BREAK;
875    CASE(VM_GETITEM)
876    {
877        a[2] = NULL;
878
879        a[1] = VAL;
880        a[0] = TIVI_POP();
881
882        VAL = native::getitem(bt, TIVI_FETCH_SRCPOS(), a);
883        TIVI_NEXTI();
884    }
885    BREAK;
886    CASE(VM_SETITEM)
887    {
888        a[3] = NULL;
889        a[0] = TIVI_STACK(1);
890        a[1] = TIVI_STACK(0);
891        a[2] = VAL;
892
893        SP -= 2;
894
895        VAL = native::setitem(bt, TIVI_FETCH_SRCPOS(), a);
896        TIVI_NEXTI();
897    }
898    BREAK;
899    CASE(VM_DELITEM)
900    {
901        a[2] = NULL;
902        a[1] = VAL;
903        a[0] = TIVI_POP();
904
905        VAL = native::delitem(bt, TIVI_FETCH_SRCPOS(), a);
906        TIVI_NEXTI();
907    }
908    BREAK;
909    CASE(VM_PRINT)
910    {
911        a[1] = NULL;
912        a[0] = VAL;
913
914        VAL = native::print_(bt, TIVI_FETCH_SRCPOS(), a);
915        TIVI_NEXTI();
916    }
917    BREAK;
918    CASE(VM_PRINTSTR)
919    {
920        a[0] = VAL;
921        a[1] = NULL;
922       
923        VAL = native::print_string(bt, TIVI_FETCH_SRCPOS(), a);
924        TIVI_NEXTI();
925    }
926    BREAK;
927    CASE(VM_LREF_ADD2)
928    {
929        a[2] = NULL;
930
931        a[1] = TIVI_LREF((int)TIVI_FETCH_OPERAND());
932        a[0] = TIVI_POP();
933
934        VAL = native::add(bt, TIVI_FETCH_SRCPOS(), a);
935        TIVI_NEXTI();
936    }
937    BREAK;
938    CASE(VM_LREF_SUB2)
939    {
940        a[2] = NULL;
941
942        a[1] = TIVI_LREF((int)TIVI_FETCH_OPERAND());
943        a[0] = TIVI_POP();
944
945        VAL = native::sub(bt, TIVI_FETCH_SRCPOS(), a);
946        TIVI_NEXTI();
947    }
948    BREAK;
949    CASE(VM_LREF_MUL2)
950    {
951        a[2] = NULL;
952        a[1] = TIVI_LREF((int)TIVI_FETCH_OPERAND());
953        a[0] = TIVI_POP();
954
955        VAL = native::mul(bt, TIVI_FETCH_SRCPOS(), a);
956        TIVI_NEXTI();
957    }
958    BREAK;
959    CASE(VM_LREF_DIV2)
960    {
961        a[2] = NULL;
962        a[1] = TIVI_LREF((int)TIVI_FETCH_OPERAND());
963        a[0] = TIVI_POP();
964
965        VAL = native::div(bt, TIVI_FETCH_SRCPOS(), a);
966        TIVI_NEXTI();
967    }
968    BREAK;
969    CASE(VM_THREAD_FORK)
970    {
971        a[1] = VAL;
972        a[0] = TIVI_POP();
973
974        if(!Py_val::is_newtuple(a[1])){
975            runtime_error("thread error: argments must be a tuple", bt ,PC);
976        }
977
978        py_val_t thread = Py_val::mk_thread(a[0]);
979
980        Py_thread_args * args = new Py_thread_args();
981        args->th = thread->u.th;
982        args->strace = new ConsStack<Stack_trace_entry*>(
983            new Stack_trace_entry("--thread--",
984                                  TIVI_FETCH_SRCPOS())
985            , NULL);
986        args->pos = &TIVI_FETCH_SRCPOS();
987        args->args = new py_val_t[a[1]->u.nl->size() + 1];
988        args->parent = this;
989
990        for(uint i = 0; i < a[1]->u.nl->size();i++){
991            args->args[i] = a[1]->u.nl->get(i);
992        }
993        args->args[a[1]->u.nl->size()] = NULL;
994   
995        if (Py_val::is_vfun(a[0])){
996            if (pthread_create(&thread->u.th->th
997                               , NULL
998                               , Tivi::thread_vfun_dispatch
999                               , args) != 0) {
1000                runtime_error("thread error: cannot create thread", bt, PC);
1001            }
1002        } else if (Py_val::is_nfun(a[0])) {
1003            if (pthread_create(&thread->u.th->th
1004                               , NULL
1005                               , Tivi::thread_nfun_dispatch
1006                               , args) != 0) {
1007                runtime_error("thread error: cannot create thread", bt, PC);
1008            }
1009        }
1010
1011        VAL = thread;
1012        TIVI_NEXTI();
1013    }
1014    CASE(VM_THREAD_JOIN){
1015
1016        a[0] = VAL;
1017        if(!Py_val::is_thread(a[0])){
1018            runtime_error("thread_join: invalid argument", bt, PC);
1019        }
1020
1021        PTH_ASSERT(pthread_join(a[0]->u.th->th, NULL));
1022
1023//         PTH_ASSERT(pthread_mutex_lock(&(a[0]->u.th->join_mutex)));
1024//         while(!a[0]->u.th->joined){
1025//             PTH_ASSERT(pthread_cond_wait(&(a[0]->u.th->join_cond)
1026//                                          , &(a[0]->u.th->join_mutex)));
1027//         }
1028//         PTH_ASSERT(pthread_mutex_unlock(&(a[0]->u.th->join_mutex)));
1029
1030        TIVI_NEXTI();
1031    }
1032   
1033    }
1034
1035    goto main_loop;
1036
1037loop_exit:
1038
1039    for (uint i = 0; i < this->genv.size();i++){
1040        this->genv.set_sym(this->genv_rev[i], this->globals[i]);
1041    }
1042    delete[](this->genv_rev);
1043    delete[](this->insns);
1044    delete[](this->globals);
1045}
1046
1047void Tivi::disasm(){
1048    this->vmasm->print(this->genv);
1049}
1050
1051void * Tivi::thread_nfun_dispatch(void * a){
1052    Py_thread_args * args = static_cast<Py_thread_args*>(a);
1053
1054    py_val_t f = args->th->func;
1055
1056    f->u.n->f(CONS_STACK(new Stack_trace_entry(*f->u.n->name
1057                                               , *args->pos)
1058                         ,args->strace)
1059              , *args->pos, args->args);
1060   
1061    delete(args);
1062
1063    return NULL;
1064}
1065
1066void * Tivi::thread_vfun_dispatch(void * a){
1067
1068    Py_thread_args * args = static_cast<Py_thread_args*>(a);
1069   
1070    Tivi * vm = Tivi::fork(static_cast<Tivi*>(args->parent));
1071
1072    vm->is_thread = true;
1073
1074    // VM_PUSH_ENV
1075    vm->machine_stack[vm->stack_pointer++]
1076        = (py_val_t)vm->frame_pointer; // static link
1077    vm->frame_pointer = vm->stack_pointer - 1;
1078    vm->machine_stack[vm->stack_pointer++] = NULL; // debug info will be here.
1079   
1080    VmEnv * newenv = new VmEnv();
1081    newenv->up = vm->env;
1082    newenv->argp = vm->stack_pointer;
1083    vm->env = newenv;
1084
1085    for(uint i = 0; args->args[i] != NULL; i++){
1086        vm->machine_stack[vm->stack_pointer++] = (py_val_t)args->args[i];
1087    }
1088
1089    vm->stack_pointer += args->th->func->u.vm_i->locals; // align SP for local vars
1090
1091    vm->run(args->th->func->u.vm_i->addr, args->strace);
1092
1093
1094    PTH_ASSERT(pthread_mutex_lock(&args->th->join_mutex));
1095    args->th->joined = true;
1096    PTH_ASSERT(pthread_cond_signal(&args->th->join_cond));
1097    PTH_ASSERT(pthread_mutex_unlock(&args->th->join_mutex));
1098
1099    delete(args);
1100
1101    return NULL;
1102}
Note: See TracBrowser for help on using the browser.