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: d92d3e300c59
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: 464268b8b192
Choose a head ref
  • 6 commits
  • 10 files changed
  • 1 contributor

Commits on Sep 14, 2017

  1. Copy the full SHA
    b6d9ca5 View commit details
  2. Copy the full SHA
    b4e23ff View commit details
  3. Remove debug puts

    asterite committed Sep 14, 2017
    Copy the full SHA
    7b31d10 View commit details
  4. Copy the full SHA
    2ae9b9e View commit details
  5. Copy the full SHA
    287251a View commit details
  6. Copy the full SHA
    464268b View commit details
35 changes: 35 additions & 0 deletions spec/std/pointer_spec.cr
Original file line number Diff line number Diff line change
@@ -52,6 +52,15 @@ describe "Pointer" do
end
end

describe "realloc" do
it "raises on negative count" do
p1 = Pointer(Int32).new(123)
expect_raises(ArgumentError) do
p1.realloc(-1)
end
end
end

describe "copy_to" do
it "performs" do
p1 = Pointer.malloc(4) { |i| i }
@@ -318,4 +327,30 @@ describe "Pointer" do
ptr = Pointer(Int32).new(123)
ptr.clone.should eq(ptr)
end

{% if flag?(:bits32) %}
it "raises on copy_from with size bigger than UInt32::MAX" do
ptr = Pointer(Int32).new(123)

expect_raises(ArgumentError) do
ptr.copy_from(ptr, UInt32::MAX.to_u64 + 1)
end
end

it "raises on move_from with size bigger than UInt32::MAX" do
ptr = Pointer(Int32).new(123)

expect_raises(ArgumentError) do
ptr.move_from(ptr, UInt32::MAX.to_u64 + 1)
end
end

it "raises on clear with size bigger than UInt32::MAX" do
ptr = Pointer(Int32).new(123)

expect_raises(ArgumentError) do
ptr.clear(UInt32::MAX.to_u64 + 1)
end
end
{% end %}
end
91 changes: 65 additions & 26 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
@@ -8,9 +8,9 @@ require "./llvm_builder_helper"
module Crystal
MAIN_NAME = "__crystal_main"
RAISE_NAME = "__crystal_raise"
MALLOC_NAME = "__crystal_malloc"
MALLOC_ATOMIC_NAME = "__crystal_malloc_atomic"
REALLOC_NAME = "__crystal_realloc"
MALLOC_NAME = "__crystal_malloc64"
MALLOC_ATOMIC_NAME = "__crystal_malloc_atomic64"
REALLOC_NAME = "__crystal_realloc64"
PERSONALITY_NAME = "__crystal_personality"
GET_EXCEPTION_NAME = "__crystal_get_exception"

@@ -131,9 +131,11 @@ module Crystal
@rescue_block : LLVM::BasicBlock?
@malloc_fun : LLVM::Function?
@malloc_atomic_fun : LLVM::Function?
@c_malloc_fun : LLVM::Function?
@sret_value : LLVM::Value?
@cant_pass_closure_to_c_exception_call : Call?
@realloc_fun : LLVM::Function?
@c_realloc_fun : LLVM::Function?
@main_llvm_context : LLVM::Context
@main_llvm_typer : LLVMTyper
@main_module_info : ModuleInfo
@@ -1821,48 +1823,47 @@ module Crystal
end

def malloc(type)
generic_malloc(type) { malloc_fun }
generic_malloc(type) { crystal_malloc_fun }
end

def malloc_atomic(type)
generic_malloc(type) { malloc_atomic_fun }
generic_malloc(type) { crystal_malloc_atomic_fun }
end

def generic_malloc(type)
size = type.size

if malloc_fun = yield
size = trunc(type.size, llvm_context.int32)
pointer = call malloc_fun, size
bit_cast pointer, type.pointer
else
builder.malloc type
pointer = call_c_malloc size
end

bit_cast pointer, type.pointer
end

def array_malloc(type, count)
generic_array_malloc(type, count) { malloc_fun }
generic_array_malloc(type, count) { crystal_malloc_fun }
end

def array_malloc_atomic(type, count)
generic_array_malloc(type, count) { malloc_atomic_fun }
generic_array_malloc(type, count) { crystal_malloc_atomic_fun }
end

