You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
187 lines
7.3 KiB
187 lines
7.3 KiB
From 104b009e26c050584e4d186c8cc4e1496a14061b Mon Sep 17 00:00:00 2001
|
|
From: Nobuyoshi Nakada <nobu@ruby-lang.org>
|
|
Date: Thu, 5 Aug 2021 20:09:25 +0900
|
|
Subject: [PATCH] Get rid of type-punning pointer casts [Bug #18062]
|
|
|
|
---
|
|
vm_eval.c | 4 +++-
|
|
vm_insnhelper.c | 7 +++++--
|
|
vm_method.c | 41 ++++++++++++++++++++++++++---------------
|
|
3 files changed, 34 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/vm_eval.c b/vm_eval.c
|
|
index 6d4b5c3c0b28..7ce9f157e671 100644
|
|
--- a/vm_eval.c
|
|
+++ b/vm_eval.c
|
|
@@ -350,9 +350,11 @@ cc_new(VALUE klass, ID mid, int argc, const rb_callable_method_entry_t *cme)
|
|
{
|
|
struct rb_class_cc_entries *ccs;
|
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
|
+ VALUE ccs_data;
|
|
|
|
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs)) {
|
|
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
|
// ok
|
|
+ ccs = (struct rb_class_cc_entries *)ccs_data;
|
|
}
|
|
else {
|
|
ccs = vm_ccs_create(klass, cme);
|
|
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
|
|
index 14928b2afe8e..e186376b24d7 100644
|
|
--- a/vm_insnhelper.c
|
|
+++ b/vm_insnhelper.c
|
|
@@ -1637,9 +1637,11 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
|
|
const ID mid = vm_ci_mid(ci);
|
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
|
struct rb_class_cc_entries *ccs = NULL;
|
|
+ VALUE ccs_data;
|
|
|
|
if (cc_tbl) {
|
|
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
|
|
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
|
+ ccs = (struct rb_class_cc_entries *)ccs_data;
|
|
const int ccs_len = ccs->len;
|
|
VM_ASSERT(vm_ccs_verify(ccs, mid, klass));
|
|
|
|
@@ -1706,8 +1708,9 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
|
|
if (ccs == NULL) {
|
|
VM_ASSERT(cc_tbl != NULL);
|
|
|
|
- if (LIKELY(rb_id_table_lookup(cc_tbl, mid, (VALUE*)&ccs))) {
|
|
+ if (LIKELY(rb_id_table_lookup(cc_tbl, mid, &ccs_data))) {
|
|
// rb_callable_method_entry() prepares ccs.
|
|
+ ccs = (struct rb_class_cc_entries *)ccs_data;
|
|
}
|
|
else {
|
|
// TODO: required?
|
|
diff --git a/vm_method.c b/vm_method.c
|
|
index 016dba1dbb18..1fd0bd57f7ca 100644
|
|
--- a/vm_method.c
|
|
+++ b/vm_method.c
|
|
@@ -42,11 +42,11 @@ vm_ccs_dump(VALUE klass, ID target_mid)
|
|
{
|
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
|
if (cc_tbl) {
|
|
- const struct rb_class_cc_entries *ccs;
|
|
+ VALUE ccs;
|
|
if (target_mid) {
|
|
- if (rb_id_table_lookup(cc_tbl, target_mid, (VALUE *)&ccs)) {
|
|
+ if (rb_id_table_lookup(cc_tbl, target_mid, &ccs)) {
|
|
fprintf(stderr, " [CCTB] %p\n", (void *)cc_tbl);
|
|
- vm_ccs_dump_i(target_mid, (VALUE)ccs, NULL);
|
|
+ vm_ccs_dump_i(target_mid, ccs, NULL);
|
|
}
|
|
}
|
|
else {
|
|
@@ -72,11 +72,11 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
|
|
fprintf(stderr, "# vm_mtbl\n");
|
|
while (klass) {
|
|
rp_m(" -> ", klass);
|
|
- rb_method_entry_t *me;
|
|
+ VALUE me;
|
|
|
|
if (RCLASS_M_TBL(klass)) {
|
|
if (target_mid != 0) {
|
|
- if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, (VALUE *)&me)) {
|
|
+ if (rb_id_table_lookup(RCLASS_M_TBL(klass), target_mid, &me)) {
|
|
rp_m(" [MTBL] ", me);
|
|
}
|
|
}
|
|
@@ -90,7 +90,7 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
|
|
}
|
|
if (RCLASS_CALLABLE_M_TBL(klass)) {
|
|
if (target_mid != 0) {
|
|
- if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, (VALUE *)&me)) {
|
|
+ if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) {
|
|
rp_m(" [CM**] ", me);
|
|
}
|
|
}
|
|
@@ -144,10 +144,11 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
|
// check only current class
|
|
|
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
|
- struct rb_class_cc_entries *ccs;
|
|
+ VALUE ccs_data;
|
|
|
|
// invalidate CCs
|
|
- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
|
|
+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
|
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
|
|
rb_vm_ccs_free(ccs);
|
|
rb_id_table_delete(cc_tbl, mid);
|
|
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs);
|
|
@@ -205,9 +206,10 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
|
}
|
|
else {
|
|
rb_vm_t *vm = GET_VM();
|
|
- if (rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) {
|
|
+ VALUE cme_data = (VALUE) cme;
|
|
+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) {
|
|
rb_id_table_delete(vm->negative_cme_table, mid);
|
|
- vm_me_invalidate_cache((rb_callable_method_entry_t *)cme);
|
|
+ vm_me_invalidate_cache((rb_callable_method_entry_t *)cme_data);
|
|
|
|
RB_DEBUG_COUNTER_INC(cc_invalidate_negative);
|
|
}
|
|
@@ -1030,6 +1032,7 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
|
|
{
|
|
struct rb_id_table *mtbl;
|
|
const rb_callable_method_entry_t *cme;
|
|
+ VALUE cme_data;
|
|
|
|
if (me) {
|
|
if (me->defined_class == 0) {
|
|
@@ -1039,7 +1042,8 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
|
|
|
|
mtbl = RCLASS_CALLABLE_M_TBL(defined_class);
|
|
|
|
- if (mtbl && rb_id_table_lookup(mtbl, id, (VALUE *)&cme)) {
|
|
+ if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) {
|
|
+ cme = (rb_callable_method_entry_t *)cme_data;
|
|
RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
|
|
VM_ASSERT(callable_method_entry_p(cme));
|
|
VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme));
|
|
@@ -1083,9 +1087,10 @@ cached_callable_method_entry(VALUE klass, ID mid)
|
|
ASSERT_vm_locking();
|
|
|
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
|
- struct rb_class_cc_entries *ccs;
|
|
+ VALUE ccs_data;
|
|
|
|
- if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
|
|
+ if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
|
+ struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
|
|
VM_ASSERT(vm_ccs_p(ccs));
|
|
|
|
if (LIKELY(!METHOD_ENTRY_INVALIDATED(ccs->cme))) {
|
|
@@ -1111,12 +1116,14 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_
|
|
|
|
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
|
struct rb_class_cc_entries *ccs;
|
|
+ VALUE ccs_data;
|
|
|
|
if (!cc_tbl) {
|
|
cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2);
|
|
}
|
|
|
|
- if (rb_id_table_lookup(cc_tbl, mid, (VALUE *)&ccs)) {
|
|
+ if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
|
+ ccs = (struct rb_class_cc_entries *)ccs_data;
|
|
VM_ASSERT(ccs->cme == cme);
|
|
}
|
|
else {
|
|
@@ -1130,8 +1137,12 @@ negative_cme(ID mid)
|
|
{
|
|
rb_vm_t *vm = GET_VM();
|
|
const rb_callable_method_entry_t *cme;
|
|
+ VALUE cme_data;
|
|
|
|
- if (!rb_id_table_lookup(vm->negative_cme_table, mid, (VALUE *)&cme)) {
|
|
+ if (rb_id_table_lookup(vm->negative_cme_table, mid, &cme_data)) {
|
|
+ cme = (rb_callable_method_entry_t *)cme_data;
|
|
+ }
|
|
+ else {
|
|
cme = (rb_callable_method_entry_t *)rb_method_entry_alloc(mid, Qnil, Qnil, NULL);
|
|
rb_id_table_insert(vm->negative_cme_table, mid, (VALUE)cme);
|
|
}
|