Skip to content
This repository has been archived by the owner on Dec 30, 2022. It is now read-only.

Commit

Permalink
Add core libraries
Browse files Browse the repository at this point in the history
  • Loading branch information
noriyotcp committed Sep 30, 2017
1 parent 040366b commit 505e5c1
Show file tree
Hide file tree
Showing 16 changed files with 3,082 additions and 3 deletions.
62 changes: 62 additions & 0 deletions src/core/bool.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Bool has only two possible values: `true` and `false`. They are constructed using these literals:
#
# ```
# true # A Bool that is true
# false # A Bool that is false
# ```
struct Bool
# Bitwise OR. Returns `true` if this bool or *other* is `true`, otherwise returns `false`.
#
# ```
# false | false # => false
# false | true # => true
# true | false # => true
# true | true # => true
# ```
def |(other : Bool)
self ? true : other
end

# Bitwise AND. Returns `true` if this bool and *other* are `true`, otherwise returns `false`.
#
# ```
# false & false # => false
# false & true # => false
# true & false # => false
# true & true # => true
# ```
def &(other : Bool)
self ? other : false
end

# Exclusive OR. Returns `true` if this bool is different from *other*, otherwise returns `false`.
#
# ```
# false ^ false # => false
# false ^ true # => true
# true ^ false # => true
# true ^ true # => false
# ```
def ^(other : Bool)
self != other
end

# Returns a hash value for this boolean: 0 for `false`, 1 for `true`.
def hash
self ? 1 : 0
end

# Returns `"true"` for `true` and `"false"` for `false`.
def to_s
self ? "true" : "false"
end

# Appends `"true"` for `true` and `"false"` for `false` to the given IO.
# def to_s(io)
# io << to_s
# end

def clone
self
end
end
54 changes: 54 additions & 0 deletions src/core/comparable.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# The `Comparable` mixin is used by classes whose objects may be ordered.
#
# Including types must provide an `<=>` method, which compares the receiver against
# another object, returning `-1`, `0`, or `+1` depending on whether the receiver is less than,
# equal to, or greater than the other object.
#
# `Comparable` uses `<=>` to implement the conventional comparison operators (`<`, `<=`, `==`, `>=`, and `>`).
module Comparable(T)
# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `-1`.
def <(other : T)
(self <=> other) < 0
end

# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `-1` or `0`.
def <=(other : T)
(self <=> other) <= 0
end

# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `0`.
# Also returns `true` if this and *other* are the same object.
def ==(other : T)
if self.is_a?(Reference)
# Need to do two different comparisons because the compiler doesn't yet
# restrict something like `other.is_a?(Reference) || other.is_a?(Nil)`.
# See #2461
return true if other.is_a?(Reference) && self.same?(other)
return true if other.is_a?(Nil) && self.same?(other)
end

(self <=> other) == 0
end

# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `1`.
def >(other : T)
(self <=> other) > 0
end

# Compares this object to *other* based on the receiver’s `<=>` method, returning `true` if it returns `1` or `0`.
def >=(other : T)
(self <=> other) >= 0
end

# Comparison operator. Returns `0` if the two objects are equal,
# a negative number if this object is considered less than *other*,
# or a positive number otherwise.
#
# Subclasses define this method to provide class-specific ordering.
#
# ```
# # Sort in a descending way
# [4, 7, 2].sort { |x, y| y <=> x } # => [7, 4, 2]
# ```
abstract def <=>(other : T)
end
13 changes: 13 additions & 0 deletions src/core/gc.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module GC
def self.malloc(size : Int)
__crystal_malloc(size.to_u32)
end

def self.malloc_atomic(size : Int)
__crystal_malloc_atomic(size.to_u32)
end

def self.realloc(pointer : Void*, size : Int)
__crystal_realloc(pointer, size.to_u32)
end
end
152 changes: 152 additions & 0 deletions src/core/gc/boehm.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# @[Link("pthread")]
# {% if flag?(:freebsd) %}
# @[Link("gc-threaded")]
# {% else %}
# @[Link("gc")]
# {% end %}

lib LibGC
alias Int = LibCR::Int
alias SizeT = LibCR::SizeT
alias Word = LibCR::ULong

fun init = GC_init
fun malloc = GC_malloc(size : SizeT) : Void*
fun malloc_atomic = GC_malloc_atomic(size : SizeT) : Void*
fun realloc = GC_realloc(ptr : Void*, size : SizeT) : Void*
fun free = GC_free(ptr : Void*)
fun collect_a_little = GC_collect_a_little : Int
fun collect = GC_gcollect
fun add_roots = GC_add_roots(low : Void*, high : Void*)
fun enable = GC_enable
fun disable = GC_disable
fun set_handle_fork = GC_set_handle_fork(value : Int)

fun base = GC_base(displaced_pointer : Void*) : Void*
fun is_heap_ptr = GC_is_heap_ptr(pointer : Void*) : Int
fun general_register_disappearing_link = GC_general_register_disappearing_link(link : Void**, obj : Void*) : Int

type Finalizer = Void*, Void* ->
fun register_finalizer = GC_register_finalizer(obj : Void*, fn : Finalizer, cd : Void*, ofn : Finalizer*, ocd : Void**)
fun register_finalizer_ignore_self = GC_register_finalizer_ignore_self(obj : Void*, fn : Finalizer, cd : Void*, ofn : Finalizer*, ocd : Void**)
fun invoke_finalizers = GC_invoke_finalizers : Int