def generic_array_malloc(type, count)
size = trunc(type.size, llvm_context.int32)
count = trunc(count, llvm_context.int32)
size = builder.mul size, count
size = builder.mul type.size, count

if malloc_fun = yield
pointer = call malloc_fun, size
memset pointer, int8(0), size
bit_cast pointer, type.pointer
else
pointer = builder.array_malloc(type, count)
void_pointer = bit_cast pointer, llvm_context.void_pointer
memset void_pointer, int8(0), size
pointer
pointer = call_c_malloc size
end

memset pointer, int8(0), size
bit_cast pointer, type.pointer
end

def malloc_fun
def crystal_malloc_fun
@malloc_fun ||= @main_mod.functions[MALLOC_NAME]?
if malloc_fun = @malloc_fun
check_main_fun MALLOC_NAME, malloc_fun
@@ -1871,7 +1872,7 @@ module Crystal
end
end

def malloc_atomic_fun
def crystal_malloc_atomic_fun
@malloc_atomic_fun ||= @main_mod.functions[MALLOC_ATOMIC_NAME]?
if malloc_fun = @malloc_atomic_fun
check_main_fun MALLOC_ATOMIC_NAME, malloc_fun
@@ -1880,6 +1881,47 @@ module Crystal
end
end

def crystal_realloc_fun
@realloc_fun ||= @main_mod.functions[REALLOC_NAME]?
if realloc_fun = @realloc_fun
check_main_fun REALLOC_NAME, realloc_fun
else
nil
end
end

# We only use C's malloc in tests that don't require the prelude,
# so they don't require the GC. Outside tests these are not used,
# and __crystal_* functions are invoked instead.

def call_c_malloc(size)
size = trunc(size, llvm_context.int32) unless @program.bits64?
call c_malloc_fun, size
end

def c_malloc_fun
malloc_fun = @c_malloc_fun = @main_mod.functions["malloc"]? || begin
size = @program.bits64? ? @main_llvm_context.int64 : @main_llvm_context.int32
@main_mod.functions.add("malloc", ([size]), @main_llvm_context.void_pointer)
end

check_main_fun "malloc", malloc_fun
end

def call_c_realloc(buffer, size)
size = trunc(size, llvm_context.int32) unless @program.bits64?
call c_realloc_fun, [buffer, size]
end

def c_realloc_fun
realloc_fun = @c_realloc_fun = @main_mod.functions["realloc"]? || begin
size = @program.bits64? ? @main_llvm_context.int64 : @main_llvm_context.int32
@main_mod.functions.add("realloc", ([@main_llvm_context.void_pointer, size]), @main_llvm_context.void_pointer)
end

check_main_fun "realloc", realloc_fun
end

def memset(pointer, value, size)
pointer = cast_to_void_pointer pointer
call @program.memset(@llvm_mod, llvm_context), [pointer, value, trunc(size, llvm_context.int32), int32(4), int1(0)]
@@ -1890,13 +1932,10 @@ module Crystal
end

def realloc(buffer, size)
@realloc_fun ||= @main_mod.functions[REALLOC_NAME]?
if realloc_fun = @realloc_fun
realloc_fun = check_main_fun REALLOC_NAME, realloc_fun
size = trunc(size, llvm_context.int32)
if realloc_fun = crystal_realloc_fun
call realloc_fun, [buffer, size]
else
call @program.realloc(@llvm_mod, llvm_context), [buffer, size]
call_c_realloc buffer, size
end
end

2 changes: 1 addition & 1 deletion src/compiler/crystal/codegen/llvm_typer.cr
Original file line number Diff line number Diff line change
@@ -564,7 +564,7 @@ module Crystal
end

def size_t
if @program.has_flag?("x86_64") || @program.has_flag?("aarch64")
if @program.bits64?
@llvm_context.int64
else
@llvm_context.int32
2 changes: 1 addition & 1 deletion src/compiler/crystal/codegen/primitives.cr
Original file line number Diff line number Diff line change
@@ -858,7 +858,7 @@ class Crystal::CodeGenVisitor
when CharType
inst.alignment = 4
else
inst.alignment = @program.has_flag?("x86_64") || @program.has_flag?("aarch64") ? 8 : 4
inst.alignment = @program.bits64? ? 8 : 4
end
end

