Skip to content

Commit 54e40e3

Browse files
committed
adding checked float to int conversions for #725
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
1 parent 0d9f1b5 commit 54e40e3

File tree

13 files changed

+162
-80
lines changed

13 files changed

+162
-80
lines changed

base/array.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,22 +618,22 @@ end
618618
function .^{S<:Integer,T<:Integer}(A::Array{S}, B::Array{T})
619619
F = Array(Float64, promote_shape(size(A), size(B)))
620620
for i=1:numel(A)
621-
F[i] = A[i]^B[i]
621+
F[i] = float64(A[i])^float64(B[i])
622622
end
623623
return F
624624
end
625625

626626
function .^{T<:Integer}(A::Integer, B::Array{T})
627627
F = similar(B, Float64)
628628
for i=1:numel(B)
629-
F[i] = A^B[i]
629+
F[i] = float64(A)^float64(B[i])
630630
end
631631
return F
632632
end
633633

634-
function _jl_power_array_int_body(F, A, B)
634+
function _jl_power_array_int_body{T}(F::Array{T}, A, B)
635635
for i=1:numel(A)
636-
F[i] = A[i]^B
636+
F[i] = A[i]^convert(T,B)
637637
end
638638
return F
639639
end

base/base.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ type ArgumentError <: Exception
3131
msg::String
3232
end
3333

34-
type UnboundError <: Exception
35-
var::Symbol
36-
end
34+
#type UnboundError <: Exception
35+
# var::Symbol
36+
#end
3737

3838
type KeyError <: Exception
3939
key

base/intfuncs.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function power_by_squaring(x, p::Integer)
9393
elseif p == 0
9494
return one(x)
9595
elseif p < 0
96-
error("power_by_squaring: exponent must be non-negative")
96+
throw(DomainError())
9797
elseif p == 2
9898
return x*x
9999
end
@@ -120,16 +120,16 @@ function power_by_squaring(x, p::Integer)
120120
return x
121121
end
122122

123-
^{T<:Integer}(x::T, p::T) = p < 0 ? x^float(p) : power_by_squaring(x,p)
124-
^(x::Number, p::Integer) = p < 0 ? x^float(p) : power_by_squaring(x,p)
123+
^{T<:Integer}(x::T, p::T) = power_by_squaring(x,p)
124+
^(x::Number, p::Integer) = power_by_squaring(x,p)
125125
^(x, p::Integer) = power_by_squaring(x,p)
126126

127127
# x^p mod m
128128
function powermod(x::Integer, p::Integer, m::Integer)
129129
if p == 0
130130
return one(x)
131131
elseif p < 0
132-
error("powermod: exponent must be non-negative")
132+
throw(DomainError())
133133
end
134134
t = 1
135135
while t <= p

base/random.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ const chi2rnd = randchi2 # alias chi2rnd
246246
# http://www.johndcook.com/julia_rng.html
247247
function randbeta(a, b)
248248
if a <= 0 || b <= 0
249-
error("Beta parameters must be positive")
249+
error("beta parameters must be positive")
250250
end
251251

252252
## There are more efficient methods for generating beta samples.

src/alloc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ jl_bits_type_t *jl_pointer_type;
5151
jl_value_t *jl_an_empty_cell=NULL;
5252
jl_value_t *jl_stackovf_exception;
5353
jl_value_t *jl_divbyzero_exception;
54+
jl_value_t *jl_domain_exception;
55+
jl_value_t *jl_overflow_exception;
56+
jl_value_t *jl_inexact_exception;
5457
jl_value_t *jl_undefref_exception;
5558
jl_value_t *jl_interrupt_exception;
5659
jl_value_t *jl_memory_exception;

src/array.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ jl_value_t *jl_arrayref(jl_array_t *a, size_t i)
371371
else {
372372
elt = ((jl_value_t**)a->data)[i];
373373
if (elt == NULL) {
374-
jl_undef_ref_error();
374+
jl_raise(jl_undefref_exception);
375375
}
376376
}
377377
return elt;

src/boot.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ abstract Exception
160160

161161
type BoundsError <: Exception end
162162
type DivideByZeroError <: Exception end
163+
type DomainError <: Exception end
164+
type OverflowError <: Exception end
165+
type InexactError <: Exception end
163166
type MemoryError <: Exception end
164167
type IOError <: Exception end
165168
type StackOverflowError <: Exception end

src/builtins.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,6 @@ void jl_type_error(const char *fname, jl_value_t *expected, jl_value_t *got)
7777
jl_type_error_rt(fname, "", expected, got);
7878
}
7979

80-
void jl_undef_ref_error(void)
81-
{
82-
jl_raise(jl_undefref_exception);
83-
}
84-
85-
void jl_divide_by_zero_error(void)
86-
{
87-
jl_raise(jl_divbyzero_exception);
88-
}
89-
9080
JL_CALLABLE(jl_f_throw)
9181
{
9282
JL_NARGS(throw, 1, 1);
@@ -610,7 +600,7 @@ static jl_value_t *nth_field(jl_value_t *v, size_t i)
610600
{
611601
jl_value_t *fld = ((jl_value_t**)v)[1+i];
612602
if (fld == NULL)
613-
jl_undef_ref_error();
603+
jl_raise(jl_undefref_exception);
614604
return fld;
615605
}
616606

src/cgutils.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,23 +89,39 @@ static void error_unless(Value *cond, const std::string &msg, jl_codectx_t *ctx)
8989
builder.SetInsertPoint(passBB);
9090
}
9191

