11 /* Object reference held. */
12 struct object
* s_object
;
13 /* Next stack slot. */
22 /* Message being handled. */
23 struct message
* c_message
;
24 /* Stack top pointer. */
25 struct stack
* c_stacktop
;
26 /* Instruction pointer. */
28 /* Number register value. */
30 /* Alternative mode flag. */
35 struct object
* c_locals
[];
38 /*****************************************************************************/
39 struct object
* context_pop(struct context
* ctx
)
44 struct stack
* tmp
= ctx
->c_stacktop
;
45 struct object
* obj
= tmp
->s_object
;
46 ctx
->c_stacktop
= tmp
->s_next
;
51 /*****************************************************************************/
52 void context_push(struct context
* ctx
, struct object
* obj
)
54 struct stack
* newslot
= malloc(sizeof(struct stack
));
56 fprintf(stderr
, "Out of memory!\n");
59 newslot
->s_next
= ctx
->c_stacktop
;
60 newslot
->s_object
= obj
;
61 ctx
->c_stacktop
= newslot
;
64 /*****************************************************************************/
65 unsigned context_prepare(struct context
* ctx
)
67 /* Grab message queue lock and context lock. */
68 vat_grab_queue_lock(ctx
->c_vat
);
69 mutex_lock(&ctx
->c_lock
);
71 ctx
->c_message
= vat_deque_message(ctx
->c_vat
);
75 /* Mark object as being executed. */
76 object_set_executing(message_target(ctx
->c_message
));
79 ctx
->c_stacktop
= NULL
;
83 for(size_t i
= 0; i
< vat_maxlocals(ctx
->c_vat
); i
++)
84 ctx
->c_locals
[i
] = NULL
;
86 mutex_unlock(&ctx
->c_lock
);
87 vat_ungrab_queue_lock(ctx
->c_vat
);
91 /*****************************************************************************/
92 void context_unprepare(struct context
* ctx
)
94 /* Grab message queue lock and context lock. */
95 vat_grab_queue_lock(ctx
->c_vat
);
96 mutex_lock(&ctx
->c_lock
);
98 object_clear_executing(message_target(ctx
->c_message
));
100 /* Kill the message. It is now handled. */
101 free(ctx
->c_message
);
103 /* Kill all the locals. */
104 for(size_t i
= 0; i
< vat_maxlocals(ctx
->c_vat
); i
++)
105 ctx
->c_locals
[i
] = NULL
;
107 while(ctx
->c_stacktop
)
110 mutex_unlock(&ctx
->c_lock
);
111 vat_ungrab_queue_lock(ctx
->c_vat
);
114 /*****************************************************************************/
115 size_t context_stacksize(struct context
* ctx
)
118 struct stack
* s
= ctx
->c_stacktop
;
127 /*****************************************************************************/
128 void context_singlestep(struct context
* ctx
)
130 struct message
* msg
= ctx
->c_message
;
131 struct object
* t
= message_target(msg
);
132 struct class* tc
= object_class(t
);
135 struct message
* tmp4
;
137 /* Grab context lock. */
138 mutex_lock(&ctx
->c_lock
);
140 if(ctx
->c_alt_flag
) {
141 switch(class_get_ins(tc
, ctx
->c_ip
)) {
151 /* Just clear the alternative mode. */
154 mutex_unlock(&ctx
->c_lock
);
159 switch(class_get_ins(tc
, ctx
->c_ip
)) {
167 tmp1
= context_pop(ctx
);
168 tmp2
= context_pop(ctx
);
173 object_write_field(t
, ctx
->c_numreg
, context_pop(ctx
));
176 context_push(ctx
, object_read_field(t
, ctx
->c_numreg
));
179 tmp1
= context_pop(ctx
);
180 if(ctx
->c_numreg
< class_local_count(tc
))
181 ctx
->c_locals
[ctx
->c_numreg
] = tmp1
;
184 if(ctx
->c_numreg
< class_local_count(tc
))
185 tmp1
= ctx
->c_locals
[ctx
->c_numreg
];
188 context_push(ctx
, tmp1
);
191 message_write_slot(msg
, ctx
->c_numreg
, context_pop(ctx
));
194 context_push(ctx
, message_read_slot(msg
, ctx
->c_numreg
));
197 tmp1
= context_pop(ctx
);
202 tmp4
= message_create(tmp1
, context_stacksize(ctx
));
203 for(size_t i
= 0; i
< message_parameters(tmp4
); i
++)
204 message_write_slot(tmp4
, i
, context_pop(ctx
));
205 vat_queue_message(ctx
->c_vat
, tmp4
);
208 context_push(ctx
, t
);
211 tmp1
= object_create_ordinary(class_search(ctx
->c_numreg
));
212 vat_add_object(ctx
->c_vat
, tmp1
);
213 context_push(ctx
, tmp1
);
220 mutex_unlock(&ctx
->c_lock
);
223 /*****************************************************************************/
224 struct context
* context_create(struct vat
* vat
)
226 struct context
* ctx
= malloc(sizeof(struct context
) +
227 vat_maxlocals(vat
) * sizeof(struct object
*));
229 fprintf(stderr
, "Out of memory!\n");
234 ctx
->c_stacktop
= NULL
;
238 for(size_t i
= 0; i
< vat_maxlocals(vat
); i
++)
239 ctx
->c_locals
[i
] = NULL
;
243 /*****************************************************************************/
244 void context_lock(struct context
* ctx
)
246 mutex_lock(&ctx
->c_lock
);
249 /*****************************************************************************/
250 void context_unlock(struct context
* ctx
)
252 mutex_unlock(&ctx
->c_lock
);
255 /*****************************************************************************/
256 void context_queue_message(struct context
* context
, struct message
* message
)
258 vat_queue_message(context
->c_vat
, message
);
261 /*****************************************************************************/
262 unsigned context_execute_msghandler(struct context
* ctx
)
264 if(!context_prepare(ctx
))
267 struct message
* m
= ctx
->c_message
;
268 struct object
* t
= message_target(m
);
269 struct class* tc
= object_class(t
);
271 if(object_exec_special(t
, ctx
, m
)) {
272 context_unprepare(ctx
);
275 /* Should not happen... */
276 context_unprepare(ctx
);
280 while(ctx
->c_ip
< class_ins_count(tc
)) {
281 context_singlestep(ctx
);
284 context_unprepare(ctx
);