10 changes: 10 additions & 0 deletions src/compiler/crystal/semantic/flags.cr
Original file line number Diff line number Diff line change
@@ -21,6 +21,10 @@ class Crystal::Program
flags.includes?(name)
end

def bits64?
has_flag?("bits64")
end

private def parse_flags(flags_name)
set = flags_name.map(&.downcase).to_set
set.add "darwin" if set.any?(&.starts_with?("macosx")) || set.any?(&.starts_with?("darwin"))
@@ -37,6 +41,12 @@ class Crystal::Program
set.add "armhf" if set.includes?("gnueabihf")
end

if set.includes?("x86_64") || set.includes?("aarch64")
set.add "bits64"
else
set.add "bits32"
end

set
end
end
33 changes: 33 additions & 0 deletions src/gc/boehm.cr
Original file line number Diff line number Diff line change
@@ -74,6 +74,39 @@ fun __crystal_realloc(ptr : Void*, size : UInt32) : Void*
LibGC.realloc(ptr, size)
end

# :nodoc:
fun __crystal_malloc64(size : UInt64) : Void*
{% if flag?(:bits32) %}
if size > UInt32::MAX
raise ArgumentError.new("Given size is bigger than UInt32::MAX")
end
{% end %}

LibGC.malloc(size)
end

# :nodoc:
fun __crystal_malloc_atomic64(size : UInt64) : Void*
{% if flag?(:bits32) %}
if size > UInt32::MAX
raise ArgumentError.new("Given size is bigger than UInt32::MAX")
end
{% end %}

LibGC.malloc_atomic(size)
end

# :nodoc:
fun __crystal_realloc64(ptr : Void*, size : UInt64) : Void*
{% if flag?(:bits32) %}
if size > UInt32::MAX
raise ArgumentError.new("Given size is bigger than UInt32::MAX")
end
{% end %}

LibGC.realloc(ptr, size)
end

module GC
def self.init
LibGC.set_handle_fork(1)
15 changes: 15 additions & 0 deletions src/gc/null.cr
Original file line number Diff line number Diff line change
@@ -13,6 +13,21 @@ fun __crystal_realloc(ptr : Void*, size : UInt32) : Void*
LibC.realloc(ptr, size)
end

# :nodoc:
fun __crystal_malloc64(size : UInt64) : Void*
LibC.malloc(size)
end

# :nodoc:
fun __crystal_malloc_atomic64(size : UInt64) : Void*
LibC.malloc(size)
end

# :nodoc:
fun __crystal_realloc64(ptr : Void*, size : UInt64) : Void*
LibC.realloc(ptr, size)
end

module GC
def self.init
end
4 changes: 2 additions & 2 deletions src/io/memory.cr
Original file line number Diff line number Diff line change
@@ -101,7 +101,7 @@ class IO::Memory
slice.copy_to(@buffer + @pos, count)

if @pos > @bytesize
Intrinsics.memset((@buffer + @bytesize).as(Void*), 0_u8, (@pos - @bytesize).to_u32, 0_u32, false)
(@buffer + @bytesize).clear(@pos - @bytesize)
end

@pos += count
@@ -125,7 +125,7 @@ class IO::Memory
(@buffer + @pos).value = byte

if @pos > @bytesize
Intrinsics.memset((@buffer + @bytesize).as(Void*), 0_u8, (@pos - @bytesize).to_u32, 0_u32, false)
(@buffer + @bytesize).clear(@pos - @bytesize)
end

@pos += 1
13 changes: 0 additions & 13 deletions src/llvm/builder.cr
Original file line number Diff line number Diff line change
@@ -89,19 +89,6 @@ class LLVM::Builder
Value.new LibLLVM.build_load(self, ptr, name)
end

def malloc(type, name = "")
# check_type("malloc", type)

Value.new LibLLVM.build_malloc(self, type, name)
end

def array_malloc(type, value, name = "")
# check_type("array_malloc", type)
# check_value(value)

Value.new LibLLVM.build_array_malloc(self, type, value, name)
end

{% for method_name in %w(gep inbounds_gep) %}
def {{method_name.id}}(value, indices : Array(LLVM::ValueRef), name = "")
# check_value(value)
Loading