Skip to content

Instantly share code, notes, and snippets.

Created November 26, 2013 04:08
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/7653326 to your computer and use it in GitHub Desktop.
Save anonymous/7653326 to your computer and use it in GitHub Desktop.
diff --git a/compile.c b/compile.c
index 9ff3bf5..306fd80 100644
--- a/compile.c
+++ b/compile.c
@@ -172,10 +172,10 @@ r_value(VALUE value)
(((rb_iseq_t*)DATA_PTR(iseq))->filepath)
#define NEW_ISEQVAL(node, name, type, line_no) \
- new_child_iseq(iseq, (node), (name), 0, (type), (line_no))
+ new_child_iseq(iseq, (node), rb_str_frozen_literal(name), 0, (type), (line_no))
#define NEW_CHILD_ISEQVAL(node, name, type, line_no) \
- new_child_iseq(iseq, (node), (name), iseq->self, (type), (line_no))
+ new_child_iseq(iseq, (node), rb_str_frozen_literal(name), iseq->self, (type), (line_no))
/* add instructions */
#define ADD_SEQ(seq1, seq2) \
@@ -2201,13 +2201,20 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int *cntp
debugp_param("nd_lit", lit);
if (!NIL_P(lit)) {
- hide_obj(lit);
+ lit = rb_str_frozen_literal(lit);
+ /* hide_obj(lit);*/
cnt++;
ADD_INSN1(ret, nd_line(node), putobject, lit);
}
+ /* rb_io_write(rb_stdout, rb_parser_dump_tree(node, 1));*/
+
while (list) {
COMPILE(ret, "each string", list->nd_head);
+ /* if (nd_type(list) == NODE_STR)*/
+ /* fprintf(stderr, "WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: %d\n", nd_type(list));*/
+ if (nd_type(list->nd_head) == NODE_STR)
+ list->nd_head->nd_lit = rb_str_frozen_literal(list->nd_head->nd_lit);
cnt++;
list = list->nd_next;
}
@@ -2300,6 +2307,10 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
opt_p = Qfalse;
}
COMPILE_(anchor, "array element", node->nd_head, poped);
+ //if (nd_type(node->nd_head) == NODE_STR) {
+ // /* fprintf(stderr, "yeaaaaaabudddddddddddddddyy: %s\n", RSTRING_PTR(node->nd_head->nd_lit));*/
+ // node->nd_head->nd_lit = rb_str_frozen_literal(node->nd_head->nd_lit);
+ //}
node = node->nd_next;
}
}
@@ -2357,7 +2368,7 @@ case_when_optimizable_literal(NODE * node)
break;
}
case NODE_STR:
- return node->nd_lit;
+ return rb_str_frozen_literal(node->nd_lit);
}
return Qfalse;
}
@@ -2382,7 +2393,8 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, VALUE s
if (nd_type(val) == NODE_STR) {
debugp_param("nd_lit", val->nd_lit);
- OBJ_FREEZE(val->nd_lit);
+ /* OBJ_FREEZE(val->nd_lit);*/
+ val->nd_lit = rb_str_frozen_literal(val->nd_lit);
ADD_INSN1(cond_seq, nd_line(val), putobject, val->nd_lit);
}
else {
@@ -3736,7 +3748,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_DASGN_CURR:{
int idx, lv, ls;
COMPILE(ret, "dvalue", node->nd_value);
- debugp_param("dassn id", rb_str_new2(rb_id2name(node->nd_vid) ? rb_id2name(node->nd_vid) : "*"));
+ debugp_param("dassn id", rb_str_frozen_literal(rb_str_new2(rb_id2name(node->nd_vid) ? rb_id2name(node->nd_vid) : "*")));
if (!poped) {
ADD_INSN(ret, nd_line(node), dup);
@@ -4299,6 +4311,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
INIT_ANCHOR(list);
switch (type) {
case NODE_ARRAY:{
+ /* rb_io_write(rb_stdout, rb_parser_dump_tree(node->nd_head, 1));*/
compile_array(iseq, list, node->nd_head, Qfalse);
size = OPERAND_AT(POP_ELEMENT(list), 0);
ADD_SEQ(ret, list);
@@ -4472,7 +4485,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
INIT_ANCHOR(recv);
INIT_ANCHOR(val);
switch(nd_type(node)) {
- case NODE_MATCH:
+ case NODE_MATCH: /* nd_lit is string here? */
+ rb_io_write(rb_stdout, rb_parser_dump_tree(node, 1));
ADD_INSN1(recv, nd_line(node), putobject, node->nd_lit);
ADD_INSN2(val, nd_line(node), getspecial, INT2FIX(0),
INT2FIX(0));
@@ -4516,6 +4530,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_LIT:{
debugp_param("lit", node->nd_lit);
if (!poped) {
+ /* if (RB_TYPE_P(node->nd_lit, T_STRING))*/
+ /* node->nd_lit = rb_str_frozen_literal(node->nd_lit);*/
ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
}
break;
@@ -4523,8 +4539,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_STR:{
debugp_param("nd_lit", node->nd_lit);
if (!poped) {
- OBJ_FREEZE(node->nd_lit);
- ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit);
+ /* OBJ_FREEZE(node->nd_lit);*/
+ /* VALUE lit = rb_str_frozen_literal(node->nd_lit);*/
+ node->nd_lit = rb_str_frozen_literal(node->nd_lit);
+ VALUE lit = node->nd_lit;
+ ADD_INSN1(ret, nd_line(node), putstring, lit);
}
break;
}
@@ -4537,7 +4556,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_XSTR:{
- OBJ_FREEZE(node->nd_lit);
+ /* OBJ_FREEZE(node->nd_lit);*/
+ node->nd_lit = rb_str_frozen_literal(node->nd_lit);
ADD_CALL_RECEIVER(ret, nd_line(node));
ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
@@ -4636,7 +4656,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_DEFN:{
VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
- rb_str_dup(rb_id2str(node->nd_mid)),
+ rb_id2str(node->nd_mid),
ISEQ_TYPE_METHOD, nd_line(node));
debugp_param("defn/iseq", iseqval);
@@ -4656,7 +4676,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
case NODE_DEFS:{
VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
- rb_str_dup(rb_id2str(node->nd_mid)),
+ rb_id2str(node->nd_mid),
ISEQ_TYPE_METHOD, nd_line(node));
debugp_param("defs/iseq", iseqval);
@@ -4846,6 +4866,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
RSTRING_PTR(iseq->name), (void *)iseq,
iseq->compile_data->flip_cnt++);
+ key = rb_str_frozen_literal(key);
hide_obj(key);
iseq_add_mark_object_compile_time(iseq, key);
ADD_INSN2(ret, nd_line(node), getspecial, key, INT2FIX(0));
@@ -4901,6 +4922,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
}
break;
}
+ case NODE_FILE:{
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), putobject, iseq->filename);
+ }
+ break;
+ }
case NODE_ERRINFO:{
if (!poped) {
if (iseq->type == ISEQ_TYPE_RESCUE) {
@@ -5206,7 +5233,7 @@ rb_insns_name_array(void)
VALUE ary = rb_ary_new();
int i;
for (i = 0; i < numberof(insn_name_info); i++) {
- rb_ary_push(ary, rb_obj_freeze(rb_str_new2(insn_name_info[i])));
+ rb_ary_push(ary, rb_str_frozen_literal(rb_str_new2(insn_name_info[i])));
}
return rb_obj_freeze(ary);
}
diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c
index 66e33a3..fd08158 100644
--- a/ext/objspace/objspace.c
+++ b/ext/objspace/objspace.c
@@ -531,7 +531,7 @@ count_nodes(int argc, VALUE *argv, VALUE os)
COUNT_NODE(NODE_LAMBDA);
COUNT_NODE(NODE_OPTBLOCK);
#undef COUNT_NODE
- default: node = INT2FIX(nodes[i]);
+ default: node = INT2FIX(i);
}
rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
}
diff --git a/gc.c b/gc.c
index dfe4c06..7dffefa 100644
--- a/gc.c
+++ b/gc.c
@@ -310,6 +310,7 @@ typedef struct RVALUE {
struct RRational rational;
struct RComplex complex;
} as;
+ unsigned int mark_count;
} RVALUE;
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
@@ -1854,6 +1855,7 @@ gc_mark_ptr(rb_objspace_t *objspace, VALUE ptr)
register uintptr_t *bits = GET_HEAP_BITMAP(ptr);
if (MARKED_IN_BITMAP(bits, ptr)) return 0;
MARK_IN_BITMAP(bits, ptr);
+ RANY(ptr)->mark_count++;
objspace->heap.marked_num++;
return 1;
}
@@ -1907,6 +1909,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
bits = GET_HEAP_BITMAP(ptr);
if (MARKED_IN_BITMAP(bits, ptr)) return; /* already marked */
MARK_IN_BITMAP(bits, ptr);
+ RANY(ptr)->mark_count++;
objspace->heap.marked_num++;
marking:
@@ -2177,6 +2180,8 @@ add_slot_local_freelist(rb_objspace_t *objspace, RVALUE *p)
{
struct heaps_slot *slot;
+ if (FL_TEST(p, FL_RESERVED))
+ fprintf(stderr, "FORCED BAD NEWWWWWWWWWS\n");
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
p->as.free.flags = 0;
slot = GET_HEAP_SLOT(p);
@@ -2286,6 +2291,8 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
final_num++;
}
else {
+ if (FL_TEST(p, FL_RESERVED))
+ fprintf(stderr, "BAD NEWWWWWWWWWS\n");
VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE));
p->as.free.flags = 0;
p->as.free.next = sweep_slot->freelist;
@@ -2730,6 +2737,7 @@ gc_marks(rb_objspace_t *objspace)
rb_gc_mark_symbols();
rb_gc_mark_encodings();
+ rb_str_frozen_literal_mark();
/* mark protected global variables */
for (list = global_List; list; list = list->next) {
@@ -3725,6 +3733,12 @@ rb_obj_sourceline(VALUE obj)
return meta ? INT2FIX(meta->line) : Qnil;
}
+static VALUE
+rb_obj_markcount(VALUE obj)
+{
+ return UINT2NUM(RANY(obj)->mark_count);
+}
+
/*
* call-seq:
* GC.count -> Integer
@@ -4092,6 +4106,7 @@ Init_GC(void)
rb_define_method(rb_cBasicObject, "__sourcefile__", rb_obj_sourcefile, 0);
rb_define_method(rb_cBasicObject, "__sourceline__", rb_obj_sourceline, 0);
+ rb_define_method(rb_cBasicObject, "__markcount__", rb_obj_markcount, 0);
rb_define_module_function(rb_mObSpace, "count_objects", count_objects, -1);
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index a4eef71..0f0e5e6 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -686,6 +686,7 @@ VALUE rb_str_locktmp(VALUE);
VALUE rb_str_unlocktmp(VALUE);
VALUE rb_str_dup_frozen(VALUE);
#define rb_str_dup_frozen rb_str_new_frozen
+VALUE rb_str_frozen_literal(VALUE);
VALUE rb_str_plus(VALUE, VALUE);
VALUE rb_str_times(VALUE, VALUE);
long rb_str_sublen(VALUE, long);
diff --git a/internal.h b/internal.h
index a819cc1..448750f 100644
--- a/internal.h
+++ b/internal.h
@@ -163,6 +163,7 @@ size_t rb_strftime_timespec(char *s, size_t maxsize, const char *format, const s
/* string.c */
int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
+void rb_str_frozen_literal_mark(void);
/* struct.c */
VALUE rb_struct_init_copy(VALUE copy, VALUE s);
diff --git a/iseq.c b/iseq.c
index ffbc759..7bb6165 100644
--- a/iseq.c
+++ b/iseq.c
@@ -228,6 +228,8 @@ rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj)
OBJ_UNTRUST(iseq->mark_ary);
RBASIC(iseq->mark_ary)->klass = 0;
}
+ /* if (RB_TYPE_P(obj, T_STRING) && OBJ_FROZEN(obj))*/
+ /* obj = rb_str_frozen_literal(obj);*/
rb_ary_push(iseq->mark_ary, obj);
}
@@ -237,8 +239,12 @@ prepare_iseq_build(rb_iseq_t *iseq,
VALUE parent, enum iseq_type type, VALUE block_opt,
const rb_compile_option_t *option)
{
- OBJ_FREEZE(name);
- OBJ_FREEZE(filename);
+ /* OBJ_FREEZE(name);*/
+ name = rb_str_frozen_literal(name);
+ /* OBJ_FREEZE(filename);*/
+ filename = rb_str_frozen_literal(filename);
+ if (RTEST(filepath) && !rb_str_cmp(filename, filepath))
+ filepath = filename;
iseq->name = name;
iseq->filename = filename;
diff --git a/node.h b/node.h
index bb96107..bababf0 100644
--- a/node.h
+++ b/node.h
@@ -228,6 +228,8 @@ enum node_type {
#define NODE_LAMBDA NODE_LAMBDA
NODE_OPTBLOCK,
#define NODE_OPTBLOCK NODE_OPTBLOCK
+ NODE_FILE,
+#define NODE_FILE NODE_FILE
NODE_LAST
#define NODE_LAST NODE_LAST
};
@@ -447,6 +449,7 @@ typedef struct RNode {
#define NEW_ATTRASGN(r,m,a) NEW_NODE(NODE_ATTRASGN,r,m,a)
#define NEW_PRELUDE(p,b) NEW_NODE(NODE_PRELUDE,p,b,0)
#define NEW_OPTBLOCK(a) NEW_NODE(NODE_OPTBLOCK,a,0,0)
+#define NEW_FILE() NEW_NODE(NODE_FILE,0,0,0)
#if defined __GNUC__ && __GNUC__ >= 4
#pragma GCC visibility push(default)
diff --git a/parse.y b/parse.y
index d36156f..9f57d38 100644
--- a/parse.y
+++ b/parse.y
@@ -3918,6 +3918,7 @@ regexp : tREGEXP_BEG regexp_contents tREGEXP_END
case NODE_STR:
{
VALUE src = node->nd_lit;
+ /* src = rb_str_frozen_literal(src);*/
nd_set_type(node, NODE_LIT);
node->nd_lit = reg_compile(src, options);
}
@@ -5830,9 +5831,7 @@ parser_regx_options(struct parser_params *parser)
static void
dispose_string(VALUE str)
{
- /* TODO: should use another API? */
- if (RBASIC(str)->flags & RSTRING_NOEMBED)
- xfree(RSTRING_PTR(str));
+ rb_str_free(str);
rb_gc_force_recycle(str);
}
@@ -8266,6 +8265,7 @@ gettable_gen(struct parser_params *parser, ID id)
return NEW_FALSE();
}
else if (id == keyword__FILE__) {
+ return NEW_FILE();
return NEW_STR(rb_external_str_new_with_enc(ruby_sourcefile, strlen(ruby_sourcefile),
rb_filesystem_encoding()));
}
@@ -8791,6 +8791,10 @@ reduce_nodes_gen(struct parser_params *parser, NODE **body)
}
if (!subnodes(nd_head, nd_resq)) goto end;
break;
+ case NODE_STR:
+ /* fprintf(stderr, "AHEYSKJFI##################: %s\n", RSTRING_PTR(node->nd_lit));*/
+ /* node->nd_lit = rb_str_frozen_literal(node->nd_lit);*/
+ return;
default:
return;
}
@@ -9450,6 +9454,8 @@ reg_compile_gen(struct parser_params* parser, VALUE str, int options)
VALUE err;
reg_fragment_setenc(str, options);
+ if (RSTRING_LEN(str) == 1)
+ str = rb_str_frozen_literal(str);
err = rb_errinfo();
re = rb_reg_compile(str, options & RE_OPTION_MASK, ruby_sourcefile, ruby_sourceline);
if (NIL_P(re)) {
@@ -9781,6 +9787,7 @@ static ID
register_symid(ID id, const char *name, long len, rb_encoding *enc)
{
VALUE str = rb_enc_str_new(name, len, enc);
+ /* str = rb_str_frozen_literal(str);*/
OBJ_FREEZE(str);
st_add_direct(global_symbols.sym_id, (st_data_t)str, id);
st_add_direct(global_symbols.id_str, id, (st_data_t)str);
diff --git a/string.c b/string.c
index eaa8579..8d0a23e 100644
--- a/string.c
+++ b/string.c
@@ -56,6 +56,7 @@ VALUE rb_cSymbol;
#define STR_NOEMBED FL_USER1
#define STR_SHARED FL_USER2 /* = ELTS_SHARED */
#define STR_ASSOC FL_USER3
+#define STR_LITERAL FL_RESERVED
#define STR_SHARED_P(s) FL_ALL((s), STR_NOEMBED|ELTS_SHARED)
#define STR_ASSOC_P(s) FL_ALL((s), STR_NOEMBED|STR_ASSOC)
#define STR_NOCAPA (STR_NOEMBED|ELTS_SHARED|STR_ASSOC)
@@ -711,6 +712,104 @@ rb_str_new_frozen(VALUE orig)
RUBY_ALIAS_FUNCTION(rb_str_new4(VALUE orig), rb_str_new_frozen, (orig))
#define rb_str_new4 rb_str_new_frozen
+int rb_str_hash_cmp(VALUE, VALUE);
+st_index_t rb_str_hash(VALUE);
+
+/* static st_index_t*/
+/* rstrhash(st_data_t arg)*/
+/* {*/
+/* register const struct RString *str = (const struct RString *)arg;*/
+/* #define FNV1_32A_INIT 0x811c9dc5*/
+/* return st_hash(RSTRING_PTR(str), RSTRING_LEN(str), FNV1_32A_INIT);*/
+/* }*/
+
+static const struct st_hash_type type_rstrhash = {
+ rb_str_hash_cmp,
+ rb_str_hash
+};
+
+st_table*
+st_init_rstrtable(void)
+{
+ return st_init_table(&type_rstrhash);
+}
+
+static st_table *literal_strings;
+
+static int
+mark_string_i(st_data_t key, st_data_t val, void *data)
+{
+ rb_gc_mark((VALUE)val);
+ return ST_CONTINUE;
+}
+
+void
+rb_str_frozen_literal_mark()
+{
+ fprintf(stderr, "string literal table is %zu entries\n", literal_strings->num_entries);
+ st_foreach(literal_strings, mark_string_i, 0);
+}
+
+void
+rb_str_frozen_literal_delete(VALUE str)
+{
+ st_data_t key, val;
+ key = (st_data_t)RSTRING(str);
+
+ assert(FL_TEST(str, STR_LITERAL));
+ FL_UNSET(str, STR_LITERAL);
+
+ /* MEMCPY(&key, RSTRING(str), struct RString, 1);*/
+
+ if (st_delete(literal_strings, &key, &val)) {
+ /* fprintf(stderr, "removing literal '%s'\n", RSTRING_PTR(str));*/
+ assert((VALUE)val == str);
+ } else
+ fprintf(stderr, "DELEEEEEEEEEEEEEEEEEEEETE\n");
+
+}
+
+VALUE
+rb_str_frozen_literal(VALUE str)
+{
+ char *ptr;
+ long len;
+ st_data_t frozen;
+
+ Check_Type(str, T_STRING);
+ ptr = RSTRING_PTR(str);
+ len = RSTRING_LEN(str);
+
+ /* OBJ_FREEZE(str);*/
+ /* return str;*/
+
+ if (FL_TEST(str, STR_LITERAL))
+ return str;
+
+ /* if (!ptr || len > 32 || ptr[len] != 0 || STR_ASSOC_P(str)) {*/
+ if (ptr && (len < 64 || ptr[0] == '/') && ptr[len] == 0 && !STR_SHARED_P(str)) {
+ /* ok */
+ } else if (!STR_EMBED_P(str)) {
+ OBJ_FREEZE(str);
+ return str;
+ }
+
+ if (st_lookup(literal_strings, (st_data_t)RSTRING(str), &frozen)) {
+ /* STR_SET_NOEMBED(str);*/
+ /* FL_SET(str, ELTS_SHARED);*/
+ /* RSTRING(str)->as.heap.aux.shared = (VALUE)frozen;*/
+ /* OBJ_FREEZE(str);*/
+ /* fprintf(stderr, "MATCH: '%s' for '%s'\n", RSTRING_PTR(frozen), RSTRING_PTR(str));*/
+ return (VALUE)frozen;
+ } else {
+ FL_SET(str, STR_LITERAL);
+ OBJ_FREEZE(str);
+ /* fprintf(stderr, "creating literal '%s'\n", RSTRING_PTR(str));*/
+ st_add_direct(literal_strings, (st_data_t)RSTRING(str), (st_data_t)RSTRING(str));
+ return str;
+ }
+}
+
VALUE
rb_str_new_with_class(VALUE obj, const char *ptr, long len)
{
@@ -788,6 +887,10 @@ rb_free_tmp_buffer(volatile VALUE *store)
void
rb_str_free(VALUE str)
{
+ if (FL_TEST(str, STR_LITERAL)) {
+ /* if (STR_EMBED_P(str)) {*/
+ rb_str_frozen_literal_delete(str);
+ }
if (!STR_EMBED_P(str) && !STR_SHARED_P(str)) {
xfree(RSTRING(str)->as.heap.ptr);
}
@@ -910,7 +1013,13 @@ rb_str_dup(VALUE str)
VALUE
rb_str_resurrect(VALUE str)
{
- return str_replace(str_alloc(rb_cString), str);
+ VALUE ret = str_replace(str_alloc(rb_cString), str);
+ if (FL_TEST(str, STR_LITERAL)) {
+ assert(OBJ_FROZEN(str));
+ /* assert(STR_EMBED_P(str));*/
+ /* fprintf(stderr, "resurructed '%s' to '%s'\n", RSTRING_PTR(str), RSTRING_PTR(ret));*/
+ }
+ return ret;
}
/*
@@ -7772,6 +7881,8 @@ rb_to_id(VALUE name)
void
Init_String(void)
{
+ literal_strings = st_init_rstrtable();
+
#undef rb_intern
#define rb_intern(str) rb_intern_const(str)
diff --git a/variable.c b/variable.c
index 303bb27..7c9c580 100644
--- a/variable.c
+++ b/variable.c
@@ -65,7 +65,8 @@ fc_path(struct fc_result *fc, ID name)
path = tmp;
fc = fc->prev;
}
- OBJ_FREEZE(path);
+ path = rb_str_frozen_literal(path);
+ /* OBJ_FREEZE(path);*/
return path;
}
@@ -153,7 +154,8 @@ classname(VALUE klass)
return find_class_path(klass);
}
path = rb_str_dup(rb_id2str(SYM2ID((VALUE)n)));
- OBJ_FREEZE(path);
+ path = rb_str_frozen_literal(path);
+ /* OBJ_FREEZE(path);*/
st_insert(RCLASS_IV_TBL(klass), (st_data_t)classpath, (st_data_t)path);
n = classid;
st_delete(RCLASS_IV_TBL(klass), &n, 0);
@@ -208,7 +210,8 @@ rb_class_path(VALUE klass)
}
}
path = rb_sprintf("#<%s:%p>", s, (void*)klass);
- OBJ_FREEZE(path);
+ path = rb_str_frozen_literal(path);
+ /* OBJ_FREEZE(path);*/
rb_ivar_set(klass, tmp_classpath, path);
return path;
@@ -227,7 +230,8 @@ rb_set_class_path_string(VALUE klass, VALUE under, VALUE name)
str = rb_str_dup(rb_class_path(under));
rb_str_cat2(str, "::");
rb_str_append(str, name);
- OBJ_FREEZE(str);
+ str = rb_str_frozen_literal(str);
+ /* OBJ_FREEZE(str);*/
}
rb_ivar_set(klass, classpath, str);
}
@@ -245,7 +249,8 @@ rb_set_class_path(VALUE klass, VALUE under, const char *name)
rb_str_cat2(str, "::");
rb_str_cat2(str, name);
}
- OBJ_FREEZE(str);
+ str = rb_str_frozen_literal(str);
+ /* OBJ_FREEZE(str);*/
rb_ivar_set(klass, classpath, str);
}
@@ -1464,7 +1469,8 @@ rb_autoload(VALUE mod, ID id, const char *file)
}
fn = rb_str_new2(file);
FL_UNSET(fn, FL_TAINT);
- OBJ_FREEZE(fn);
+ fn = rb_str_frozen_literal(fn);
+ /* OBJ_FREEZE(fn);*/
st_insert(tbl, (st_data_t)id, (st_data_t)rb_node_newnode(NODE_MEMO, fn, rb_safe_level(), 0));
}
diff --git a/vm_eval.c b/vm_eval.c
index 6f2da3e..6ec6af0 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -972,6 +972,7 @@ static VALUE
eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *volatile file, volatile int line)
{
int state;
+ VALUE filename = Qnil;
VALUE result = Qundef;
VALUE envval;
rb_binding_t *bind = 0;
@@ -983,6 +984,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char
if (file == 0) {
file = rb_sourcefile();
+ filename = rb_sourcefilename();
line = rb_sourceline();
}
@@ -999,6 +1001,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char
envval = bind->env;
if (strcmp(file, "(eval)") == 0 && bind->filename != Qnil) {
file = RSTRING_PTR(bind->filename);
+ filename = bind->filename;
line = bind->line_no;
}
}
@@ -1024,10 +1027,13 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char
}
}
+ if (!RTEST(filename))
+ filename = rb_str_new2(file);
+
/* make eval iseq */
th->parse_in_eval++;
th->mild_compile_error++;
- iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
+ iseqval = rb_iseq_compile(src, rb_str_frozen_literal(filename), INT2FIX(line));
th->mild_compile_error--;
th->parse_in_eval--;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment