For context, this is a bug that we ran into while looking for a way to load and evaluate a code within a fiber.
In H2O, we would like to evaluate mruby code that defines a Rack handler within a fiber, so that when a blocking operation is triggered within the evaluation Fiber.yield could be used to transfer that operation into C code.
Essentially, we would like to allow users to write something like the snippet below, which will be evaluated within a fiber (note: join methods calls Fiber.yield to delegate network operations to the main fiber).
# cache the response from http://upstream, and use it for every requestcached_resp=http_request("http://upstream/").join.joinProc.newdo |env|
@matz Thank you for the clarification. The reasoning sounds totally reasonable that you cannot call yield from an eval-ed script running in a fiber due to C function boundaries.
OTOH, may I ask if you have any idea that we could solve the issue? As stated in #3415 (comment) what we want to do is to evaluate user-specified script in a child fiber. We are more than happy to write such solution in C.
Another question: are there standard ways to generate Proc's instance from mruby source code?
(sorry for changing the topic from this issue)
We found that we can address the issue described in #3415 (comment) in another way, by passing the compiled code to some preparing method as a proc. Like the following, prepare_app method calls that compiled proc in a fiber (because compiled_proc may call Fiber.yield).
But as far as I see the mruby API, there seems to be no ways to do it. mrb_generate_code returns struct RProc*, but can I convert it to a Proc's instance? I tried mrb_obj_value(mrb_generate_code(mrb, parser_state)), but it failed when that proc is called. Am I missing something?