fun get_heap_usage_safe = GC_get_heap_usage_safe(heap_size : Word*, free_bytes : Word*, unmapped_bytes : Word*, bytes_since_gc : Word*, total_bytes : Word*)
fun set_max_heap_size = GC_set_max_heap_size(Word)

fun get_start_callback = GC_get_start_callback : Void*
fun set_start_callback = GC_set_start_callback(callback : ->)

fun set_push_other_roots = GC_set_push_other_roots(proc : ->)
fun get_push_other_roots = GC_get_push_other_roots : ->

fun push_all_eager = GC_push_all_eager(bottom : Void*, top : Void*)

$stackbottom = GC_stackbottom : Void*

fun set_on_collection_event = GC_set_on_collection_event(cb : ->)

$gc_no = GC_gc_no : LibCR::ULong
$bytes_found = GC_bytes_found : LibCR::Long
# GC_on_collection_event isn't exported. Can't collect totals without it.
# bytes_allocd, heap_size, unmapped_bytes are macros

fun size = GC_size(addr : Void*) : LibCR::SizeT

# Boehm GC requires to use GC_pthread_create and GC_pthread_join instead of pthread_create and pthread_join
fun pthread_create = GC_pthread_create(thread : LibCR::PthreadT*, attr : Void*, start : Void* ->, arg : Void*) : LibCR::Int
fun pthread_join = GC_pthread_join(thread : LibCR::PthreadT, value : Void**) : LibCR::Int
fun pthread_detach = GC_pthread_detach(thread : LibCR::PthreadT) : LibCR::Int
end

# :nodoc:
fun __crystal_malloc(size : UInt32) : Void*
LibGC.malloc(size)
end

# :nodoc:
fun __crystal_malloc_atomic(size : UInt32) : Void*
LibGC.malloc_atomic(size)
end

# :nodoc:
fun __crystal_realloc(ptr : Void*, size : UInt32) : Void*
LibGC.realloc(ptr, size)
end

module GC
def self.init
LibGC.set_handle_fork(1)
LibGC.init
end

def self.collect
LibGC.collect
end

def self.enable
LibGC.enable
end

def self.disable
LibGC.disable
end

def self.free(pointer : Void*)
LibGC.free(pointer)
end

def self.add_finalizer(object : Reference)
add_finalizer_impl(object)
end

def self.add_finalizer(object)
# Nothing
end

private def self.add_finalizer_impl(object : T) forall T
LibGC.register_finalizer_ignore_self(object.as(Void*),
->(obj, data) { obj.as(T).finalize },
nil, nil, nil)
nil
end

def self.add_root(object : Reference)
roots = @@roots ||= [] of Pointer(Void)
roots << Pointer(Void).new(object.object_id)
end

def self.register_disappearing_link(pointer : Void**)
base = LibGC.base(pointer.value)
LibGC.general_register_disappearing_link(pointer, base)
end

def self.is_heap_ptr(pointer : Void*)
LibGC.is_heap_ptr(pointer) != 0
end

record Stats,
# collections : LibCR::ULong,
# bytes_found : LibCR::Long,
heap_size : LibCR::ULong,
free_bytes : LibCR::ULong,
unmapped_bytes : LibCR::ULong,
bytes_since_gc : LibCR::ULong,
total_bytes : LibCR::ULong

def self.stats
LibGC.get_heap_usage_safe(out heap_size, out free_bytes, out unmapped_bytes, out bytes_since_gc, out total_bytes)
# collections = LibGC.gc_no - 1
# bytes_found = LibGC.bytes_found

Stats.new(
# collections: collections,
# bytes_found: bytes_found,
heap_size: heap_size,
free_bytes: free_bytes,
unmapped_bytes: unmapped_bytes,
bytes_since_gc: bytes_since_gc,
total_bytes: total_bytes
)
end
end
10 changes: 10 additions & 0 deletions src/core/lib_cr/x86_64-linux-musl/c/stdint.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
lib LibCR
alias Int8T = SChar
alias Int16T = Short
alias Int32T = Int
alias Int64T = Long
alias UInt8T = Char
alias UInt16T = UShort
alias UInt32T = UInt
alias UInt64T = ULong
end
61 changes: 61 additions & 0 deletions src/core/lib_cr/x86_64-linux-musl/c/sys/types.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require "../stddef"
require "../stdint"

lib LibCR
alias BlkcntT = Long
alias BlksizeT = Long
alias ClockT = Long
alias ClockidT = Int
alias DevT = ULong
alias GidT = UInt
alias IdT = UInt
alias InoT = ULong
alias ModeT = UInt
alias NlinkT = ULong
alias OffT = Long
alias PidT = Int

union PthreadAttrTU
__i : StaticArray(Int, 14)
__vi : StaticArray(Int, 14)
__s : StaticArray(ULong, 7)
end

struct PthreadAttrT
__u : PthreadAttrTU
end

union PthreadCondTU
__i : StaticArray(Int, 12)
__vi : StaticArray(Int, 12)
__p : StaticArray(Void*, 6)
end

struct PthreadCondT
__u : PthreadCondTU
end

struct PthreadCondattrT
__attr : UInt
end

union PthreadMutexTU
__i : StaticArray(Int, 10)
__vi : StaticArray(Int, 10)
__p : StaticArray(Void*, 5)
end

struct PthreadMutexT
__u : PthreadMutexTU
end

struct PthreadMutexattrT
__attr : UInt
end

type PthreadT = Void*
alias SSizeT = Long
alias SusecondsT = Long
alias TimeT = Long
alias UidT = UInt
end
Loading

0 comments on commit 505e5c1

Please sign in to comment.