1 /* sub.h 2 * Copyright (C) 2001-2008, Parrot Foundation. 3 * Data Structure and Algorithms: 4 * Subroutine, coroutine, closure and continuation structures 5 * and related routines. 6 */ 7 8 #ifndef PARROT_SUB_H_GUARD 9 #define PARROT_SUB_H_GUARD 10 11 #include "parrot/parrot.h" 12 13 /* 14 * Subroutine flags 15 */ 16 typedef enum { 17 /* runtime usage flags */ 18 SUB_FLAG_CORO_FF = PObj_private0_FLAG, 19 SUB_FLAG_C_HANDLER = PObj_private0_FLAG, /* C exceptions only */ 20 SUB_FLAG_TAILCALL = PObj_private2_FLAG, 21 SUB_FLAG_GENERATOR = PObj_private3_FLAG, /* unused old python pmcs */ 22 23 /* compile/loadtime usage flags */ 24 /* from packfile */ 25 SUB_FLAG_IS_OUTER = PObj_private1_FLAG, 26 SUB_FLAG_PF_ANON = PObj_private3_FLAG, 27 SUB_FLAG_PF_MAIN = PObj_private4_FLAG, 28 SUB_FLAG_PF_LOAD = PObj_private5_FLAG, 29 SUB_FLAG_PF_IMMEDIATE = PObj_private6_FLAG, 30 SUB_FLAG_PF_POSTCOMP = PObj_private7_FLAG, 31 32 SUB_FLAG_PF_MASK = SUB_FLAG_PF_ANON 33 | SUB_FLAG_PF_LOAD 34 | SUB_FLAG_PF_IMMEDIATE 35 | SUB_FLAG_PF_POSTCOMP 36 } sub_flags_enum; 37 38 #define SUB_FLAG_get_FLAGS(o) (PObj_get_FLAGS(o)) 39 #define SUB_FLAG_flag_TEST(flag, o) (SUB_FLAG_get_FLAGS(o) & SUB_FLAG_ ## flag) 40 #define SUB_FLAG_flag_SET(flag, o) (SUB_FLAG_get_FLAGS(o) |= SUB_FLAG_ ## flag) 41 #define SUB_FLAG_flag_CLEAR(flag, o) (SUB_FLAG_get_FLAGS(o) &= ~(UINTVAL)(SUB_FLAG_ ## flag)) 42 43 #define SUB_FLAG_flags_SETTO(o, f) SUB_FLAG_get_FLAGS(o) = (f) 44 #define SUB_FLAG_flags_CLEARALL(o) SUB_FLAG_flags_SETTO((o), 0) 45 46 #define SUB_FLAG_TAILCALL_TEST(o) SUB_FLAG_flag_TEST(TAILCALL, (o)) 47 #define SUB_FLAG_TAILCALL_ISSET(o) SUB_FLAG_flag_TEST(TAILCALL, (o)) 48 #define SUB_FLAG_TAILCALL_NOTSET(o) (!SUB_FLAG_flag_TEST(TAILCALL, (o))) 49 #define SUB_FLAG_TAILCALL_SET(o) SUB_FLAG_flag_SET(TAILCALL, (o)) 50 #define SUB_FLAG_TAILCALL_CLEAR(o) SUB_FLAG_flag_CLEAR(TAILCALL, (o)) 51 52 #define SUB_FLAG(n) ((UINTVAL)1 << (n)) 53 typedef enum { 54 SUB_COMP_FLAG_BIT_0 = SUB_FLAG(0), 55 SUB_COMP_FLAG_BIT_1 = SUB_FLAG(1), 56 SUB_COMP_FLAG_VTABLE = SUB_COMP_FLAG_BIT_1, 57 SUB_COMP_FLAG_BIT_2 = SUB_FLAG(2), 58 SUB_COMP_FLAG_METHOD = SUB_COMP_FLAG_BIT_2, 59 SUB_COMP_FLAG_BIT_3 = SUB_FLAG(3), 60 SUB_COMP_FLAG_BIT_4 = SUB_FLAG(4), 61 SUB_COMP_FLAG_BIT_5 = SUB_FLAG(5), 62 SUB_COMP_FLAG_BIT_6 = SUB_FLAG(6), 63 SUB_COMP_FLAG_BIT_7 = SUB_FLAG(7), 64 SUB_COMP_FLAG_BIT_8 = SUB_FLAG(8), 65 SUB_COMP_FLAG_BIT_9 = SUB_FLAG(9), 66 SUB_COMP_FLAG_BIT_10 = SUB_FLAG(10), 67 SUB_COMP_FLAG_PF_INIT = SUB_COMP_FLAG_BIT_10, 68 SUB_COMP_FLAG_BIT_11 = SUB_FLAG(11), 69 SUB_COMP_FLAG_NSENTRY = SUB_COMP_FLAG_BIT_11, 70 SUB_COMP_FLAG_BIT_12 = SUB_FLAG(12), 71 SUB_COMP_FLAG_BIT_13 = SUB_FLAG(13), 72 SUB_COMP_FLAG_BIT_14 = SUB_FLAG(14), 73 SUB_COMP_FLAG_BIT_15 = SUB_FLAG(15), 74 SUB_COMP_FLAG_BIT_16 = SUB_FLAG(16), 75 SUB_COMP_FLAG_BIT_17 = SUB_FLAG(17), 76 SUB_COMP_FLAG_BIT_18 = SUB_FLAG(18), 77 SUB_COMP_FLAG_BIT_19 = SUB_FLAG(19), 78 SUB_COMP_FLAG_BIT_20 = SUB_FLAG(20), 79 SUB_COMP_FLAG_BIT_21 = SUB_FLAG(21), 80 SUB_COMP_FLAG_BIT_22 = SUB_FLAG(22), 81 SUB_COMP_FLAG_BIT_23 = SUB_FLAG(23), 82 SUB_COMP_FLAG_BIT_24 = SUB_FLAG(24), 83 SUB_COMP_FLAG_BIT_25 = SUB_FLAG(25), 84 SUB_COMP_FLAG_BIT_26 = SUB_FLAG(26), 85 SUB_COMP_FLAG_BIT_27 = SUB_FLAG(27), 86 SUB_COMP_FLAG_BIT_28 = SUB_FLAG(28), 87 SUB_COMP_FLAG_BIT_29 = SUB_FLAG(29), 88 SUB_COMP_FLAG_BIT_30 = SUB_FLAG(30), 89 SUB_COMP_FLAG_MASK = SUB_COMP_FLAG_VTABLE | SUB_COMP_FLAG_METHOD 90 | SUB_COMP_FLAG_NSENTRY | SUB_COMP_FLAG_PF_INIT 91 } sub_comp_flags_enum; 92 #undef SUB_FLAG 93 94 #define Sub_comp_get_FLAGS(o) ((o)->comp_flags) 95 #define Sub_comp_flag_TEST(flag, o) (Sub_comp_get_FLAGS(o) & SUB_COMP_FLAG_ ## flag) 96 #define Sub_comp_flag_SET(flag, o) (Sub_comp_get_FLAGS(o) |= SUB_COMP_FLAG_ ## flag) 97 #define Sub_comp_flag_CLEAR(flag, o) (Sub_comp_get_FLAGS(o) &= ~(UINTVAL)(SUB_COMP_FLAG_ ## flag)) 98 99 #define Sub_comp_flags_SETTO(o, f) Sub_comp_get_FLAGS(o) = (f) 100 #define Sub_comp_flags_CLEARALL(o) Sub_comp_flags_SETTO((o), 0) 101 102 #define Sub_comp_INIT_TEST(o) Sub_comp_flag_TEST(PF_INIT, o) 103 #define Sub_comp_INIT_SET(o) Sub_comp_flag_SET(PF_INIT, o) 104 #define Sub_comp_INIT_CLEAR(o) Sub_comp_flag_CLEAR(PF_INIT, o) 105 106 /* 107 * maximum sub recursion depth 108 */ 109 110 #define RECURSION_LIMIT 1000 111 112 113 /* 114 * Counts and flags describing the arguments. 115 */ 116 typedef struct Parrot_sub_arginfo { 117 Parrot_UInt2 pos_required; 118 Parrot_UInt2 pos_optional; 119 Parrot_UInt2 named_required; 120 Parrot_UInt2 named_optional; 121 Parrot_UInt1 pos_slurpy; 122 Parrot_UInt1 named_slurpy; 123 } Parrot_sub_arginfo; 124 125 #define PMC_get_sub(interp, pmc, sub) \ 126 do { \ 127 const INTVAL type = (pmc)->vtable->base_type; \ 128 if (type == enum_class_Sub || \ 129 type == enum_class_Coroutine) \ 130 {\ 131 (sub) = PARROT_SUB((pmc)); \ 132 } \ 133 else { \ 134 (sub) = (Parrot_Sub_attributes*)Parrot_get_sub_pmc_from_subclass((interp), (pmc)); \ 135 } \ 136 } while (0) 137 138 typedef struct Parrot_Sub_attributes Parrot_sub; 139 typedef struct Parrot_Coroutine_attributes Parrot_coro; 140 typedef struct Parrot_Continuation_attributes Parrot_cont; 141 142 #define PMC_cont(pmc) PARROT_CONTINUATION(pmc) 143 144 typedef struct Parrot_Context_info { 145 STRING *subname; 146 STRING *nsname; 147 STRING *fullname; 148 STRING *file; 149 opcode_t *address; 150 int pc; 151 int line; 152 } Parrot_Context_info; 153 154 /* HEADERIZER BEGIN: src/sub.c */ 155 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 156 157 PARROT_EXPORT 158 PARROT_CANNOT_RETURN_NULL 159 void * Parrot_get_sub_pmc_from_subclass(PARROT_INTERP, ARGIN(PMC *subclass)) 160 __attribute__nonnull__(1) 161 __attribute__nonnull__(2); 162 163 PARROT_EXPORT 164 void Parrot_sub_capture_lex(PARROT_INTERP, ARGMOD(PMC *sub_pmc)) 165 __attribute__nonnull__(1) 166 __attribute__nonnull__(2) 167 FUNC_MODIFIES(*sub_pmc); 168 169 PARROT_EXPORT 170 int Parrot_sub_context_get_info(PARROT_INTERP, 171 ARGIN(PMC *ctx), 172 ARGOUT(Parrot_Context_info *info)) 173 __attribute__nonnull__(1) 174 __attribute__nonnull__(2) 175 __attribute__nonnull__(3) 176 FUNC_MODIFIES(*info); 177 178 PARROT_EXPORT 179 PARROT_CAN_RETURN_NULL 180 PARROT_WARN_UNUSED_RESULT 181 STRING* Parrot_sub_Context_infostr(PARROT_INTERP, 182 ARGIN(PMC *ctx), 183 int is_top) 184 __attribute__nonnull__(1) 185 __attribute__nonnull__(2); 186 187 PARROT_EXPORT 188 PARROT_CAN_RETURN_NULL 189 PARROT_WARN_UNUSED_RESULT 190 STRING* Parrot_sub_full_sub_name(PARROT_INTERP, ARGIN_NULLOK(PMC* sub_pmc)) 191 __attribute__nonnull__(1); 192 193 PARROT_EXPORT 194 PARROT_CANNOT_RETURN_NULL 195 PARROT_WARN_UNUSED_RESULT 196 PMC* Parrot_sub_new_closure(PARROT_INTERP, ARGIN(PMC *sub_pmc)) 197 __attribute__nonnull__(1) 198 __attribute__nonnull__(2); 199 200 void Parrot_sub_continuation_check(PARROT_INTERP, ARGIN(const PMC *pmc)) 201 __attribute__nonnull__(1) 202 __attribute__nonnull__(2); 203 204 void Parrot_sub_continuation_rewind_environment(PARROT_INTERP, 205 ARGIN(PMC *pmc)) 206 __attribute__nonnull__(1) 207 __attribute__nonnull__(2); 208 209 PARROT_CAN_RETURN_NULL 210 PARROT_WARN_UNUSED_RESULT 211 PMC* Parrot_sub_find_dynamic_pad(PARROT_INTERP, 212 ARGIN(STRING *lex_name), 213 ARGIN(PMC *ctx)) 214 __attribute__nonnull__(1) 215 __attribute__nonnull__(2) 216 __attribute__nonnull__(3); 217 218 PARROT_CAN_RETURN_NULL 219 PARROT_WARN_UNUSED_RESULT 220 PMC* Parrot_sub_find_pad(PARROT_INTERP, 221 ARGIN(STRING *lex_name), 222 ARGIN(PMC *ctx)) 223 __attribute__nonnull__(1) 224 __attribute__nonnull__(2) 225 __attribute__nonnull__(3); 226 227 PARROT_CANNOT_RETURN_NULL 228 STRING * Parrot_sub_get_filename_from_pc(PARROT_INTERP, 229 ARGIN_NULLOK(PMC *subpmc), 230 ARGIN_NULLOK(opcode_t *pc)) 231 __attribute__nonnull__(1); 232 233 INTVAL Parrot_sub_get_line_from_pc(PARROT_INTERP, 234 ARGIN_NULLOK(PMC *subpmc), 235 ARGIN_NULLOK(opcode_t *pc)) 236 __attribute__nonnull__(1); 237 238 #define ASSERT_ARGS_Parrot_get_sub_pmc_from_subclass \ 239 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 240 PARROT_ASSERT_ARG(interp) \ 241 , PARROT_ASSERT_ARG(subclass)) 242 #define ASSERT_ARGS_Parrot_sub_capture_lex __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 243 PARROT_ASSERT_ARG(interp) \ 244 , PARROT_ASSERT_ARG(sub_pmc)) 245 #define ASSERT_ARGS_Parrot_sub_context_get_info __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 246 PARROT_ASSERT_ARG(interp) \ 247 , PARROT_ASSERT_ARG(ctx) \ 248 , PARROT_ASSERT_ARG(info)) 249 #define ASSERT_ARGS_Parrot_sub_Context_infostr __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 250 PARROT_ASSERT_ARG(interp) \ 251 , PARROT_ASSERT_ARG(ctx)) 252 #define ASSERT_ARGS_Parrot_sub_full_sub_name __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 253 PARROT_ASSERT_ARG(interp)) 254 #define ASSERT_ARGS_Parrot_sub_new_closure __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 255 PARROT_ASSERT_ARG(interp) \ 256 , PARROT_ASSERT_ARG(sub_pmc)) 257 #define ASSERT_ARGS_Parrot_sub_continuation_check __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 258 PARROT_ASSERT_ARG(interp) \ 259 , PARROT_ASSERT_ARG(pmc)) 260 #define ASSERT_ARGS_Parrot_sub_continuation_rewind_environment \ 261 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 262 PARROT_ASSERT_ARG(interp) \ 263 , PARROT_ASSERT_ARG(pmc)) 264 #define ASSERT_ARGS_Parrot_sub_find_dynamic_pad __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 265 PARROT_ASSERT_ARG(interp) \ 266 , PARROT_ASSERT_ARG(lex_name) \ 267 , PARROT_ASSERT_ARG(ctx)) 268 #define ASSERT_ARGS_Parrot_sub_find_pad __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 269 PARROT_ASSERT_ARG(interp) \ 270 , PARROT_ASSERT_ARG(lex_name) \ 271 , PARROT_ASSERT_ARG(ctx)) 272 #define ASSERT_ARGS_Parrot_sub_get_filename_from_pc \ 273 __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 274 PARROT_ASSERT_ARG(interp)) 275 #define ASSERT_ARGS_Parrot_sub_get_line_from_pc __attribute__unused__ int _ASSERT_ARGS_CHECK = (\ 276 PARROT_ASSERT_ARG(interp)) 277 /* Don't modify between HEADERIZER BEGIN / HEADERIZER END. Your changes will be lost. */ 278 /* HEADERIZER END: src/sub.c */ 279 280 #endif /* PARROT_SUB_H_GUARD */ 281 282 /* 283 * Local variables: 284 * c-file-style: "parrot" 285 * End: 286 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' : 287 */ 288