mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
Rename putstring instruction as dupstring
As well as `putchilledstring` as `dupchilledstring`. This is more consistent with similar `duparray` and `duphash` instructions and better reflect it's behavior.
This commit is contained in:
1 parent
3f75e99961
commit
072a6a4a10
15 files changed
+60
-60
Notes:
git
2026-04-29 21:31:26 +00:00
No files matched your search
@@ -86,7 +86,7 @@ tests = [
|
||||
[ 'putobject', %q{ /(?<x>x)/ =~ "x"; x == "x" }, ],
|
||||
|
||||
[ 'putspecialobject', %q{ {//=>true}[//] }, ],
|
||||
[ 'putstring', %q{ "true" }, ],
|
||||
[ 'dupstring', %q{ "true" }, ],
|
||||
[ 'tostring / concatstrings', %q{ "#{true}" }, ],
|
||||
[ 'toregexp', %q{ /#{true}/ =~ "true" && $~ }, ],
|
||||
[ 'intern', %q{ :"#{true}" }, ],
|
||||
|
||||
@@ -3195,7 +3195,7 @@ iseq_pop_newarray(rb_iseq_t *iseq, INSN *iobj)
|
||||
static int
|
||||
is_frozen_putstring(INSN *insn, VALUE *op)
|
||||
{
|
||||
if (IS_INSN_ID(insn, putstring) || IS_INSN_ID(insn, putchilledstring)) {
|
||||
if (IS_INSN_ID(insn, dupstring) || IS_INSN_ID(insn, dupchilledstring)) {
|
||||
*op = OPERAND_AT(insn, 0);
|
||||
return 1;
|
||||
}
|
||||
@@ -3255,8 +3255,8 @@ optimize_checktype(rb_iseq_t *iseq, INSN *iobj)
|
||||
VALUE type;
|
||||
|
||||
switch (INSN_OF(iobj)) {
|
||||
case BIN(putstring):
|
||||
case BIN(putchilledstring):
|
||||
case BIN(dupstring):
|
||||
case BIN(dupchilledstring):
|
||||
type = INT2FIX(T_STRING);
|
||||
break;
|
||||
case BIN(putnil):
|
||||
@@ -3454,8 +3454,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
}
|
||||
|
||||
/*
|
||||
* putstring "beg"
|
||||
* putstring "end"
|
||||
* dupstring "beg"
|
||||
* dupstring "end"
|
||||
* newrange excl
|
||||
*
|
||||
* ==>
|
||||
@@ -3670,16 +3670,16 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
* =>
|
||||
* jump L1
|
||||
*
|
||||
* putstring ".."
|
||||
* dupstring ".."
|
||||
* if L1
|
||||
* =>
|
||||
* jump L1
|
||||
*
|
||||
* putstring ".."
|
||||
* dupstring ".."
|
||||
* dup
|
||||
* if L1
|
||||
* =>
|
||||
* putstring ".."
|
||||
* dupstring ".."
|
||||
* jump L1
|
||||
*
|
||||
*/
|
||||
@@ -3694,7 +3694,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
OPERAND_AT(pobj, 0) == Qfalse :
|
||||
FALSE);
|
||||
}
|
||||
else if (IS_INSN_ID(pobj, putstring) ||
|
||||
else if (IS_INSN_ID(pobj, dupstring) ||
|
||||
IS_INSN_ID(pobj, duparray) ||
|
||||
IS_INSN_ID(pobj, newarray)) {
|
||||
cond = IS_INSN_ID(iobj, branchif);
|
||||
@@ -3732,7 +3732,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
|
||||
if (IS_INSN_ID(iobj, pop)) {
|
||||
/*
|
||||
* putself / putnil / putobject obj / putstring "..."
|
||||
* putself / putnil / putobject obj / dupstring "..."
|
||||
* pop
|
||||
* =>
|
||||
* # do nothing
|
||||
@@ -3741,8 +3741,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
if (IS_INSN(prev)) {
|
||||
enum ruby_vminsn_type previ = ((INSN *)prev)->insn_id;
|
||||
if (previ == BIN(putobject) || previ == BIN(putnil) ||
|
||||
previ == BIN(putself) || previ == BIN(putstring) ||
|
||||
previ == BIN(putchilledstring) ||
|
||||
previ == BIN(putself) || previ == BIN(dupstring) ||
|
||||
previ == BIN(dupchilledstring) ||
|
||||
previ == BIN(dup) ||
|
||||
previ == BIN(getlocal) ||
|
||||
previ == BIN(getblockparam) ||
|
||||
@@ -3884,10 +3884,10 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_INSN_ID(iobj, putstring) || IS_INSN_ID(iobj, putchilledstring) ||
|
||||
if (IS_INSN_ID(iobj, dupstring) || IS_INSN_ID(iobj, dupchilledstring) ||
|
||||
(IS_INSN_ID(iobj, putobject) && RB_TYPE_P(OPERAND_AT(iobj, 0), T_STRING))) {
|
||||
/*
|
||||
* putstring ""
|
||||
* dupstring ""
|
||||
* concatstrings N
|
||||
* =>
|
||||
* concatstrings N-1
|
||||
@@ -4222,7 +4222,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((IS_INSN_ID(niobj, putstring) || IS_INSN_ID(niobj, putchilledstring) ||
|
||||
else if ((IS_INSN_ID(niobj, dupstring) || IS_INSN_ID(niobj, dupchilledstring) ||
|
||||
(IS_INSN_ID(niobj, putobject) && RB_TYPE_P(OPERAND_AT(niobj, 0), T_STRING))) &&
|
||||
IS_NEXT_INSN_ID(&niobj->link, send)) {
|
||||
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT((INSN *)niobj->link.next, 0);
|
||||
@@ -4235,9 +4235,9 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
||||
return COMPILE_OK;
|
||||
}
|
||||
}
|
||||
// newarray n, putchilledstring "E", getlocal b, send :pack with {buffer: b}
|
||||
// -> putchilledstring "E", getlocal b, opt_newarray_send n+2, :pack, :buffer
|
||||
else if ((IS_INSN_ID(niobj, putstring) || IS_INSN_ID(niobj, putchilledstring) ||
|
||||
// newarray n, dupchilledstring "E", getlocal b, send :pack with {buffer: b}
|
||||
// -> dupchilledstring "E", getlocal b, opt_newarray_send n+2, :pack, :buffer
|
||||
else if ((IS_INSN_ID(niobj, dupstring) || IS_INSN_ID(niobj, dupchilledstring) ||
|
||||
(IS_INSN_ID(niobj, putobject) && RB_TYPE_P(OPERAND_AT(niobj, 0), T_STRING))) &&
|
||||
IS_NEXT_INSN_ID(&niobj->link, getlocal) &&
|
||||
(niobj->link.next && IS_NEXT_INSN_ID(niobj->link.next, send))) {
|
||||
@@ -4260,7 +4260,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
|
||||
// Break the "else if" chain since some prior checks abort after sub-ifs.
|
||||
// We already found "newarray". To match `[...].include?(arg)` we look for
|
||||
// the instruction(s) representing the argument followed by a "send".
|
||||
if ((IS_INSN_ID(niobj, putstring) || IS_INSN_ID(niobj, putchilledstring) ||
|
||||
if ((IS_INSN_ID(niobj, dupstring) || IS_INSN_ID(niobj, dupchilledstring) ||
|
||||
IS_INSN_ID(niobj, putobject) ||
|
||||
IS_INSN_ID(niobj, putself) ||
|
||||
IS_INSN_ID(niobj, getlocal) ||
|
||||
@@ -4729,7 +4729,7 @@ compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
|
||||
int cnt;
|
||||
if (!RNODE_DSTR(node)->nd_next) {
|
||||
VALUE lit = rb_node_dstr_string_val(node);
|
||||
ADD_INSN1(ret, node, putstring, lit);
|
||||
ADD_INSN1(ret, node, dupstring, lit);
|
||||
RB_OBJ_SET_SHAREABLE(lit);
|
||||
RB_OBJ_WRITTEN(iseq, Qundef, lit);
|
||||
}
|
||||
@@ -11250,10 +11250,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
|
||||
}
|
||||
switch (option->frozen_string_literal) {
|
||||
case ISEQ_FROZEN_STRING_LITERAL_UNSET:
|
||||
ADD_INSN1(ret, node, putchilledstring, lit);
|
||||
ADD_INSN1(ret, node, dupchilledstring, lit);
|
||||
break;
|
||||
case ISEQ_FROZEN_STRING_LITERAL_DISABLED:
|
||||
ADD_INSN1(ret, node, putstring, lit);
|
||||
ADD_INSN1(ret, node, dupstring, lit);
|
||||
break;
|
||||
case ISEQ_FROZEN_STRING_LITERAL_ENABLED:
|
||||
ADD_INSN1(ret, node, putobject, lit);
|
||||
|
||||
@@ -6,12 +6,12 @@
|
||||
__END__
|
||||
|
||||
putobject putobject
|
||||
putobject putstring
|
||||
putobject dupstring
|
||||
putobject setlocal
|
||||
|
||||
putstring putstring
|
||||
putstring putobject
|
||||
putstring setlocal
|
||||
dupstring dupstring
|
||||
dupstring putobject
|
||||
dupstring setlocal
|
||||
|
||||
# putnil end
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ The supported dump items:
|
||||
$ ruby --dump=insns t.rb
|
||||
== disasm: #<ISeq:<main>@t.rb:1 (1,0)-(1,10)> (catch: FALSE)
|
||||
0000 putself ( 1)[Li]
|
||||
0001 putstring "Foo"
|
||||
0001 dupstring "Foo"
|
||||
0003 opt_send_without_block <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>
|
||||
0005 leave
|
||||
```
|
||||
|
||||
@@ -373,7 +373,7 @@ putspecialobject
|
||||
|
||||
/* put string val. string will be copied. */
|
||||
DEFINE_INSN
|
||||
putstring
|
||||
dupstring
|
||||
(VALUE str)
|
||||
()
|
||||
(VALUE val)
|
||||
@@ -383,7 +383,7 @@ putstring
|
||||
|
||||
/* put chilled string val. string will be copied but frozen in the future. */
|
||||
DEFINE_INSN
|
||||
putchilledstring
|
||||
dupchilledstring
|
||||
(VALUE str)
|
||||
()
|
||||
(VALUE val)
|
||||
|
||||
@@ -3266,7 +3266,7 @@ iseqw_s_of(VALUE klass, VALUE body)
|
||||
* 0000 trace 8 ( 1)
|
||||
* 0002 trace 1 ( 2)
|
||||
* 0004 putself
|
||||
* 0005 putstring "hello, world"
|
||||
* 0005 dupstring "hello, world"
|
||||
* 0007 send :puts, 1, nil, 8, <ic:0>
|
||||
* 0013 trace 16 ( 3)
|
||||
* 0015 leave ( 2)
|
||||
|
||||
+1
-1
@@ -5074,7 +5074,7 @@ pm_interpolated_regular_expression_node_closing_set(pm_parser_t *parser, pm_inte
|
||||
* PM_NODE_FLAG_STATIC_LITERAL indicates that the node should be treated as a
|
||||
* single static literal string that can be pushed onto the stack on its own.
|
||||
* Note that this doesn't necessarily mean that the string will be frozen or
|
||||
* not; the instructions in CRuby will be either putobject or putstring,
|
||||
* not; the instructions in CRuby will be either putobject, dupstring or dupchilledstring,
|
||||
* depending on the combination of `--enable-frozen-string-literal`,
|
||||
* `# frozen_string_literal: true`, and whether or not there is interpolation.
|
||||
*
|
||||
|
||||
+8
-8
@@ -774,9 +774,9 @@ pm_interpolated_node_compile(rb_iseq_t *iseq, const pm_node_list_t *parts, const
|
||||
if (frozen_result) {
|
||||
PUSH_INSN1(ret, current_location, putobject, current_string);
|
||||
} else if (mutable_result || interpolated) {
|
||||
PUSH_INSN1(ret, current_location, putstring, current_string);
|
||||
PUSH_INSN1(ret, current_location, dupstring, current_string);
|
||||
} else {
|
||||
PUSH_INSN1(ret, current_location, putchilledstring, current_string);
|
||||
PUSH_INSN1(ret, current_location, dupchilledstring, current_string);
|
||||
}
|
||||
} else {
|
||||
PUSH_INSN1(ret, current_location, putobject, current_string);
|
||||
@@ -9677,10 +9677,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
||||
PUSH_INSN1(ret, location, putobject, string);
|
||||
}
|
||||
else if (PM_NODE_FLAG_P(node, PM_INTERPOLATED_STRING_NODE_FLAGS_MUTABLE)) {
|
||||
PUSH_INSN1(ret, location, putstring, string);
|
||||
PUSH_INSN1(ret, location, dupstring, string);
|
||||
}
|
||||
else {
|
||||
PUSH_INSN1(ret, location, putchilledstring, string);
|
||||
PUSH_INSN1(ret, location, dupchilledstring, string);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10395,10 +10395,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
||||
PUSH_INSN1(ret, location, putobject, string);
|
||||
}
|
||||
else if (PM_NODE_FLAG_P(cast, PM_STRING_FLAGS_MUTABLE)) {
|
||||
PUSH_INSN1(ret, location, putstring, string);
|
||||
PUSH_INSN1(ret, location, dupstring, string);
|
||||
}
|
||||
else {
|
||||
PUSH_INSN1(ret, location, putchilledstring, string);
|
||||
PUSH_INSN1(ret, location, dupchilledstring, string);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -10452,10 +10452,10 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
|
||||
PUSH_INSN1(ret, location, putobject, value);
|
||||
}
|
||||
else if (PM_NODE_FLAG_P(node, PM_STRING_FLAGS_MUTABLE)) {
|
||||
PUSH_INSN1(ret, location, putstring, value);
|
||||
PUSH_INSN1(ret, location, dupstring, value);
|
||||
}
|
||||
else {
|
||||
PUSH_INSN1(ret, location, putchilledstring, value);
|
||||
PUSH_INSN1(ret, location, dupchilledstring, value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -728,7 +728,7 @@ class TestRubyOptimization < Test::Unit::TestCase
|
||||
insn = iseq.disasm
|
||||
assert_match %r{putobject\s+#{Regexp.quote('"1.8.0"..."1.8.8"')}}, insn
|
||||
assert_match %r{putobject\s+#{Regexp.quote('"2.0.0".."2.3.2"')}}, insn
|
||||
assert_no_match(/putstring/, insn)
|
||||
assert_no_match(/dupstring/, insn)
|
||||
assert_no_match(/newrange/, insn)
|
||||
end
|
||||
end
|
||||
|
||||
+4
-4
@@ -2764,7 +2764,7 @@ fn gen_newhash(
|
||||
Some(KeepCompiling)
|
||||
}
|
||||
|
||||
fn gen_putstring(
|
||||
fn gen_dupstring(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
) -> Option<CodegenStatus> {
|
||||
@@ -2784,7 +2784,7 @@ fn gen_putstring(
|
||||
Some(KeepCompiling)
|
||||
}
|
||||
|
||||
fn gen_putchilledstring(
|
||||
fn gen_dupchilledstring(
|
||||
jit: &mut JITState,
|
||||
asm: &mut Assembler,
|
||||
) -> Option<CodegenStatus> {
|
||||
@@ -10814,8 +10814,8 @@ fn get_gen_fn(opcode: VALUE) -> Option<InsnGenFn> {
|
||||
YARVINSN_concattoarray => Some(gen_concattoarray),
|
||||
YARVINSN_pushtoarray => Some(gen_pushtoarray),
|
||||
YARVINSN_newrange => Some(gen_newrange),
|
||||
YARVINSN_putstring => Some(gen_putstring),
|
||||
YARVINSN_putchilledstring => Some(gen_putchilledstring),
|
||||
YARVINSN_dupstring => Some(gen_dupstring),
|
||||
YARVINSN_dupchilledstring => Some(gen_dupchilledstring),
|
||||
YARVINSN_expandarray => Some(gen_expandarray),
|
||||
YARVINSN_defined => Some(gen_defined),
|
||||
YARVINSN_definedivar => Some(gen_definedivar),
|
||||
|
||||
Generated
+4
-4
@@ -723,8 +723,8 @@ pub const YARVINSN_putnil: ruby_vminsn_type = 17;
|
||||
pub const YARVINSN_putself: ruby_vminsn_type = 18;
|
||||
pub const YARVINSN_putobject: ruby_vminsn_type = 19;
|
||||
pub const YARVINSN_putspecialobject: ruby_vminsn_type = 20;
|
||||
pub const YARVINSN_putstring: ruby_vminsn_type = 21;
|
||||
pub const YARVINSN_putchilledstring: ruby_vminsn_type = 22;
|
||||
pub const YARVINSN_dupstring: ruby_vminsn_type = 21;
|
||||
pub const YARVINSN_dupchilledstring: ruby_vminsn_type = 22;
|
||||
pub const YARVINSN_concatstrings: ruby_vminsn_type = 23;
|
||||
pub const YARVINSN_anytostring: ruby_vminsn_type = 24;
|
||||
pub const YARVINSN_toregexp: ruby_vminsn_type = 25;
|
||||
@@ -836,8 +836,8 @@ pub const YARVINSN_trace_putnil: ruby_vminsn_type = 130;
|
||||
pub const YARVINSN_trace_putself: ruby_vminsn_type = 131;
|
||||
pub const YARVINSN_trace_putobject: ruby_vminsn_type = 132;
|
||||
pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 133;
|
||||
pub const YARVINSN_trace_putstring: ruby_vminsn_type = 134;
|
||||
pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 135;
|
||||
pub const YARVINSN_trace_dupstring: ruby_vminsn_type = 134;
|
||||
pub const YARVINSN_trace_dupchilledstring: ruby_vminsn_type = 135;
|
||||
pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 136;
|
||||
pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 137;
|
||||
pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 138;
|
||||
|
||||
@@ -69,22 +69,22 @@ fn test_putobject() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_putstring() {
|
||||
fn test_dupstring() {
|
||||
eval(r##"
|
||||
def test = "#{""}"
|
||||
test
|
||||
"##);
|
||||
assert_contains_opcode("test", YARVINSN_putstring);
|
||||
assert_contains_opcode("test", YARVINSN_dupstring);
|
||||
assert_snapshot!(assert_compiles(r##"test"##), @r#""""#);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_putchilledstring() {
|
||||
fn test_dupchilledstring() {
|
||||
eval(r#"
|
||||
def test = ""
|
||||
test
|
||||
"#);
|
||||
assert_contains_opcode("test", YARVINSN_putchilledstring);
|
||||
assert_contains_opcode("test", YARVINSN_dupchilledstring);
|
||||
assert_snapshot!(assert_compiles(r#"test"#), @r#""""#);
|
||||
}
|
||||
|
||||
|
||||
Generated
+4
-4
@@ -1589,8 +1589,8 @@ pub const YARVINSN_putnil: ruby_vminsn_type = 17;
|
||||
pub const YARVINSN_putself: ruby_vminsn_type = 18;
|
||||
pub const YARVINSN_putobject: ruby_vminsn_type = 19;
|
||||
pub const YARVINSN_putspecialobject: ruby_vminsn_type = 20;
|
||||
pub const YARVINSN_putstring: ruby_vminsn_type = 21;
|
||||
pub const YARVINSN_putchilledstring: ruby_vminsn_type = 22;
|
||||
pub const YARVINSN_dupstring: ruby_vminsn_type = 21;
|
||||
pub const YARVINSN_dupchilledstring: ruby_vminsn_type = 22;
|
||||
pub const YARVINSN_concatstrings: ruby_vminsn_type = 23;
|
||||
pub const YARVINSN_anytostring: ruby_vminsn_type = 24;
|
||||
pub const YARVINSN_toregexp: ruby_vminsn_type = 25;
|
||||
@@ -1702,8 +1702,8 @@ pub const YARVINSN_trace_putnil: ruby_vminsn_type = 130;
|
||||
pub const YARVINSN_trace_putself: ruby_vminsn_type = 131;
|
||||
pub const YARVINSN_trace_putobject: ruby_vminsn_type = 132;
|
||||
pub const YARVINSN_trace_putspecialobject: ruby_vminsn_type = 133;
|
||||
pub const YARVINSN_trace_putstring: ruby_vminsn_type = 134;
|
||||
pub const YARVINSN_trace_putchilledstring: ruby_vminsn_type = 135;
|
||||
pub const YARVINSN_trace_dupstring: ruby_vminsn_type = 134;
|
||||
pub const YARVINSN_trace_dupchilledstring: ruby_vminsn_type = 135;
|
||||
pub const YARVINSN_trace_concatstrings: ruby_vminsn_type = 136;
|
||||
pub const YARVINSN_trace_anytostring: ruby_vminsn_type = 137;
|
||||
pub const YARVINSN_trace_toregexp: ruby_vminsn_type = 138;
|
||||
|
||||
+2
-2
@@ -6984,12 +6984,12 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
|
||||
};
|
||||
state.stack_push(fun.push_insn(block, insn));
|
||||
}
|
||||
YARVINSN_putstring => {
|
||||
YARVINSN_dupstring => {
|
||||
let val = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) });
|
||||
let insn_id = fun.push_insn(block, Insn::StringCopy { val, chilled: false, state: exit_id });
|
||||
state.stack_push(insn_id);
|
||||
}
|
||||
YARVINSN_putchilledstring => {
|
||||
YARVINSN_dupchilledstring => {
|
||||
let val = fun.push_insn(block, Insn::Const { val: Const::Value(get_arg(pc, 0)) });
|
||||
let insn_id = fun.push_insn(block, Insn::StringCopy { val, chilled: true, state: exit_id });
|
||||
state.stack_push(insn_id);
|
||||
|
||||
@@ -744,7 +744,7 @@ pub(crate) mod hir_build_tests {
|
||||
#[test]
|
||||
fn test_string_copy() {
|
||||
eval("def test = \"hello\"");
|
||||
assert_contains_opcode("test", YARVINSN_putchilledstring);
|
||||
assert_contains_opcode("test", YARVINSN_dupchilledstring);
|
||||
assert_snapshot!(hir_string("test"), @"
|
||||
fn test@<compiled>:1:
|
||||
bb1():
|
||||
|
||||
Reference in new issue
Block a user