theKernel 10.0
Loading...
Searching...
No Matches
MkCall_rb.c File Reference

tag: nhi1-release-250425 More...

#include "LibMkKernel_private_rb.h"
#include "misc_check_rb.h"
+ Include dependency graph for MkCall_rb.c:

Go to the source code of this file.

Macros

#define META_FILE_NAME   "MkCall_rb.c"
 

Functions

static VALUE rbmkkernel_sRescue (MK_RT mkrt, MK_MNG const mng, VALUE(*proc)(ANYARGS), VALUE data)
 
static VALUE rbmkkernel_sCallMethod (VALUE array)
 
static VALUE rbmkkernel_sCallProc (VALUE array)
 
enum MkErrorE rbmkkernel_CheckCallable (OT_Check_ARGS, MK_PTR *retP)
 
void rbmkkernel_CallFree (MK_PTR *callP)
 
void rbmkkernel_CallFreeOnce (MK_CBP *callP)
 
enum MkErrorE rbmkkernel_ObjectDeleteCall (MK_RT mkrt, MK_OBJN const obj, MK_STRN const typeName, MK_HDL const typeHdl, MK_HDL const objHdl, MK_CBP const __data__)
 
void rbmkkernel_ObjectDeleteFree (MkObjectDeleteFreeF_ARGS)
 

Detailed Description

tag: nhi1-release-250425

Definition in file MkCall_rb.c.

Macro Definition Documentation

◆ META_FILE_NAME

#define META_FILE_NAME   "MkCall_rb.c"

Definition at line 12 of file MkCall_rb.c.

Function Documentation

◆ rbmkkernel_CallFree()

void rbmkkernel_CallFree ( MK_PTR * callP)

Definition at line 114 of file MkCall_rb.c.

114 {
115 // BUG FIX → ruby crash on object allocation during GC at "Nhi1Exec Bug3.rb".
116 // The crash accourse because of GC is active after a raise of an error at constructor AND
117 // the service-callback is deleted in "DECR_REG" which create a NEW object in "rb_ary_delete" !!
118 // if (callP == NULL || *callP == NULL || rb_during_gc() ) return;
119 if (callP == NULL || *callP == NULL ) return;
120 struct MkCallS *call = (struct MkCallS*) *callP;
121 if (!OT_LNG_NULL_IS(call->procCallback)) {
122 DECR_REF(&call->procCallback);
123 call->procCallback = Qnil;
124 }
125 if (!OT_LNG_NULL_IS(call->procArgs)) {
126 DECR_REF(&call->procArgs);
127 call->procArgs = Qnil;
128 }
129//printV("call=%p, data=%p\n", call, call->procCallback)
130 if (call->isAlloc) MkSysFree(*callP);
131 else *callP = NULL;
132}
#define OT_LNG_NULL_IS(obj)
#define DECR_REF(valP)
#define MkSysFree(pointer)
VALUE procCallback
VALUE procArgs

◆ rbmkkernel_CallFreeOnce()

void rbmkkernel_CallFreeOnce ( MK_CBP * callP)

Definition at line 134 of file MkCall_rb.c.

135{
136 MK(CallFree) (callP);
137}
#define MK(n)

◆ rbmkkernel_CheckCallable()

enum MkErrorE rbmkkernel_CheckCallable ( OT_Check_ARGS ,
MK_PTR * retP )

Definition at line 47 of file MkCall_rb.c.

50 {
51 if ((*skipP) >= objc) {
52 WrongNumArgs(hdl, (*skipP), objc, -999, +999, arg);
53 goto error;
54 }
55
56 VALUE val = objv[(*skipP)++];
57
58 struct MkCallS *call = *retP;
59 if (*retP == NULL) {
60 call = (struct MkCallS *) MkSysCalloc(MK_ERROR_PANIC,1,sizeof(struct MkCallS));
61 call->isAlloc = true;
62 }
63
64 call->hdl = hdl;
65 call->mkrt = MK_RT_PTR;
66 call->procArgs = rb_ary_new();
67 INCR_REF(&call->procArgs);
68
69 if (rb_obj_is_kind_of(val, rb_cMethod) == Qtrue) {
70 // val belongs to calling object, but is NOT callable from other
72 call->procCallback = val;
73 INCR_REF(&call->procCallback);
74 } else if (rb_obj_is_kind_of(val, rb_cProc) == Qtrue) {
75 // val belongs to global proc and is callable from other
76 call->procType = MkCallS_proc;
77 call->procCallback = val;
78 INCR_REF(&call->procCallback);
79 } else if (NIL_P(val)) {
80 call->procCallback = Qnil;
81 } else if (rb_obj_is_kind_of(val, rb_cUnboundMethod) == Qtrue) {
82 // val belongs to calling object, but is NOT callable from other
84 call->procCallback = val;
85 INCR_REF(&call->procCallback);
86 } else if (rb_obj_is_kind_of(val, rb_cString) == Qtrue) {
87 const MkStringR tmp = VAL2MkStringR(val);
88 if (MkStringIsNULL(tmp)) {
89 call->procCallback = Qnil;
90 } else {
92 goto error;
93 }
94 } else {
95 WrongCallableError(OT_OBJ_TYPE_STRING(val));
96 goto error;
97 }
98
99 if (call->procCallback == Qnil) {
100 DECR_REF(&call->procArgs);
101 call->procArgs = Qnil;
102 if ( call->isAlloc ) MkSysFree(call);
103 *retP = NULL;
104 } else {
105 call->procArity = VAL2I32(rb_funcallv(call->procCallback,NS(id_arity),0,NULL));
106 *retP = call;
107 }
108 return MK_OK;
109error:
110 return OT_ERROR_STACK;
111}
#define INCR_REF(valP)
#define NS(n)
#define VAL2I32(val)
#define VAL2MkStringR(_obj)
#define MK_ERROR_PANIC
@ MK_OK
(persistent) everything is OK.
static bool MkStringIsNULL(MkStringR const strR)
check if strR is MK_NULL_STR return true or false …
MK_PTR MkSysCalloc(MK_OBJN fmtobj, size_t const nmemb, size_t const size)
calloc syscall with rbmkkernel error plugin
#define MK_RT_PTR
#define OT_ERROR_STACK
#define WrongNumArgs(...)
#define WrongCallableError(got)
MK_I32 procArity
enum MkCallS::@0 procType
@ MkCallS_unbound_method
string data default format …
MK_STRN ptr
pointer to the string data

