Skip to content

Commit

Permalink
Add __crystal_raise_overflow as well known function
Browse files Browse the repository at this point in the history
  • Loading branch information
bcardiff committed Jan 22, 2019
1 parent fdba15f commit cb19460
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 12 deletions.
25 changes: 18 additions & 7 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ require "../program"
require "./llvm_builder_helper"

module Crystal
MAIN_NAME = "__crystal_main"
RAISE_NAME = "__crystal_raise"
MALLOC_NAME = "__crystal_malloc64"
MALLOC_ATOMIC_NAME = "__crystal_malloc_atomic64"
REALLOC_NAME = "__crystal_realloc64"
GET_EXCEPTION_NAME = "__crystal_get_exception"
MAIN_NAME = "__crystal_main"
RAISE_NAME = "__crystal_raise"
RAISE_OVERFLOW_NAME = "__crystal_raise_overflow"
MALLOC_NAME = "__crystal_malloc64"
MALLOC_ATOMIC_NAME = "__crystal_malloc_atomic64"
REALLOC_NAME = "__crystal_realloc64"
GET_EXCEPTION_NAME = "__crystal_get_exception"

class Program
def run(code, filename = nil, debug = Debug::Default)
Expand Down Expand Up @@ -137,6 +138,7 @@ module Crystal
@cant_pass_closure_to_c_exception_call : Call?
@realloc_fun : LLVM::Function?
@c_realloc_fun : LLVM::Function?
@raise_overflow_fun : LLVM::Function?
@main_llvm_context : LLVM::Context
@main_llvm_typer : LLVMTyper
@main_module_info : ModuleInfo
Expand Down Expand Up @@ -293,7 +295,7 @@ module Crystal

def visit(node : FunDef)
case node.name
when MALLOC_NAME, MALLOC_ATOMIC_NAME, REALLOC_NAME, RAISE_NAME, @codegen.personality_name, GET_EXCEPTION_NAME
when MALLOC_NAME, MALLOC_ATOMIC_NAME, REALLOC_NAME, RAISE_NAME, @codegen.personality_name, GET_EXCEPTION_NAME, RAISE_OVERFLOW_NAME
@codegen.accept node
end
false
Expand Down Expand Up @@ -1927,6 +1929,15 @@ module Crystal
end
end

def crystal_raise_overflow_fun
@raise_overflow_fun ||= @main_mod.functions[RAISE_OVERFLOW_NAME]?
if raise_overflow_fun = @raise_overflow_fun
check_main_fun RAISE_OVERFLOW_NAME, raise_overflow_fun
else
raise "BUG: __crystal_raise_overflow is not defined"
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.
Expand Down
18 changes: 13 additions & 5 deletions src/compiler/crystal/codegen/primitives.cr
Original file line number Diff line number Diff line change
Expand Up @@ -368,11 +368,19 @@ class Crystal::CodeGenVisitor
private def codegen_raise_overflow
location = @call_location.not_nil!
set_current_debug_location(location) if @debug.line_numbers?
ex = Call.new(Path.global("OverflowError").at(location), "new").at(location)
call = Call.global("raise", ex).at(location)
visitor = MainVisitor.new(@program)
@program.visit_main call, visitor: visitor
accept call

func = crystal_raise_overflow_fun
call_args = [] of LLVM::Value

if (rescue_block = @rescue_block)
invoke_out_block = new_block "invoke_out"
invoke func, call_args, invoke_out_block, rescue_block
position_at_end invoke_out_block
else
call func, call_args
end

unreachable
end

private def codegen_raise_overflow_cond(overflow_condition)
Expand Down
5 changes: 5 additions & 0 deletions src/raise.cr
Original file line number Diff line number Diff line change
Expand Up @@ -237,3 +237,8 @@ end
fun __crystal_raise_string(message : UInt8*)
raise String.new(message)
end

# :nodoc:
fun __crystal_raise_overflow : NoReturn
raise OverflowError.new
end

0 comments on commit cb19460

Please sign in to comment.