Skip to content

Commit

Permalink
[PRISM] Fix compile_prism when src is a file
Browse files Browse the repository at this point in the history
`compile_prism` can take a source and file (and other arguments) or a
file as the source. `compile` checks if the source is a file and if it
is converts it. `compile_prism` is now doing the same thing.

On the Ruby side `compile` handles a file
[here](https://github.com/ruby/ruby/blob/master/iseq.c#L1159-L1162).

Before:

```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(26,21)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] name@0
0000 putstring                              "Prism"                   (  25)[Li]
0002 setlocal                               name@0, 0
0005 putself                                                          (  26)[Li]
0006 putobject                              "hello, "
0008 getlocal                               name@0, 0
0011 dup
0012 objtostring                            <calldata!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>
0014 anytostring
0015 concatstrings                          2
0017 send                                   <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, nil
0020 leave
hello, Prism

"********* PRISM *************"
./test.rb:13:in `compile_prism': wrong argument type File (expected String) (TypeError)
	from ./test.rb:13:in `<main>'
make: *** [run] Error 1
```

After:

```
"********* Ruby *************"
== disasm: #<ISeq:<compiled>@<compiled>:1 (1,0)-(26,21)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] name@0
0000 putstring                              "Prism"                   (  25)[Li]
0002 setlocal                               name@0, 0
0005 putself                                                          (  26)[Li]
0006 putobject                              "hello, "
0008 getlocal                               name@0, 0
0011 dup
0012 objtostring                            <calldata!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>
0014 anytostring
0015 concatstrings                          2
0017 send                                   <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, nil
0020 leave

"********* PRISM *************"
== disasm: #<ISeq:<compiled>@test_code.rb:24 (24,0)-(25,21)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] name@0
0000 putstring                              "Prism"                   (  24)[Li]
0002 setlocal                               name@0, 0
0005 putself                                                          (  25)[Li]
0006 putobject                              "hello, "
0008 getlocal                               name@0, 0
0011 dup
0012 objtostring                            <calldata!mid:to_s, argc:0, FCALL|ARGS_SIMPLE>
0014 anytostring
0015 concatstrings                          2
0017 send                                   <calldata!mid:puts, argc:1, FCALL|ARGS_SIMPLE>, nil
0020 leave                                                            (  24)
```

Fixes ruby/prism#1609
  • Loading branch information
eileencodes authored and kddnewton committed Dec 15, 2023
1 parent 20f4f00 commit 049a9bd
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
14 changes: 13 additions & 1 deletion iseq.c
Expand Up @@ -1447,7 +1447,19 @@ iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self)
pm_options_line_set(&options, start_line);

pm_parser_t parser;
pm_parser_init(&parser, (const uint8_t *) RSTRING_PTR(src), RSTRING_LEN(src), &options);

if (RB_TYPE_P(src, T_FILE)) {
FilePathValue(src);
file = rb_fstring(src); /* rb_io_t->pathv gets frozen anyways */

pm_string_t input;
pm_string_mapped_init(&input, RSTRING_PTR(file));

pm_parser_init(&parser, pm_string_source(&input), pm_string_length(&input), &options);
}
else {
pm_parser_init(&parser, (const uint8_t *) RSTRING_PTR(src), RSTRING_LEN(src), &options);
}

rb_iseq_t *iseq = iseq_alloc();
iseqw_s_compile_prism_compile(&parser, opt, iseq, file, path, start_line);
Expand Down
11 changes: 11 additions & 0 deletions test/ruby/test_iseq.rb
Expand Up @@ -798,4 +798,15 @@ def test_ibf_bignum
result = RubyVM::InstructionSequence.load_from_binary(iseq.to_binary).eval
assert_equal expected, result, proc {sprintf("expected: %x, result: %x", expected, result)}
end

def test_compile_prism_with_file
Tempfile.create(%w"test_iseq .rb") do |f|
f.puts "name = 'Prism'; puts 'hello"
f.close

assert_nothing_raised(SyntaxError) {
RubyVM::InstructionSequence.compile_prism(f.path)
}
end
end
end

0 comments on commit 049a9bd

Please sign in to comment.