Skip to content

Commit

Permalink
adding checked float to int conversions for #725
Browse files Browse the repository at this point in the history
  checked_fptoui32, checked_fptosi32, checked_fptoui64, checked_fptosi64
adding integer arithmetic intrinsics with overflow checking for #855
  checked_sadd, checked_uadd, checked_ssub, checked_usub, checked_smul, checked_umul
domain error for int^(negative int), closes #745
  • Loading branch information
JeffBezanson committed May 22, 2012
1 parent 0d9f1b5 commit 54e40e3
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 80 deletions.
8 changes: 4 additions & 4 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -618,22 +618,22 @@ end
function .^{S<:Integer,T<:Integer}(A::Array{S}, B::Array{T})
F = Array(Float64, promote_shape(size(A), size(B)))
for i=1:numel(A)
F[i] = A[i]^B[i]
F[i] = float64(A[i])^float64(B[i])
end
return F
end

function .^{T<:Integer}(A::Integer, B::Array{T})
F = similar(B, Float64)
for i=1:numel(B)
F[i] = A^B[i]
F[i] = float64(A)^float64(B[i])
end
return F
end

function _jl_power_array_int_body(F, A, B)
function _jl_power_array_int_body{T}(F::Array{T}, A, B)
for i=1:numel(A)
F[i] = A[i]^B
F[i] = A[i]^convert(T,B)
end
return F
end
Expand Down
6 changes: 3 additions & 3 deletions base/base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ type ArgumentError <: Exception
msg::String
end

type UnboundError <: Exception
var::Symbol
end
#type UnboundError <: Exception
# var::Symbol
#end

type KeyError <: Exception
key
Expand Down
8 changes: 4 additions & 4 deletions base/intfuncs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ function power_by_squaring(x, p::Integer)
elseif p == 0
return one(x)
elseif p < 0
error("power_by_squaring: exponent must be non-negative")
throw(DomainError())
elseif p == 2
return x*x
end
Expand All @@ -120,16 +120,16 @@ function power_by_squaring(x, p::Integer)
return x
end

^{T<:Integer}(x::T, p::T) = p < 0 ? x^float(p) : power_by_squaring(x,p)
^(x::Number, p::Integer) = p < 0 ? x^float(p) : power_by_squaring(x,p)
^{T<:Integer}(x::T, p::T) = power_by_squaring(x,p)
^(x::Number, p::Integer) = power_by_squaring(x,p)
^(x, p::Integer) = power_by_squaring(x,p)

# x^p mod m
function powermod(x::Integer, p::Integer, m::Integer)
if p == 0
return one(x)
elseif p < 0
error("powermod: exponent must be non-negative")
throw(DomainError())
end
t = 1
while t <= p
Expand Down
2 changes: 1 addition & 1 deletion base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ const chi2rnd = randchi2 # alias chi2rnd
# http://www.johndcook.com/julia_rng.html
function randbeta(a, b)
if a <= 0 || b <= 0
error("Beta parameters must be positive")
error("beta parameters must be positive")
end

## There are more efficient methods for generating beta samples.
Expand Down
3 changes: 3 additions & 0 deletions src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ jl_bits_type_t *jl_pointer_type;
jl_value_t *jl_an_empty_cell=NULL;
jl_value_t *jl_stackovf_exception;
jl_value_t *jl_divbyzero_exception;
jl_value_t *jl_domain_exception;
jl_value_t *jl_overflow_exception;
jl_value_t *jl_inexact_exception;
jl_value_t *jl_undefref_exception;
jl_value_t *jl_interrupt_exception;
jl_value_t *jl_memory_exception;
Expand Down
2 changes: 1 addition & 1 deletion src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
else {
elt = ((jl_value_t**)a->data)[i];
if (elt == NULL) {
jl_undef_ref_error();
jl_raise(jl_undefref_exception);
}
}
return elt;
Expand Down
3 changes: 3 additions & 0 deletions src/boot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ abstract Exception

type BoundsError <: Exception end
type DivideByZeroError <: Exception end
type DomainError <: Exception end
type OverflowError <: Exception end
type InexactError <: Exception end
type MemoryError <: Exception end
type IOError <: Exception end
type StackOverflowError <: Exception end
Expand Down
12 changes: 1 addition & 11 deletions src/builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,16 +77,6 @@ void jl_type_error(const char *fname, jl_value_t *expected, jl_value_t *got)
jl_type_error_rt(fname, "", expected, got);
}

void jl_undef_ref_error(void)
{
jl_raise(jl_undefref_exception);
}

void jl_divide_by_zero_error(void)
{
jl_raise(jl_divbyzero_exception);
}

JL_CALLABLE(jl_f_throw)
{
JL_NARGS(throw, 1, 1);
Expand Down Expand Up @@ -610,7 +600,7 @@ static jl_value_t *nth_field(jl_value_t *v, size_t i)
{
jl_value_t *fld = ((jl_value_t**)v)[1+i];
if (fld == NULL)
jl_undef_ref_error();
jl_raise(jl_undefref_exception);
return fld;
}

Expand Down
26 changes: 21 additions & 5 deletions src/cgutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,23 +89,39 @@ static void error_unless(Value *cond, const std::string &msg, jl_codectx_t *ctx)
builder.SetInsertPoint(passBB);
}

