public

  • Download Gist
optimized-String#freeze.diff
Diff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
diff --git a/compile.c b/compile.c
index 2285d28..02044f3 100644
--- a/compile.c
+++ b/compile.c
@@ -4311,6 +4311,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
break;
}
case NODE_CALL:
+ if (nd_type(node->nd_recv) == NODE_STR && node->nd_mid == idFreeze && node->nd_args == NULL) {
+ ADD_INSN1(ret, line, opt_str_freeze, rb_fstring(node->nd_recv->nd_lit));
+ if (poped) {
+ ADD_INSN(ret, line, pop);
+ }
+ break;
+ }
case NODE_FCALL:
case NODE_VCALL:{ /* VCALL: variable or call */
/*
diff --git a/defs/id.def b/defs/id.def
index 57c0ae9..53ed377 100644
--- a/defs/id.def
+++ b/defs/id.def
@@ -1,5 +1,6 @@
# -*- mode: ruby; coding: us-ascii -*-
firstline, predefined = __LINE__+1, %[\
+ freeze
inspect
intern
object_id
diff --git a/insns.def b/insns.def
index 740ff5d..e8deedb 100644
--- a/insns.def
+++ b/insns.def
@@ -1002,6 +1002,20 @@ send
CALL_METHOD(ci);
}
+DEFINE_INSN
+opt_str_freeze
+(VALUE str)
+()
+(VALUE val)
+{
+ if (BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG)) {
+ val = str;
+ }
+ else {
+ val = rb_funcall(rb_str_resurrect(str), idFreeze, 0);
+ }
+}
+
/**
@c optimize
@e Invoke method without block, splat
diff --git a/string.c b/string.c
index 7bf4006..be1cee7 100644
--- a/string.c
+++ b/string.c
@@ -8738,6 +8738,7 @@ Init_String(void)
rb_define_method(rb_cString, "byteslice", rb_str_byteslice, -1);
rb_define_method(rb_cString, "scrub", rb_str_scrub, -1);
rb_define_method(rb_cString, "scrub!", str_scrub_bang, -1);
+ rb_define_method(rb_cString, "freeze", rb_obj_freeze, 0);
rb_define_method(rb_cString, "to_i", rb_str_to_i, -1);
rb_define_method(rb_cString, "to_f", rb_str_to_f, 0);
diff --git a/vm.c b/vm.c
index a43f3d6..62bb89b 100644
--- a/vm.c
+++ b/vm.c
@@ -1096,6 +1096,7 @@ vm_init_redefined_flag(void)
OP(EmptyP, EMPTY_P), (C(Array), C(String), C(Hash));
OP(Succ, SUCC), (C(Fixnum), C(String), C(Time));
OP(EqTilde, MATCH), (C(Regexp), C(String));
+ OP(Freeze, FREEZE), (C(String));
#undef C
#undef OP
}
diff --git a/vm_insnhelper.h b/vm_insnhelper.h
index 73e88e5..8978ea0 100644
--- a/vm_insnhelper.h
+++ b/vm_insnhelper.h
@@ -56,6 +56,7 @@ enum {
BOP_NOT,
BOP_NEQ,
BOP_MATCH,
+ BOP_FREEZE,
BOP_LAST_
};

poped my favorite typo!

I think it is a religious reference :)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.