[439] | 1 | /**
|
---|
| 2 | ** @file mruby/proc.h - Proc class
|
---|
[270] | 3 | **
|
---|
| 4 | ** See Copyright Notice in mruby.h
|
---|
| 5 | */
|
---|
| 6 |
|
---|
| 7 | #ifndef MRUBY_PROC_H
|
---|
| 8 | #define MRUBY_PROC_H
|
---|
| 9 |
|
---|
[331] | 10 | #include "common.h"
|
---|
| 11 | #include <mruby/irep.h>
|
---|
[270] | 12 |
|
---|
| 13 | /**
|
---|
| 14 | * Proc class
|
---|
| 15 | */
|
---|
| 16 | MRB_BEGIN_DECL
|
---|
| 17 |
|
---|
| 18 | struct REnv {
|
---|
| 19 | MRB_OBJECT_HEADER;
|
---|
| 20 | mrb_value *stack;
|
---|
[439] | 21 | struct mrb_context *cxt;
|
---|
| 22 | mrb_sym mid;
|
---|
[270] | 23 | };
|
---|
| 24 |
|
---|
[439] | 25 | /* flags (21bits): 1(shared flag):10(cioff/bidx):10(stack_len) */
|
---|
| 26 | #define MRB_ENV_SET_STACK_LEN(e,len) ((e)->flags = (((e)->flags & ~0x3ff)|((unsigned int)(len) & 0x3ff)))
|
---|
| 27 | #define MRB_ENV_STACK_LEN(e) ((mrb_int)((e)->flags & 0x3ff))
|
---|
| 28 | #define MRB_ENV_STACK_UNSHARED (1<<20)
|
---|
| 29 | #define MRB_ENV_UNSHARE_STACK(e) ((e)->flags |= MRB_ENV_STACK_UNSHARED)
|
---|
| 30 | #define MRB_ENV_STACK_SHARED_P(e) (((e)->flags & MRB_ENV_STACK_UNSHARED) == 0)
|
---|
| 31 | #define MRB_ENV_BIDX(e) (((e)->flags >> 10) & 0x3ff)
|
---|
| 32 | #define MRB_ENV_SET_BIDX(e,idx) ((e)->flags = (((e)->flags & ~(0x3ff<<10))|((unsigned int)(idx) & 0x3ff)<<10))
|
---|
[270] | 33 |
|
---|
[439] | 34 | void mrb_env_unshare(mrb_state*, struct REnv*);
|
---|
[331] | 35 |
|
---|
[270] | 36 | struct RProc {
|
---|
| 37 | MRB_OBJECT_HEADER;
|
---|
| 38 | union {
|
---|
| 39 | mrb_irep *irep;
|
---|
| 40 | mrb_func_t func;
|
---|
| 41 | } body;
|
---|
[439] | 42 | struct RProc *upper;
|
---|
| 43 | union {
|
---|
| 44 | struct RClass *target_class;
|
---|
| 45 | struct REnv *env;
|
---|
| 46 | } e;
|
---|
[270] | 47 | };
|
---|
| 48 |
|
---|
| 49 | /* aspec access */
|
---|
| 50 | #define MRB_ASPEC_REQ(a) (((a) >> 18) & 0x1f)
|
---|
| 51 | #define MRB_ASPEC_OPT(a) (((a) >> 13) & 0x1f)
|
---|
| 52 | #define MRB_ASPEC_REST(a) (((a) >> 12) & 0x1)
|
---|
| 53 | #define MRB_ASPEC_POST(a) (((a) >> 7) & 0x1f)
|
---|
| 54 | #define MRB_ASPEC_KEY(a) (((a) >> 2) & 0x1f)
|
---|
| 55 | #define MRB_ASPEC_KDICT(a) ((a) & (1<<1))
|
---|
| 56 | #define MRB_ASPEC_BLOCK(a) ((a) & 1)
|
---|
| 57 |
|
---|
[439] | 58 | #define MRB_PROC_CFUNC_FL 128
|
---|
| 59 | #define MRB_PROC_CFUNC_P(p) (((p)->flags & MRB_PROC_CFUNC_FL) != 0)
|
---|
| 60 | #define MRB_PROC_CFUNC(p) (p)->body.func
|
---|
[270] | 61 | #define MRB_PROC_STRICT 256
|
---|
| 62 | #define MRB_PROC_STRICT_P(p) (((p)->flags & MRB_PROC_STRICT) != 0)
|
---|
[331] | 63 | #define MRB_PROC_ORPHAN 512
|
---|
| 64 | #define MRB_PROC_ORPHAN_P(p) (((p)->flags & MRB_PROC_ORPHAN) != 0)
|
---|
[439] | 65 | #define MRB_PROC_ENVSET 1024
|
---|
| 66 | #define MRB_PROC_ENV_P(p) (((p)->flags & MRB_PROC_ENVSET) != 0)
|
---|
| 67 | #define MRB_PROC_ENV(p) (MRB_PROC_ENV_P(p) ? (p)->e.env : NULL)
|
---|
| 68 | #define MRB_PROC_TARGET_CLASS(p) (MRB_PROC_ENV_P(p) ? (p)->e.env->c : (p)->e.target_class)
|
---|
| 69 | #define MRB_PROC_SET_TARGET_CLASS(p,tc) do {\
|
---|
| 70 | if (MRB_PROC_ENV_P(p)) {\
|
---|
| 71 | (p)->e.env->c = (tc);\
|
---|
| 72 | mrb_field_write_barrier(mrb, (struct RBasic*)(p)->e.env, (struct RBasic*)(tc));\
|
---|
| 73 | }\
|
---|
| 74 | else {\
|
---|
| 75 | (p)->e.target_class = (tc);\
|
---|
| 76 | mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)(tc));\
|
---|
| 77 | }\
|
---|
| 78 | } while (0)
|
---|
| 79 | #define MRB_PROC_SCOPE 2048
|
---|
| 80 | #define MRB_PROC_SCOPE_P(p) (((p)->flags & MRB_PROC_SCOPE) != 0)
|
---|
[270] | 81 |
|
---|
| 82 | #define mrb_proc_ptr(v) ((struct RProc*)(mrb_ptr(v)))
|
---|
| 83 |
|
---|
| 84 | struct RProc *mrb_proc_new(mrb_state*, mrb_irep*);
|
---|
| 85 | struct RProc *mrb_closure_new(mrb_state*, mrb_irep*);
|
---|
| 86 | MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t);
|
---|
| 87 | MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals);
|
---|
| 88 | void mrb_proc_copy(struct RProc *a, struct RProc *b);
|
---|
[439] | 89 | mrb_int mrb_proc_arity(const struct RProc *p);
|
---|
[270] | 90 |
|
---|
| 91 | /* implementation of #send method */
|
---|
[439] | 92 | mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
|
---|
[270] | 93 |
|
---|
| 94 | /* following functions are defined in mruby-proc-ext so please include it when using */
|
---|
[439] | 95 | MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv);
|
---|
| 96 | MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx);
|
---|
[270] | 97 | /* old name */
|
---|
| 98 | #define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx)
|
---|
| 99 |
|
---|
[439] | 100 | #define MRB_METHOD_FUNC_FL 1
|
---|
| 101 | #define MRB_METHOD_NOARG_FL 2
|
---|
| 102 | #ifndef MRB_METHOD_T_STRUCT
|
---|
| 103 |
|
---|
| 104 | #define MRB_METHOD_FUNC_P(m) (((uintptr_t)(m))&MRB_METHOD_FUNC_FL)
|
---|
| 105 | #define MRB_METHOD_NOARG_P(m) (((uintptr_t)(m))&MRB_METHOD_NOARG_FL)
|
---|
| 106 | #define MRB_METHOD_NOARG_SET(m) ((m)=(mrb_method_t)(((uintptr_t)(m))|MRB_METHOD_NOARG_FL))
|
---|
[440] | 107 | #define MRB_METHOD_FUNC(m) ((mrb_func_t)((uintptr_t)(m)>>2))
|
---|
| 108 | #define MRB_METHOD_FROM_FUNC(m,fn) ((m)=(mrb_method_t)((((uintptr_t)(fn))<<2)|MRB_METHOD_FUNC_FL))
|
---|
[439] | 109 | #define MRB_METHOD_FROM_PROC(m,pr) ((m)=(mrb_method_t)(pr))
|
---|
| 110 | #define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
|
---|
| 111 | #define MRB_METHOD_PROC(m) ((struct RProc*)(m))
|
---|
| 112 | #define MRB_METHOD_UNDEF_P(m) ((m)==0)
|
---|
| 113 |
|
---|
| 114 | #else
|
---|
| 115 |
|
---|
| 116 | #define MRB_METHOD_FUNC_P(m) ((m).flags&MRB_METHOD_FUNC_FL)
|
---|
| 117 | #define MRB_METHOD_NOARG_P(m) ((m).flags&MRB_METHOD_NOARG_FL)
|
---|
| 118 | #define MRB_METHOD_FUNC(m) ((m).func)
|
---|
| 119 | #define MRB_METHOD_NOARG_SET(m) do{(m).flags|=MRB_METHOD_NOARG_FL;}while(0)
|
---|
| 120 | #define MRB_METHOD_FROM_FUNC(m,fn) do{(m).flags=MRB_METHOD_FUNC_FL;(m).func=(fn);}while(0)
|
---|
| 121 | #define MRB_METHOD_FROM_PROC(m,pr) do{(m).flags=0;(m).proc=(pr);}while(0)
|
---|
| 122 | #define MRB_METHOD_PROC_P(m) (!MRB_METHOD_FUNC_P(m))
|
---|
| 123 | #define MRB_METHOD_PROC(m) ((m).proc)
|
---|
| 124 | #define MRB_METHOD_UNDEF_P(m) ((m).proc==NULL)
|
---|
| 125 |
|
---|
| 126 | #endif /* MRB_METHOD_T_STRUCT */
|
---|
| 127 |
|
---|
| 128 | #define MRB_METHOD_CFUNC_P(m) (MRB_METHOD_FUNC_P(m)?TRUE:(MRB_METHOD_PROC(m)?(MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m))):FALSE))
|
---|
| 129 | #define MRB_METHOD_CFUNC(m) (MRB_METHOD_FUNC_P(m)?MRB_METHOD_FUNC(m):((MRB_METHOD_PROC(m)&&MRB_PROC_CFUNC_P(MRB_METHOD_PROC(m)))?MRB_PROC_CFUNC(MRB_METHOD_PROC(m)):NULL))
|
---|
| 130 |
|
---|
| 131 |
|
---|
[331] | 132 | #include <mruby/khash.h>
|
---|
[439] | 133 | KHASH_DECLARE(mt, mrb_sym, mrb_method_t, TRUE)
|
---|
[270] | 134 |
|
---|
| 135 | MRB_END_DECL
|
---|
| 136 |
|
---|
| 137 | #endif /* MRUBY_PROC_H */
|
---|