[前][次][番号順一覧][スレッド一覧]

ruby-changes:57523

From: Jeremy <ko1@a...>
Date: Wed, 4 Sep 2019 03:39:37 +0900 (JST)
Subject: [ruby-changes:57523] 39c3252cd1 (master): Merge pull request #2422 from jeremyevans/rb_keyword_given_p

https://git.ruby-lang.org/ruby.git/commit/?id=39c3252cd1

From 39c3252cd175074581855e5f9681cc723c15ff72 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Tue, 3 Sep 2019 11:32:02 -0700
Subject: Merge pull request #2422 from jeremyevans/rb_keyword_given_p

Add rb_keyword_given_p to the C-API

diff --git a/eval.c b/eval.c
index 30d4ea5..eb34c35 100644
--- a/eval.c
+++ b/eval.c
@@ -899,6 +899,14 @@ rb_block_given_p(void) https://github.com/ruby/ruby/blob/trunk/eval.c#L899
     }
 }
 
+int rb_vm_cframe_keyword_p(const rb_control_frame_t *cfp);
+
+int
+rb_keyword_given_p(void)
+{
+    return rb_vm_cframe_keyword_p(GET_EC()->cfp);
+}
+
 VALUE rb_eThreadError;
 
 /*! Declares that the current method needs a block.
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 0d7880b..53d4eab 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -1960,6 +1960,7 @@ VALUE rb_yield_values(int n, ...); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1960
 VALUE rb_yield_values2(int n, const VALUE *argv);
 VALUE rb_yield_splat(VALUE);
 VALUE rb_yield_block(VALUE, VALUE, int, const VALUE *, VALUE); /* rb_block_call_func */
+int rb_keyword_given_p(void);
 int rb_block_given_p(void);
 void rb_need_block(void);
 VALUE rb_iterate(VALUE(*)(VALUE),VALUE,rb_block_call_func_t,VALUE);
diff --git a/vm.c b/vm.c
index cbd7b31..88b76c4 100644
--- a/vm.c
+++ b/vm.c
@@ -96,6 +96,12 @@ VM_CF_BLOCK_HANDLER(const rb_control_frame_t * const cfp) https://github.com/ruby/ruby/blob/trunk/vm.c#L96
     return VM_ENV_BLOCK_HANDLER(ep);
 }
 
+int
+rb_vm_cframe_keyword_p(const rb_control_frame_t *cfp)
+{
+    return VM_FRAME_CFRAME_KW_P(cfp);
+}
+
 VALUE
 rb_vm_frame_block_handler(const rb_control_frame_t *cfp)
 {
diff --git a/vm_core.h b/vm_core.h
index 1ebcea7..eec80e4 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -1166,11 +1166,11 @@ typedef rb_control_frame_t * https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1166
 
 enum {
     /* Frame/Environment flag bits:
-     *   MMMM MMMM MMMM MMMM ____ __FF FFFF EEEX (LSB)
+     *   MMMM MMMM MMMM MMMM ____ _FFF FFFF EEEX (LSB)
      *
      * X   : tag for GC marking (It seems as Fixnum)
      * EEE : 3 bits Env flags
-     * FF..: 6 bits Frame flags
+     * FF..: 7 bits Frame flags
      * MM..: 15 bits frame magic (to check frame corruption)
      */
 
@@ -1194,6 +1194,7 @@ enum { https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1194
     VM_FRAME_FLAG_CFRAME    = 0x0080,
     VM_FRAME_FLAG_LAMBDA    = 0x0100,
     VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM = 0x0200,
+    VM_FRAME_FLAG_CFRAME_KW = 0x0400,
 
     /* env flag */
     VM_ENV_FLAG_LOCAL       = 0x0002,
@@ -1249,6 +1250,12 @@ VM_FRAME_LAMBDA_P(const rb_control_frame_t *cfp) https://github.com/ruby/ruby/blob/trunk/vm_core.h#L1250
 }
 
 static inline int
+VM_FRAME_CFRAME_KW_P(const rb_control_frame_t *cfp)
+{
+    return VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_CFRAME_KW) != 0;
+}
+
+static inline int
 VM_FRAME_FINISHED_P(const rb_control_frame_t *cfp)
 {
     return VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_FINISH) != 0;
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 1c74b12..b1a13d0 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -2185,6 +2185,7 @@ vm_call_cfunc_with_frame(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2185
 
     VALUE recv = calling->recv;
     VALUE block_handler = calling->block_handler;
+    VALUE frame_type = VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL;
     int argc = calling->argc;
     int orig_argc = argc;
 
@@ -2193,11 +2194,14 @@ vm_call_cfunc_with_frame(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2194
             argc--;
         }
     }
+    if (UNLIKELY(IS_ARGS_KW_OR_KW_SPLAT(ci))) {
+        frame_type |= VM_FRAME_FLAG_CFRAME_KW;
+    }
 
     RUBY_DTRACE_CMETHOD_ENTRY_HOOK(ec, me->owner, me->def->original_id);
     EXEC_EVENT_HOOK(ec, RUBY_EVENT_C_CALL, recv, me->def->original_id, ci->mid, me->owner, Qundef);
 
-    vm_push_frame(ec, NULL, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL, recv,
+    vm_push_frame(ec, NULL, frame_type, recv,
 		  block_handler, (VALUE)me,
 		  0, ec->cfp->sp, 0, 0);
 
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 7709840..9f09d4a 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -241,6 +241,7 @@ THROW_DATA_CONSUMED_SET(struct vm_throw_data *obj) https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.h#L241
 #define IS_ARGS_SPLAT(ci)   ((ci)->flag & VM_CALL_ARGS_SPLAT)
 #define IS_ARGS_KEYWORD(ci) ((ci)->flag & VM_CALL_KWARG)
 #define IS_ARGS_KW_SPLAT(ci) ((ci)->flag & VM_CALL_KW_SPLAT)
+#define IS_ARGS_KW_OR_KW_SPLAT(ci) ((ci)->flag & (VM_CALL_KWARG | VM_CALL_KW_SPLAT))
 
 /* If this returns true, an optimized function returned by `vm_call_iseq_setup_func`
    can be used as a fastpath. */
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]