◆ rbmkkernel_ObjectDeleteCall()

enum MkErrorE rbmkkernel_ObjectDeleteCall ( MK_RT mkrt,
MK_OBJN const obj,
MK_STRN const typeName,
MK_HDL const typeHdl,
MK_HDL const objHdl,
MK_CBP const __data__ )

Definition at line 154 of file MkCall_rb.c.

155{
157
158 // if NO self object is available than NO callback is called
159 if (!MkSelfExists(obj)) return MK_OK;
160
161 struct MkCallS *call = __data__;
162 int argNum = 3;
163
164 rb_set_errinfo(Qnil);
165
166 // 1. check environment
167 if (OT_LNG_NULL_IS(call->procCallback)) return MK_OK;
168
169 // 2. if not already done initialize
170 if (call->procCall == NULL) {
171 switch (call->procType) {
172 case MkCallS_own_method: {
173 call->procCall = NS(sCallMethod);
174 if (argNum != call->procArity) goto methode_arg_error;
175 }
176 break;
177 case MkCallS_proc:
178 call->procCall = NS(sCallProc);
179 if (argNum != call->procArity) goto methode_arg_error;
180 break;
181 default:
182 MkErrorSetV_3M(obj, "WrongInitError", "found invalid procType for callback '%s'", VAL2STRN(call->procCallback));
183 goto error;
184 break;
185 }
186 }
187
188 // 3. call callback
189 VALUE ary = rb_ary_resize(call->procArgs,4);
190 rb_ary_store(ary,0,call->procCallback);
191 rb_ary_store(ary,1,STRN2VAL(typeName));
192 rb_ary_store(ary,2,HDL2VAL(typeHdl));
193 rb_ary_store(ary,3,HDL2VAL(objHdl));
194 // info: https://docs.ruby-lang.org/en/master/extension_rdoc.html#label-Appendix+E.+RB_GC_GUARD+to+protect+from+premature+GC
195 NS(sRescue)(MK_RT_CALL call->hdl,call->procCall,ary);
197 return MkErrorGetCode_0E();
198
199methode_arg_error:
200 MkErrorSetV_3M(obj, "WrongNumberOfArgError",
201 "for callback '%s' exactly '%d' argument is required, but '%d' was received",
202 VAL2STRN(call->procCallback), argNum, call->procArity);
203 goto error;
204
205error:
206MkDbgDeepX_3(mqctx, "EEE", "cmd=%s", VAL2STRN(rb_inspect(call->procCallback)));
207 return MkErrorStack_0E();
208}
#define MkErrorCheck_0E()
check return-code and goto error on error …
#define HDL2VAL(nat)
#define VAL2STRN(val)
#define STRN2VAL(nat)
#define MkErrorGetCode_0E()
#define MkErrorStack_0E()
#define MkErrorSetV_3M(err, callfunc, printfmt,...)
#define MkDbgDeepX_3(m, ident, fmt,...)
static bool MkSelfExists(MK_OBJN obj)
Check if the MkObjectS::self exists …
#define MkObjectDeleteCallF_CHECK
validate call to MkObjectDeleteCallF
#define MK_RT_CALL
rbmkkernel_procCallF procCall

◆ rbmkkernel_ObjectDeleteFree()

void rbmkkernel_ObjectDeleteFree ( MkObjectDeleteFreeF_ARGS )

Definition at line 210 of file MkCall_rb.c.

211{
212 MK(CallFree)(dataP);
213}

◆ rbmkkernel_sCallMethod()

static VALUE rbmkkernel_sCallMethod ( VALUE array)
static

Definition at line 36 of file MkCall_rb.c.

36 {
37 const VALUE *valP = rb_array_const_ptr(array);
38 return rb_method_call((int)RARRAY_LEN(array)-1, &valP[1], valP[0]);
39}

◆ rbmkkernel_sCallProc()

static VALUE rbmkkernel_sCallProc ( VALUE array)
static

Definition at line 42 of file MkCall_rb.c.

42 {
43 const VALUE *valP = rb_array_const_ptr(array);
44 return rb_proc_call_with_block(valP[0], (int)RARRAY_LEN(array)-1, &valP[1], Qnil);
45}

◆ rbmkkernel_sRescue()

static VALUE rbmkkernel_sRescue ( MK_RT mkrt,
MK_MNG const mng,
VALUE(* proc )(ANYARGS),
VALUE data )
inlinestatic

Definition at line 19 of file MkCall_rb.c.

24 {
25 int state;
26 VALUE ret = rb_protect(proc, data, &state);
27 if (state) {
28 OT_ERROR_LNG_2_META_2(mng,"ProcessEvent");
29 }
30 return ret;
31}
#define OT_ERROR_LNG_2_META_2(m, s)