1 #include "shotgun/lib/shotgun.h"
2 #include "shotgun/lib/cpu.h"
3 #include "shotgun/lib/methctx.h"
4 #include "shotgun/lib/tuple.h"
5 #include "shotgun/lib/bytearray.h"
7 OBJECT
methctx_dup(STATE
, OBJECT self
) {
9 struct fast_context
*cur
, *old
;
11 methctx_reference(state
, self
);
13 ctx
= NEW_OBJECT(object_class(state
, self
), FASTCTX_FIELDS
);
15 ctx
->StoresBytes
= TRUE
;
16 if(self
->obj_type
== MContextType
) {
19 ctx
->obj_type
= self
->obj_type
;
21 assert(ctx
->obj_type
== MContextType
|| ctx
->obj_type
== BContextType
);
26 if(!NIL_P(old
->sender
)) methctx_reference(state
, old
->sender
);
27 SET_STRUCT_FIELD(ctx
, cur
->sender
, old
->sender
);
28 SET_STRUCT_FIELD(ctx
, cur
->block
, old
->block
);
29 SET_STRUCT_FIELD(ctx
, cur
->method
, old
->method
);
30 SET_STRUCT_FIELD(ctx
, cur
->literals
, old
->literals
);
31 SET_STRUCT_FIELD(ctx
, cur
->locals
, old
->locals
);
32 cur
->argcount
= old
->argcount
;
33 SET_STRUCT_FIELD(ctx
, cur
->name
, old
->name
);
34 SET_STRUCT_FIELD(ctx
, cur
->method_module
, old
->method_module
);
35 cur
->opaque_data
= old
->opaque_data
;
36 SET_STRUCT_FIELD(ctx
, cur
->self
, old
->self
);
37 SET_STRUCT_FIELD(ctx
, cur
->custom_iseq
, old
->custom_iseq
);
38 cur
->data
= old
->data
;
39 cur
->type
= old
->type
;
44 ctx
->ForeverYoung
= TRUE
;
49 OBJECT
methctx_dup_chain(STATE
, OBJECT ctx
, OBJECT
*also
) {
51 top
= methctx_dup(state
, ctx
);
55 sender
= FASTCTX(ctx
)->sender
;
56 if(NIL_P(sender
)) break;
58 methctx_reference(state
, sender
);
60 FASTCTX(ctx
)->sender
= methctx_dup(state
, sender
);
61 /* Update another ref if one is passed in
62 (used to also update home_context) */
63 if(also
&& *also
== sender
) {
64 *also
= FASTCTX(ctx
)->sender
;
72 OBJECT
blokenv_s_under_context2(STATE
, OBJECT cmethod
, OBJECT ctx
, OBJECT ctx_block
) {
74 int num_lcls
= N2I(cmethod_get_local_count(cmethod
));
76 obj
= blokenv_allocate(state
);
77 blokenv_set_home(obj
, ctx
);
78 blokenv_set_initial_ip(obj
, I2N(0));
79 // We have no real last since the block gets it's own method.
80 // Just set this very large so that comparison for bounds
81 // checks are always true.
82 blokenv_set_last_ip(obj
, I2N(1 << 25));
83 blokenv_set_post_send(obj
, I2N(0));
84 blokenv_set_home_block(obj
, ctx_block
);
85 blokenv_set_method(obj
, cmethod
);
86 blokenv_set_local_count(obj
, I2N(num_lcls
));
90 void blokenv_call(STATE
, cpu c
, OBJECT self
, int num_args
) {
94 c
->blockargs
= num_args
;
96 t3
= tuple_new(state
, num_args
);
97 for(j
= 0; j
< num_args
; j
++) {
99 tuple_put(state
, t3
, j
, t1
);
104 t2
= cpu_create_block_context(state
, c
, self
, c
->sp
);
105 cpu_activate_context(state
, c
, t2
, blokenv_get_home(self
), 1);
109 void methctx_reference(STATE
, OBJECT ctx
) {
110 struct fast_context
*fc
;
112 /* Don't do it again. */
113 if(!stack_context_p(ctx
)) return;
115 /* Has to be done first because this uses informated we're about
117 object_memory_context_referenced(state
->om
, ctx
);
120 ctx
->gc_zone
= YoungObjectZone
;
121 switch(FASTCTX(ctx
)->type
) {
123 SET_CLASS(ctx
, BASIC_CLASS(fastctx
));
124 ctx
->obj_type
= MContextType
;
128 SET_CLASS(ctx
, BASIC_CLASS(blokctx
));
129 ctx
->obj_type
= BContextType
;
132 SET_CLASS(ctx
, BASIC_CLASS(nmc
));
133 ctx
->obj_type
= MContextType
;
136 SET_NUM_FIELDS(ctx
, FASTCTX_FIELDS
);
137 ctx
->StoresBytes
= TRUE
;
138 ctx
->ForeverYoung
= TRUE
;
142 /* Fixup the locals tuple. */
143 if(!NIL_P(fc
->locals
) && fc
->locals
->gc_zone
== 0) {
144 fc
->locals
->gc_zone
= YoungObjectZone
;