static void call_error_func_unless(Value *cond, Function *errfunc,
jl_codectx_t *ctx)
static void raise_exception_unless(Value *cond, Value *exc, jl_codectx_t *ctx)
{
BasicBlock *failBB = BasicBlock::Create(getGlobalContext(),"fail",ctx->f);
BasicBlock *passBB = BasicBlock::Create(getGlobalContext(),"pass");
builder.CreateCondBr(cond, passBB, failBB);
builder.SetInsertPoint(failBB);
builder.CreateCall(errfunc);
builder.CreateCall(jlraise_func, exc);
builder.CreateBr(passBB);
ctx->f->getBasicBlockList().push_back(passBB);
builder.SetInsertPoint(passBB);
}

static void raise_exception_unless(Value *cond, GlobalVariable *exc,
jl_codectx_t *ctx)
{
raise_exception_unless(cond, (Value*)builder.CreateLoad(exc, false), ctx);
}

static void raise_exception_if(Value *cond, Value *exc, jl_codectx_t *ctx)
{
raise_exception_unless(builder.CreateXor(cond, ConstantInt::get(T_int1,-1)),
exc, ctx);
}

static void raise_exception_if(Value *cond, GlobalVariable *exc,
jl_codectx_t *ctx)
{
raise_exception_if(cond, (Value*)builder.CreateLoad(exc, false), ctx);
}

static void null_pointer_check(Value *v, jl_codectx_t *ctx)
{
call_error_func_unless(builder.CreateICmpNE(v, V_null),
jluniniterror_func, ctx);
raise_exception_unless(builder.CreateICmpNE(v,V_null), jlundeferr_var, ctx);
}

static Value *boxed(Value *v);
Expand Down
33 changes: 15 additions & 18 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,16 @@ static GlobalVariable *jlfloat32temp_var;
static GlobalVariable *jlpgcstack_var;
#endif
static GlobalVariable *jlexc_var;
static GlobalVariable *jldiverr_var;
static GlobalVariable *jlundeferr_var;
static GlobalVariable *jldomerr_var;
static GlobalVariable *jlovferr_var;
static GlobalVariable *jlinexacterr_var;

// important functions
static Function *jlnew_func;
static Function *jlraise_func;
static Function *jlerror_func;
static Function *jluniniterror_func;
static Function *jldiverror_func;
static Function *jltypeerror_func;
static Function *jlcheckassign_func;
static Function *jldeclareconst_func;
Expand Down Expand Up @@ -1906,6 +1909,16 @@ static void init_julia_llvm_env(Module *m)
jlnull_var = global_to_llvm("jl_null", (void*)&jl_null);
jlexc_var = global_to_llvm("jl_exception_in_transit",
(void*)&jl_exception_in_transit);
jldiverr_var = global_to_llvm("jl_divbyzero_exception",
(void*)&jl_divbyzero_exception);
jlundeferr_var = global_to_llvm("jl_undefref_exception",
(void*)&jl_undefref_exception);
jldomerr_var = global_to_llvm("jl_domain_exception",
(void*)&jl_domain_exception);
jlovferr_var = global_to_llvm("jl_overflow_exception",
(void*)&jl_overflow_exception);
jlinexacterr_var = global_to_llvm("jl_inexact_exception",
(void*)&jl_inexact_exception);
jlfloat32temp_var =
new GlobalVariable(*jl_Module, T_float32,
false, GlobalVariable::PrivateLinkage,
Expand Down Expand Up @@ -1937,22 +1950,6 @@ static void init_julia_llvm_env(Module *m)
(void*)&jl_new_struct_uninit);

std::vector<Type*> empty_args(0);
jluniniterror_func =
Function::Create(FunctionType::get(T_void, empty_args, false),
Function::ExternalLinkage,
"jl_undef_ref_error", jl_Module);
jluniniterror_func->setDoesNotReturn();
jl_ExecutionEngine->addGlobalMapping(jluniniterror_func,
(void*)&jl_undef_ref_error);

jldiverror_func =
Function::Create(FunctionType::get(T_void, empty_args, false),
Function::ExternalLinkage,
"jl_divide_by_zero_error", jl_Module);
jldiverror_func->setDoesNotReturn();
jl_ExecutionEngine->addGlobalMapping(jldiverror_func,
(void*)&jl_divide_by_zero_error);

setjmp_func =
Function::Create(FunctionType::get(T_int32, args1, false),
Function::ExternalLinkage, "_setjmp", jl_Module);
Expand Down
8 changes: 7 additions & 1 deletion src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void fpe_handler(int arg)
sigaddset(&sset, SIGFPE);
sigprocmask(SIG_UNBLOCK, &sset, NULL);

jl_divide_by_zero_error();
jl_raise(jl_divbyzero_exception);
}

void segv_handler(int sig, siginfo_t *info, void *context)
Expand Down Expand Up @@ -260,6 +260,12 @@ void jl_get_builtin_hooks(void)
jl_apply((jl_function_t*)core("StackOverflowError"), NULL, 0);
jl_divbyzero_exception =
jl_apply((jl_function_t*)core("DivideByZeroError"), NULL, 0);
jl_domain_exception =
jl_apply((jl_function_t*)core("DomainError"), NULL, 0);
jl_overflow_exception =
jl_apply((jl_function_t*)core("OverflowError"), NULL, 0);
jl_inexact_exception =
jl_apply((jl_function_t*)core("InexactError"), NULL, 0);
jl_undefref_exception =
jl_apply((jl_function_t*)core("UndefRefError"),NULL,0);
jl_interrupt_exception =
Expand Down
Loading

0 comments on commit 54e40e3

Please sign in to comment.