15
15
16
16
typedef struct _mp_obj_gen_wrap_t {
17
17
mp_obj_base_t base ;
18
- int n_state ;
18
+ uint n_state ;
19
19
mp_obj_t * fun ;
20
20
} mp_obj_gen_wrap_t ;
21
21
@@ -31,22 +31,8 @@ mp_obj_t gen_wrap_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
31
31
if (n_args != bc_n_args ) {
32
32
nlr_jump (mp_obj_new_exception_msg_2_args (rt_q_TypeError , "function takes %d positional arguments but %d were given" , (const char * )(machine_int_t )bc_n_args , (const char * )(machine_int_t )n_args ));
33
33
}
34
- mp_obj_t * state = m_new (mp_obj_t , 1 + self -> n_state );
35
- // put function object at first slot in state (to keep u_gen_instance small)
36
- state [0 ] = self_fun ;
37
- // init args
38
- for (int i = 0 ; i < n_args ; i ++ ) {
39
- state [1 + i ] = args [n_args - 1 - i ];
40
- }
41
34
42
- // TODO
43
- // prelude for making cells (closed over variables)
44
- // for now we just make sure there are no cells variables
45
- // need to work out how to implement closed over variables in generators
46
- assert (bc_code [0 ] == 0 );
47
- bc_code += 1 ;
48
-
49
- return mp_obj_new_gen_instance (state , bc_code , state + self -> n_state );
35
+ return mp_obj_new_gen_instance (bc_code , self -> n_state , n_args , args );
50
36
}
51
37
52
38
const mp_obj_type_t gen_wrap_type = {
@@ -75,9 +61,9 @@ mp_obj_t mp_obj_new_gen_wrap(uint n_locals, uint n_stack, mp_obj_t fun) {
75
61
76
62
typedef struct _mp_obj_gen_instance_t {
77
63
mp_obj_base_t base ;
78
- mp_obj_t * state ;
79
64
const byte * ip ;
80
65
mp_obj_t * sp ;
66
+ mp_obj_t state [];
81
67
} mp_obj_gen_instance_t ;
82
68
83
69
void gen_instance_print (void (* print )(void * env , const char * fmt , ...), void * env , mp_obj_t self_in ) {
@@ -90,9 +76,7 @@ mp_obj_t gen_instance_getiter(mp_obj_t self_in) {
90
76
91
77
mp_obj_t gen_instance_iternext (mp_obj_t self_in ) {
92
78
mp_obj_gen_instance_t * self = self_in ;
93
- //mp_obj_base_t *fun = self->u_gen_instance.state[0];
94
- //assert(fun->kind == O_FUN_BC);
95
- bool yield = mp_execute_byte_code_2 (& self -> ip , & self -> state [1 ], & self -> sp );
79
+ bool yield = mp_execute_byte_code_2 (& self -> ip , & self -> state [0 ], & self -> sp );
96
80
if (yield ) {
97
81
return * self -> sp ;
98
82
} else {
@@ -117,11 +101,24 @@ const mp_obj_type_t gen_instance_type = {
117
101
{{NULL , NULL },}, // method list
118
102
};
119
103
120
- mp_obj_t mp_obj_new_gen_instance (mp_obj_t state , const byte * ip , mp_obj_t * sp ) {
121
- mp_obj_gen_instance_t * o = m_new_obj (mp_obj_gen_instance_t );
104
+ // args are in reverse order in the array
105
+ mp_obj_t mp_obj_new_gen_instance (const byte * bytecode , uint n_state , int n_args , const mp_obj_t * args ) {
106
+ mp_obj_gen_instance_t * o = m_new_obj_var (mp_obj_gen_instance_t , mp_obj_t , n_state );
122
107
o -> base .type = & gen_instance_type ;
123
- o -> state = state ;
124
- o -> ip = ip ;
125
- o -> sp = sp ;
108
+ o -> ip = bytecode ;
109
+ o -> sp = o -> state + n_state ;
110
+
111
+ // copy args (which are in reverse order) to start of state array
112
+ for (int i = 0 ; i < n_args ; i ++ ) {
113
+ o -> state [i ] = args [n_args - 1 - i ];
114
+ }
115
+
116
+ // TODO
117
+ // prelude for making cells (closed over variables)
118
+ // for now we just make sure there are no cells variables
119
+ // need to work out how to implement closed over variables in generators
120
+ assert (o -> ip [0 ] == 0 );
121
+ o -> ip += 1 ;
122
+
126
123
return o ;
127
124
}
0 commit comments