summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/array.c9
-rw-r--r--src/dump.c24
-rw-r--r--src/hash.c95
-rw-r--r--src/print.c15
-rw-r--r--src/vm.c2
5 files changed, 98 insertions, 47 deletions
diff --git a/src/array.c b/src/array.c
index a66ff8183..8ab30bd8e 100644
--- a/src/array.c
+++ b/src/array.c
@@ -56,18 +56,17 @@ mrb_ary_new(mrb_state *mrb)
}
/*
- * to copy array, use this instead of memcpy because of portability
+ * To copy array, use this instead of memcpy because of portability
* * gcc on ARM may fail optimization of memcpy
- * http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka3934.html
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56620
* * gcc on MIPS also fail
- * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39755
* * memcpy doesn't exist on freestanding environment
*
* If you optimize for binary size, use memcpy instead of this at your own risk
* of above portability issue.
*
- * see also http://togetter.com/li/462898
- *
+ * See also https://togetter.com/li/462898 (Japanese)
*/
static inline void
array_copy(mrb_value *dst, const mrb_value *src, mrb_int size)
diff --git a/src/dump.c b/src/dump.c
index 5173b88e5..e3f3320ea 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -806,7 +806,7 @@ dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, si
section_irep_size += get_irep_record_size(mrb, irep);
/* DEBUG section size */
- if (flags & DUMP_DEBUG_INFO) {
+ if (flags & MRB_DUMP_DEBUG_INFO) {
if (debug_info_defined) {
section_lineno_size += sizeof(struct rite_section_debug_header);
/* filename table */
@@ -842,7 +842,7 @@ dump_irep(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, uint8_t **bin, si
sizeof(struct rite_binary_footer);
/* write DEBUG section */
- if (flags & DUMP_DEBUG_INFO) {
+ if (flags & MRB_DUMP_DEBUG_INFO) {
if (debug_info_defined) {
result = write_section_debug(mrb, irep, cur, filenames, filenames_len);
if (result != MRB_DUMP_OK) {
@@ -920,11 +920,13 @@ mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *f
return MRB_DUMP_WRITE_FAULT;
}
if (fprintf(fp,
- "#ifdef __cplusplus\n"
- "extern const uint8_t %s[];\n"
- "#endif\n"
+ "%s\n"
"const uint8_t %s[] = {",
- initname, initname) < 0) {
+ (flags & MRB_DUMP_STATIC) ? "static"
+ : "#ifdef __cplusplus\n"
+ "extern\n"
+ "#endif",
+ initname) < 0) {
mrb_free(mrb, bin);
return MRB_DUMP_WRITE_FAULT;
}
@@ -1232,8 +1234,14 @@ mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE
int max = 1;
int n = dump_irep_struct(mrb, irep, flags, fp, initname, 0, init_syms_code, &max);
if (n != MRB_DUMP_OK) return n;
- fprintf(fp, "#ifdef __cplusplus\nextern const struct RProc %s[];\n#endif\n", initname);
- fprintf(fp, "const struct RProc %s[] = {{\n", initname);
+ fprintf(fp,
+ "%s\n"
+ "const struct RProc %s[] = {{\n",
+ (flags & MRB_DUMP_STATIC) ? "static"
+ : "#ifdef __cplusplus\n"
+ "extern\n"
+ "#endif",
+ initname);
fprintf(fp, "NULL,NULL,MRB_TT_PROC,7,0,{&%s_irep_0},NULL,{NULL},\n}};\n", initname);
fputs("static void\n", fp);
fprintf(fp, "%s_init_syms(mrb_state *mrb)\n", initname);
diff --git a/src/hash.c b/src/hash.c
index 289f02a91..c5b4c5cbe 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -215,40 +215,70 @@ DEFINE_SWITCHER(ht, HT)
} while (0)
/*
- * `h_check_modified` raises an exception when a dangerous modification is
- * made to `h` by executing `code`.
- *
- * This macro is not called if `h->ht` (`h->ea`) is `NULL` (`Hash` size is
- * zero). And because the `hash_entry` is rather large, `h->ht->ea` and
- * `h->ht->ea_capa` are able to be safely accessed even in AR. This nature
- * is used to eliminate branch of AR or HT.
- *
- * `HT_ASSERT_SAFE_READ` checks if members can be accessed according to its
- * assumptions.
+ * In `h_check_modified()`, in the case of `MRB_NO_BOXING`, `ht_ea()` or
+ * `ht_ea_capa()` for AR may read uninitialized area (#5332). Therefore, do
+ * not use those macros for AR in `MRB_NO_BOXING` (but in the case of
+ * `MRB_64BIT`, `ht_ea_capa()` is the same as `ar_ea_capa()`, so use it).
*/
-#define HT_ASSERT_SAFE_READ(attr_name) \
+#ifdef MRB_NO_BOXING
+# define H_CHECK_MODIFIED_USE_HT_EA_FOR_AR FALSE
+# ifdef MRB_64BIT
+# define H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR TRUE
+# else
+# define H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR FALSE
+# endif /* MRB_64BIT */
+#else
+# define H_CHECK_MODIFIED_USE_HT_EA_FOR_AR TRUE
+# define H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR TRUE
+ /*
+ * `h_check_modified` raises an exception when a dangerous modification is
+ * made to `h` by executing `code`.
+ *
+ * `h_check_modified` macro is not called if `h->ht` (`h->ea`) is `NULL`
+ * (`Hash` size is zero). And because the `hash_entry` is rather large,
+ * `h->ht->ea` and `h->ht->ea_capa` are able to be safely accessed even for
+ * AR. This nature is used to eliminate branch of AR or HT.
+ *
+ * `HT_ASSERT_SAFE_READ` checks if members can be accessed according to its
+ * assumptions.
+ */
+# define HT_ASSERT_SAFE_READ(attr_name) \
mrb_static_assert1( \
offsetof(hash_table, attr_name) + sizeof(((hash_table*)0)->attr_name) <= \
sizeof(hash_entry))
HT_ASSERT_SAFE_READ(ea);
-#ifdef MRB_32BIT
+# ifdef MRB_32BIT
HT_ASSERT_SAFE_READ(ea_capa);
-#endif
-#undef HT_ASSERT_SAFE_READ
-#define h_check_modified(mrb, h, code) do { \
- struct RHash *h__ = h; \
- uint32_t mask = MRB_HASH_HT|MRB_HASH_IB_BIT_MASK|MRB_HASH_AR_EA_CAPA_MASK; \
- uint32_t flags = h__->flags & mask; \
- void* tbl__ = (mrb_assert(h__->ht), h__->ht); \
- uint32_t ht_ea_capa__ = ht_ea_capa(h__); \
- hash_entry *ht_ea__ = ht_ea(h__); \
- code; \
- if (flags != (h__->flags & mask) || \
- tbl__ != h__->ht || \
- ht_ea_capa__ != ht_ea_capa(h__) || \
- ht_ea__ != ht_ea(h__)) { \
- mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified"); \
- } \
+# endif
+# undef HT_ASSERT_SAFE_READ
+#endif /* MRB_NO_BOXING */
+
+/*
+ * `h_check_modified` raises an exception when a dangerous modification is
+ * made to `h` by executing `code`.
+ */
+#define h_check_modified(mrb, h, code) do { \
+ struct RHash *h__ = h; \
+ uint32_t mask__ = MRB_HASH_HT|MRB_HASH_IB_BIT_MASK|MRB_HASH_AR_EA_CAPA_MASK; \
+ uint32_t flags__ = h__->flags & mask__; \
+ void* tbl__ = (mrb_assert(h__->ht), h__->ht); \
+ uint32_t ht_ea_capa__ = 0; \
+ hash_entry *ht_ea__ = NULL; \
+ if (H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR || h_ht_p(h__)) { \
+ ht_ea_capa__ = ht_ea_capa(h__); \
+ } \
+ if (H_CHECK_MODIFIED_USE_HT_EA_FOR_AR || h_ht_p(h__)) { \
+ ht_ea__ = ht_ea(h__); \
+ } \
+ code; \
+ if (flags__ != (h__->flags & mask__) || \
+ tbl__ != h__->ht || \
+ ((H_CHECK_MODIFIED_USE_HT_EA_CAPA_FOR_AR || h_ht_p(h__)) && \
+ ht_ea_capa__ != ht_ea_capa(h__)) || \
+ ((H_CHECK_MODIFIED_USE_HT_EA_FOR_AR || h_ht_p(h__)) && \
+ ht_ea__ != ht_ea(h__))) { \
+ mrb_raise(mrb, E_RUNTIME_ERROR, "hash modified"); \
+ } \
} while (0)
#define U32(v) ((uint32_t)(v))
@@ -718,6 +748,7 @@ ib_bit_for(uint32_t size)
static uint32_t
ib_byte_size_for(uint32_t ib_bit)
{
+ mrb_assert(IB_INIT_BIT <= ib_bit);
uint32_t ary_size = IB_INIT_BIT == 4 ?
ib_bit_to_capa(ib_bit) * 2 / IB_TYPE_BIT * ib_bit / 2 :
ib_bit_to_capa(ib_bit) / IB_TYPE_BIT * ib_bit;
@@ -892,7 +923,13 @@ static void
ht_rehash(mrb_state *mrb, struct RHash *h)
{
/* see comments in `h_rehash` */
- uint32_t size = ht_size(h), w_size = 0, ea_capa = ht_ea_capa(h);
+ uint32_t size = ht_size(h);
+ if (size <= AR_MAX_SIZE) {
+ ht_to_ar(mrb, h);
+ ar_rehash(mrb, h);
+ return;
+ }
+ uint32_t w_size = 0, ea_capa = ht_ea_capa(h);
hash_entry *ea = ht_ea(h);
ht_init(mrb, h, 0, ea, ea_capa, h_ht(h), ib_bit_for(size));
ht_set_size(h, size);
diff --git a/src/print.c b/src/print.c
index 607eb9d1f..c96189fe9 100644
--- a/src/print.c
+++ b/src/print.c
@@ -28,10 +28,6 @@ printstr(mrb_value obj, FILE *stream)
printcstr(RSTRING_PTR(obj), RSTRING_LEN(obj), stream);
}
}
-#else
-# define printcstr(str, len, stream) (void)0
-# define printstr(obj, stream) (void)0
-#endif
void
mrb_core_init_printabort(void)
@@ -51,6 +47,17 @@ mrb_p(mrb_state *mrb, mrb_value obj)
printstr(mrb_inspect(mrb, obj), stdout);
}
}
+#else
+void
+mrb_core_init_printabort(void)
+{
+}
+
+MRB_API void
+mrb_p(mrb_state *mrb, mrb_value obj)
+{
+}
+#endif
MRB_API void
mrb_print_error(mrb_state *mrb)
diff --git a/src/vm.c b/src/vm.c
index 390ce8aaa..0e7eb65e5 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -1022,7 +1022,7 @@ mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc)
const struct mrb_irep_catch_handler *ch;
#ifdef DIRECT_THREADED
- static void *optable[] = {
+ static const void * const optable[] = {
#define OPCODE(x,_) &&L_OP_ ## x,
#include "mruby/ops.h"
#undef OPCODE