__builtin_inline!

Add an experimental `__builtin_inline!(c_expression)` special intrinsic
which run a C code snippet.
In `c_expression`, you can access the following variables:
  * ec (rb_execution_context_t *)
  * self (const VALUE)
  * local variables (const VALUE)
Not that you can read these variables, but you can not write them.
You need to return from this expression and return value will be a
result of __builtin_inline!().

Examples:
  `def foo(x) __builtin_inline!('return rb_p(x);'); end` calls `p(x)`.
  `def double(x) __builtin_inline!('return INT2NUM(NUM2INT(x) * 2);')`
  returns x*2.
This commit is contained in:
Koichi Sasada 2019-11-11 16:38:46 +09:00
parent 05a5c69e1a
commit 3141642380
5 changed files with 93 additions and 10 deletions

View file

@ -25,9 +25,12 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin
const unsigned char *bin = builtin_lookup(feature_name, &size);
// load binary
GET_VM()->builtin_function_table = table;
rb_vm_t *vm = GET_VM();
if (vm->builtin_function_table != NULL) rb_bug("vm->builtin_function_table should be NULL.");
vm->builtin_function_table = table;
vm->builtin_inline_index = 0;
const rb_iseq_t *iseq = rb_iseq_ibf_load_bytes((const char *)bin, size);
GET_VM()->builtin_function_table = NULL;
vm->builtin_function_table = NULL;
// exec
rb_iseq_eval(iseq);
@ -38,3 +41,11 @@ Init_builtin(void)
{
//
}
// inline
VALUE
rb_vm_lvar_exposed(rb_execution_context_t *ec, int index)
{
const rb_control_frame_t *cfp = ec->cfp;
return cfp->ep[index];
}