Skip to content
Permalink
Browse files
Fix: calling twice proc with extern didn't work. Fixes #4982
  • Loading branch information
asterite authored and Martin Verzilli committed Sep 16, 2017
1 parent 611b5eb commit 7f4ccff9a0c3b25f5d77a44e1c0fccfbcedda65e
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
@@ -143,6 +143,27 @@ describe "Codegen: extern struct" do
)).to_i.should eq(42)
end

it "codegens extern proc call twice (#4982)" do
run(%(
@[Extern]
struct Data
def initialize(@foo : Int32)
end
def foo
@foo
end
end
f = ->(data : Data) { data.foo }
x = f.call(Data.new(1))
y = f.call(Data.new(2))
x + y
)).to_i.should eq(3)
end

# These specs *should* also work for 32 bits, but for now we'll
# make sure they work in 64 bits (they probably work in 32 bits too,
# it's just that the specs need to be a bit different)
@@ -98,7 +98,7 @@ module Crystal
end

@c_calling_convention : Bool? = nil
setter c_calling_convention
property c_calling_convention

# Returns `self` as an `External` if this Def is an External
# that must respect the C calling convention.
@@ -651,7 +651,7 @@ class Crystal::CodeGenVisitor
c_calling_convention = target_def.proc_c_calling_convention?

proc_type = context.type.as(ProcInstanceType)
0.upto(target_def.args.size - 1) do |i|
target_def.args.size.times do |i|
arg = args[i]
proc_arg_type = proc_type.arg_types[i]
target_def_arg_type = target_def.args[i].type
@@ -685,6 +685,9 @@ class Crystal::CodeGenVisitor
# arguments according to the ABI.
# For this we temporarily set the target_def's `abi_info` and `c_calling_convention`
# properties for the non-closure branch, and then reset it.
old_abi_info = target_def.abi_info?
old_c_calling_convention = target_def.c_calling_convention

if c_calling_convention
null_fun_ptr, null_args = codegen_extern_primitive_proc_call(target_def, args, fun_ptr)
else
@@ -695,8 +698,6 @@ class Crystal::CodeGenVisitor
phi.add value, node.type

# Reset abi_info + c_calling_convention so the closure part is generated as usual
old_abi_info = target_def.abi_info?
old_c_calling_convention = target_def.c_calling_convention?
target_def.abi_info = false
target_def.c_calling_convention = nil

@@ -707,7 +708,7 @@ class Crystal::CodeGenVisitor
phi.add value, node.type, true

target_def.abi_info = old_abi_info
target_def.c_calling_convention = !!old_c_calling_convention
target_def.c_calling_convention = old_c_calling_convention
end

old_needs_value = @needs_value

0 comments on commit 7f4ccff

Please sign in to comment.