Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 82fcf2b920a0
Choose a base ref
...
head repository: crystal-lang/crystal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 8ab732187a74
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Jul 26, 2016

  1. Compiler: fix (regular) assignment of proc to C struct/union

    Ary Borenszweig committed Jul 26, 2016
    Copy the full SHA
    c9bc500 View commit details
  2. Compiler: removed unused instance variable

    Ary Borenszweig committed Jul 26, 2016
    Copy the full SHA
    8ab7321 View commit details
Showing with 33 additions and 6 deletions.
  1. +22 −0 spec/compiler/codegen/c_struct_spec.cr
  2. +11 −3 src/compiler/crystal/codegen/codegen.cr
  3. +0 −3 src/compiler/crystal/syntax/to_s.cr
22 changes: 22 additions & 0 deletions spec/compiler/codegen/c_struct_spec.cr
Original file line number Diff line number Diff line change
@@ -357,4 +357,26 @@ describe "Code gen: struct" do
foo.x
)).to_i.should eq(123)
end

it "sets instance var to proc" do
run(%(
require "prelude"
lib LibFoo
struct Foo
x : Int32 -> Int32
end
end
struct LibFoo::Foo
def set(f)
@x = f
end
end
foo = LibFoo::Foo.new
foo.set(->(x : Int32) { x + 1 })
foo.x.call(1)
)).to_i.should eq(2)
end
end
14 changes: 11 additions & 3 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
@@ -892,17 +892,25 @@ module Crystal
end

@last = last
llvm_value = last

# When setting an instance variable of an extern type, if it's a Proc
# type we need to check that the value is not a closure and just get
# the function pointer
if target.is_a?(InstanceVar) && context.type.extern? && target.type.proc?
llvm_value = check_proc_is_not_closure(llvm_value, target.type)
end

if target.is_a?(Var) && target.special_var? && !target_type.reference_like?
# For special vars that are not reference-like, the function argument will
# be a pointer to the struct value. So, we need to first cast the value to
# that type (without the pointer), load it, and store it in the argument.
# If it's a reference-like then it's just a pointer and we can reuse the
# logic in the other branch.
upcasted_value = upcast @last, target_type, value.type
store load(upcasted_value), ptr
llvm_value = upcast llvm_value, target_type, value.type
store load(llvm_value), ptr
else
assign ptr, target_type, value.type, @last
assign ptr, target_type, value.type, llvm_value
end

false
3 changes: 0 additions & 3 deletions src/compiler/crystal/syntax/to_s.cr
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@ module Crystal
@indent = 0
@inside_macro = 0
@inside_lib = false
@inside_c_struct = false
end

def visit(node : Nop)
@@ -1101,9 +1100,7 @@ module Crystal
@str << " "
@str << node.name.to_s
newline
@inside_c_struct = true
accept_with_indent node.body
@inside_c_struct = false
append_indent
@str << keyword("end")
false