summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--proc.c2
-rw-r--r--vm_core.h1
-rw-r--r--vm_eval.c2
-rw-r--r--vm_insnhelper.c55
5 files changed, 40 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 0ecb01e03f..37b7593ce7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Wed Aug 03 09:15:02 2016 Koichi Sasada <ko1@atdot.net>
+
+ * vm_core.h: introduce VM_FRAME_FLAG_CFRAME to represent cfp->iseq
+ type.
+
Tue Aug 2 21:42:40 2016 Chia-sheng Chen <qitar888@gmail.com>
* math.c (tanh): make faster by the extract form if three
diff --git a/proc.c b/proc.c
index 15351eb2c5..f6f81c4882 100644
--- a/proc.c
+++ b/proc.c
@@ -611,7 +611,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc, int8_t is_lambda)
vm_block_type_set(&proc->block, block_type_ifunc);
*(VALUE **)&proc->block.as.captured.ep = ep = sproc->env + VM_ENV_DATA_SIZE-1;
- ep[VM_ENV_DATA_INDEX_FLAGS] = VM_FRAME_MAGIC_IFUNC | VM_ENV_FLAG_LOCAL | VM_ENV_FLAG_ESCAPED;
+ ep[VM_ENV_DATA_INDEX_FLAGS] = VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL | VM_ENV_FLAG_ESCAPED;
ep[VM_ENV_DATA_INDEX_ME_CREF] = Qfalse;
ep[VM_ENV_DATA_INDEX_SPECVAL] = VM_BLOCK_HANDLER_NONE;
ep[VM_ENV_DATA_INDEX_ENV] = Qundef; /* envval */
diff --git a/vm_core.h b/vm_core.h
index 7a6f3982ce..385c482698 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -978,6 +978,7 @@ enum {
VM_FRAME_FLAG_PASSED = 0x0010,
VM_FRAME_FLAG_FINISH = 0x0020,
VM_FRAME_FLAG_BMETHOD = 0x0040,
+ VM_FRAME_FLAG_CFRAME = 0x0080,
/* env flag */
VM_ENV_FLAG_LOCAL = 0x0002,
diff --git a/vm_eval.c b/vm_eval.c
index 264c0920a8..8233c5d4b9 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -121,7 +121,7 @@ vm_call0_cfunc_with_frame(rb_thread_t* th, struct rb_calling_info *calling, cons
{
rb_control_frame_t *reg_cfp = th->cfp;
- vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC | VM_ENV_FLAG_LOCAL, recv,
+ vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL, recv,
block_handler, (VALUE)me,
0, reg_cfp->sp, 0, 0);
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 1b4123412f..834bbdb2ff 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -70,7 +70,7 @@ callable_method_entry_p(const rb_callable_method_entry_t *me)
}
static void
-vm_check_frame_detail(VALUE type, int req_block, int req_me, int req_cref, VALUE specval, VALUE cref_or_me)
+vm_check_frame_detail(VALUE type, int req_block, int req_me, int req_cref, VALUE specval, VALUE cref_or_me, int is_cframe, const rb_iseq_t *iseq)
{
unsigned int magic = (unsigned int)(type & VM_FRAME_MAGIC_MASK);
enum imemo_type cref_or_me_type = imemo_env; /* impossible value */
@@ -117,37 +117,46 @@ vm_check_frame_detail(VALUE type, int req_block, int req_me, int req_cref, VALUE
rb_bug("vm_push_frame: ment (%s) should be callable on %x frame.", rb_obj_info(cref_or_me), magic);
}
}
+
+ if ((type & VM_FRAME_MAGIC_MASK) == VM_FRAME_MAGIC_DUMMY) {
+ VM_ASSERT(iseq == NULL ||
+ RUBY_VM_NORMAL_ISEQ_P(iseq) /* argument error. it shold be fixed */);
+ }
+ else {
+ VM_ASSERT(is_cframe == !RUBY_VM_NORMAL_ISEQ_P(iseq));
+ }
}
static void
vm_check_frame(VALUE type,
VALUE specval,
- VALUE cref_or_me)
+ VALUE cref_or_me,
+ const rb_iseq_t *iseq)
{
- int magic = (int)(type & VM_FRAME_MAGIC_MASK);
+ VALUE given_magic = type & VM_FRAME_MAGIC_MASK;
VM_ASSERT(FIXNUM_P(type));
-#define CHECK(magic, req_block, req_me, req_cref) case magic: vm_check_frame_detail(type, req_block, req_me, req_cref, specval, cref_or_me); break;
- switch (magic) {
- /* BLK ME CREF */
- CHECK(VM_FRAME_MAGIC_METHOD, TRUE, TRUE, FALSE);
- CHECK(VM_FRAME_MAGIC_CLASS, TRUE, FALSE, TRUE);
- CHECK(VM_FRAME_MAGIC_TOP, TRUE, FALSE, TRUE);
- CHECK(VM_FRAME_MAGIC_CFUNC, TRUE, TRUE, FALSE);
- CHECK(VM_FRAME_MAGIC_BLOCK, FALSE, FALSE, FALSE);
- CHECK(VM_FRAME_MAGIC_PROC, FALSE, FALSE, FALSE);
- CHECK(VM_FRAME_MAGIC_IFUNC, FALSE, FALSE, FALSE);
- CHECK(VM_FRAME_MAGIC_EVAL, FALSE, FALSE, FALSE);
- CHECK(VM_FRAME_MAGIC_LAMBDA, FALSE, FALSE, FALSE);
- CHECK(VM_FRAME_MAGIC_RESCUE, FALSE, FALSE, FALSE);
- CHECK(VM_FRAME_MAGIC_DUMMY, TRUE, FALSE, FALSE);
+#define CHECK(magic, req_block, req_me, req_cref, is_cframe) case magic: vm_check_frame_detail(type, req_block, req_me, req_cref, specval, cref_or_me, is_cframe, iseq); break;
+ switch (given_magic) {
+ /* BLK ME CREF CFRAME */
+ CHECK(VM_FRAME_MAGIC_METHOD, TRUE, TRUE, FALSE, FALSE);
+ CHECK(VM_FRAME_MAGIC_CLASS, TRUE, FALSE, TRUE, FALSE);
+ CHECK(VM_FRAME_MAGIC_TOP, TRUE, FALSE, TRUE, FALSE);
+ CHECK(VM_FRAME_MAGIC_CFUNC, TRUE, TRUE, FALSE, TRUE);
+ CHECK(VM_FRAME_MAGIC_BLOCK, FALSE, FALSE, FALSE, FALSE);
+ CHECK(VM_FRAME_MAGIC_PROC, FALSE, FALSE, FALSE, FALSE);
+ CHECK(VM_FRAME_MAGIC_IFUNC, FALSE, FALSE, FALSE, TRUE);
+ CHECK(VM_FRAME_MAGIC_EVAL, FALSE, FALSE, FALSE, FALSE);
+ CHECK(VM_FRAME_MAGIC_LAMBDA, FALSE, FALSE, FALSE, FALSE);
+ CHECK(VM_FRAME_MAGIC_RESCUE, FALSE, FALSE, FALSE, FALSE);
+ CHECK(VM_FRAME_MAGIC_DUMMY, TRUE, FALSE, FALSE, FALSE);
default:
- rb_bug("vm_push_frame: unknown type (%x)", magic);
+ rb_bug("vm_push_frame: unknown type (%x)", (unsigned int)given_magic);
}
#undef CHECK
}
#else
-#define vm_check_frame(a, b, c)
+#define vm_check_frame(a, b, c, d)
#endif /* VM_CHECK_MODE > 0 */
static inline rb_control_frame_t *
@@ -165,7 +174,7 @@ vm_push_frame(rb_thread_t *th,
rb_control_frame_t *const cfp = th->cfp - 1;
int i;
- vm_check_frame(type, specval, cref_or_me);
+ vm_check_frame(type, specval, cref_or_me, iseq);
VM_ASSERT(local_size >= 0);
/* check stack overflow */
@@ -1718,7 +1727,7 @@ vm_call_cfunc_with_frame(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb
RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, me->owner, me->called_id);
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->owner, Qundef);
- vm_push_frame(th, NULL, VM_FRAME_MAGIC_CFUNC | VM_ENV_FLAG_LOCAL, recv,
+ vm_push_frame(th, NULL, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL, recv,
block_handler, (VALUE)me,
0, th->cfp->sp, 0, 0);
@@ -1808,7 +1817,7 @@ rb_vm_call_cfunc_push_frame(rb_thread_t *th)
const rb_callable_method_entry_t *me = calling->me;
th->passed_ci = 0;
- vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC | VM_ENV_FLAG_LOCAL,
+ vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC | VM_FRAME_FLAG_CFRAME | VM_ENV_FLAG_LOCAL,
calling->recv, calling->block_handler, (VALUE)me /* cref */,
0, th->cfp->sp + cc->aux.inc_sp, 0, 0);
@@ -2425,7 +2434,7 @@ vm_yield_with_cfunc(rb_thread_t *th,
blockarg = vm_block_handler_to_proc(th, block_handler);
vm_push_frame(th, (const rb_iseq_t *)captured->code.ifunc,
- VM_FRAME_MAGIC_IFUNC,
+ VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME,
self,
VM_GUARDED_PREV_EP(captured->ep),
(VALUE)me,