92-
static void call_error_func_unless(Value *cond, Function *errfunc,
93-
jl_codectx_t *ctx)
92+
static void raise_exception_unless(Value *cond, Value *exc, jl_codectx_t *ctx)
9493
{
9594
BasicBlock *failBB = BasicBlock::Create(getGlobalContext(),"fail",ctx->f);
9695
BasicBlock *passBB = BasicBlock::Create(getGlobalContext(),"pass");
9796
builder.CreateCondBr(cond, passBB, failBB);
9897
builder.SetInsertPoint(failBB);
99-
builder.CreateCall(errfunc);
98+
builder.CreateCall(jlraise_func, exc);
10099
builder.CreateBr(passBB);
101100
ctx->f->getBasicBlockList().push_back(passBB);
102101
builder.SetInsertPoint(passBB);
103102
}
104103

104+
static void raise_exception_unless(Value *cond, GlobalVariable *exc,
105+
jl_codectx_t *ctx)
106+
{
107+
raise_exception_unless(cond, (Value*)builder.CreateLoad(exc, false), ctx);
108+
}
109+
110+
static void raise_exception_if(Value *cond, Value *exc, jl_codectx_t *ctx)
111+
{
112+
raise_exception_unless(builder.CreateXor(cond, ConstantInt::get(T_int1,-1)),
113+
exc, ctx);
114+
}
115+
116+
static void raise_exception_if(Value *cond, GlobalVariable *exc,
117+
jl_codectx_t *ctx)
118+
{
119+
raise_exception_if(cond, (Value*)builder.CreateLoad(exc, false), ctx);
120+
}
121+
105122
static void null_pointer_check(Value *v, jl_codectx_t *ctx)
106123
{
107-
call_error_func_unless(builder.CreateICmpNE(v, V_null),
108-
jluniniterror_func, ctx);
124+
raise_exception_unless(builder.CreateICmpNE(v,V_null), jlundeferr_var, ctx);
109125
}
110126

111127
static Value *boxed(Value *v);

src/codegen.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,16 @@ static GlobalVariable *jlfloat32temp_var;
8989
static GlobalVariable *jlpgcstack_var;
9090
#endif
9191
static GlobalVariable *jlexc_var;
92+
static GlobalVariable *jldiverr_var;
93+
static GlobalVariable *jlundeferr_var;
94+
static GlobalVariable *jldomerr_var;
95+
static GlobalVariable *jlovferr_var;
96+
static GlobalVariable *jlinexacterr_var;
9297

9398
// important functions
9499
static Function *jlnew_func;
95100
static Function *jlraise_func;
96101
static Function *jlerror_func;
97-
static Function *jluniniterror_func;
98-
static Function *jldiverror_func;
99102
static Function *jltypeerror_func;
100103
static Function *jlcheckassign_func;
101104
static Function *jldeclareconst_func;
@@ -1906,6 +1909,16 @@ static void init_julia_llvm_env(Module *m)
19061909
jlnull_var = global_to_llvm("jl_null", (void*)&jl_null);
19071910
jlexc_var = global_to_llvm("jl_exception_in_transit",
19081911
(void*)&jl_exception_in_transit);
1912+
jldiverr_var = global_to_llvm("jl_divbyzero_exception",
1913+
(void*)&jl_divbyzero_exception);
1914+
jlundeferr_var = global_to_llvm("jl_undefref_exception",
1915+
(void*)&jl_undefref_exception);
1916+
jldomerr_var = global_to_llvm("jl_domain_exception",
1917+
(void*)&jl_domain_exception);
1918+
jlovferr_var = global_to_llvm("jl_overflow_exception",
1919+
(void*)&jl_overflow_exception);
1920+
jlinexacterr_var = global_to_llvm("jl_inexact_exception",
1921+
(void*)&jl_inexact_exception);
19091922
jlfloat32temp_var =
19101923
new GlobalVariable(*jl_Module, T_float32,
19111924
false, GlobalVariable::PrivateLinkage,
@@ -1937,22 +1950,6 @@ static void init_julia_llvm_env(Module *m)
19371950
(void*)&jl_new_struct_uninit);
19381951

19391952
std::vector<Type*> empty_args(0);
1940-
jluniniterror_func =
1941-
Function::Create(FunctionType::get(T_void, empty_args, false),
1942-
Function::ExternalLinkage,
1943-
"jl_undef_ref_error", jl_Module);
1944-
jluniniterror_func->setDoesNotReturn();
1945-
jl_ExecutionEngine->addGlobalMapping(jluniniterror_func,
1946-
(void*)&jl_undef_ref_error);
1947-
1948-
jldiverror_func =
1949-
Function::Create(FunctionType::get(T_void, empty_args, false),
1950-
Function::ExternalLinkage,
1951-
"jl_divide_by_zero_error", jl_Module);
1952-
jldiverror_func->setDoesNotReturn();
1953-
jl_ExecutionEngine->addGlobalMapping(jldiverror_func,
1954-
(void*)&jl_divide_by_zero_error);
1955-
19561953
setjmp_func =
19571954
Function::Create(FunctionType::get(T_int32, args1, false),
19581955
Function::ExternalLinkage, "_setjmp", jl_Module);

0 commit comments

Comments
 (0)