diff options
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/beam_type.erl | 15 | ||||
-rw-r--r-- | lib/compiler/src/beam_utils.erl | 5 | ||||
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 16 | ||||
-rw-r--r-- | lib/compiler/src/compile.erl | 18 | ||||
-rw-r--r-- | lib/compiler/src/sys_pre_expand.erl | 2 | ||||
-rw-r--r-- | lib/compiler/src/v3_core.erl | 7 | ||||
-rw-r--r-- | lib/compiler/src/v3_kernel.erl | 7 |
7 files changed, 51 insertions, 19 deletions
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl index 6f0ffb5b25..d307d192b2 100644 --- a/lib/compiler/src/beam_type.erl +++ b/lib/compiler/src/beam_type.erl @@ -29,10 +29,17 @@ module({Mod,Exp,Attr,Fs0,Lc}, _Opts) -> {ok,{Mod,Exp,Attr,Fs,Lc}}. function({function,Name,Arity,CLabel,Asm0}) -> - Asm1 = beam_utils:live_opt(Asm0), - Asm2 = opt(Asm1, [], tdb_new()), - Asm = beam_utils:delete_live_annos(Asm2), - {function,Name,Arity,CLabel,Asm}. + try + Asm1 = beam_utils:live_opt(Asm0), + Asm2 = opt(Asm1, [], tdb_new()), + Asm = beam_utils:delete_live_annos(Asm2), + {function,Name,Arity,CLabel,Asm} + catch + Class:Error -> + Stack = erlang:get_stacktrace(), + io:fwrite("Function: ~w/~w\n", [Name,Arity]), + erlang:raise(Class, Error, Stack) + end. %% opt([Instruction], Accumulator, TypeDb) -> {[Instruction'],TypeDb'} %% Keep track of type information; try to simplify. diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index abcd93f280..194f089ba1 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -741,6 +741,9 @@ live_opt([{badmatch,Src}=I|Is], _, D, Acc) -> live_opt([{case_end,Src}=I|Is], _, D, Acc) -> Regs = x_live([Src], 0), live_opt(Is, Regs, D, [I|Acc]); +live_opt([{try_case_end,Src}=I|Is], _, D, Acc) -> + Regs = x_live([Src], 0), + live_opt(Is, Regs, D, [I|Acc]); live_opt([if_end=I|Is], _, D, Acc) -> Regs = 0, live_opt(Is, Regs, D, [I|Acc]); @@ -802,8 +805,6 @@ live_opt([{deallocate,_}=I|Is], Regs, D, Acc) -> live_opt(Is, Regs, D, [I|Acc]); live_opt([{kill,_}=I|Is], Regs, D, Acc) -> live_opt(Is, Regs, D, [I|Acc]); -live_opt([{try_case_end,_}=I|Is], Regs, D, Acc) -> - live_opt(Is, Regs, D, [I|Acc]); live_opt([{try_end,_}=I|Is], Regs, D, Acc) -> live_opt(Is, Regs, D, [I|Acc]); live_opt([{loop_rec_end,_}=I|Is], Regs, D, Acc) -> diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index a52e7bb761..9f0bca9dd5 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -783,15 +783,27 @@ valfun_4({bs_utf16_size,{f,Fail},A,Dst}, Vst) -> valfun_4({bs_bits_to_bytes,{f,Fail},Src,Dst}, Vst) -> assert_term(Src, Vst), set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst)); -valfun_4({bs_init2,{f,Fail},_,Heap,Live,_,Dst}, Vst0) -> +valfun_4({bs_init2,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> verify_live(Live, Vst0), + if + is_integer(Sz) -> + ok; + true -> + assert_term(Sz, Vst0) + end, Vst1 = heap_alloc(Heap, Vst0), Vst2 = branch_state(Fail, Vst1), Vst3 = prune_x_regs(Live, Vst2), Vst = bs_zero_bits(Vst3), set_type_reg(binary, Dst, Vst); -valfun_4({bs_init_bits,{f,Fail},_,Heap,Live,_,Dst}, Vst0) -> +valfun_4({bs_init_bits,{f,Fail},Sz,Heap,Live,_,Dst}, Vst0) -> verify_live(Live, Vst0), + if + is_integer(Sz) -> + ok; + true -> + assert_term(Sz, Vst0) + end, Vst1 = heap_alloc(Heap, Vst0), Vst2 = branch_state(Fail, Vst1), Vst3 = prune_x_regs(Live, Vst2), diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl index 7911f51a73..7365706b94 100644 --- a/lib/compiler/src/compile.erl +++ b/lib/compiler/src/compile.erl @@ -146,10 +146,17 @@ env_default_opts() -> do_compile(Input, Opts0) -> Opts = expand_opts(Opts0), - Self = self(), - Serv = spawn_link(fun() -> internal(Self, Input, Opts) end), + {Pid,Ref} = + spawn_monitor(fun() -> + exit(try + internal(Input, Opts) + catch + error:Reason -> + {error,Reason} + end) + end), receive - {Serv,Rep} -> Rep + {'DOWN',Ref,process,Pid,Rep} -> Rep end. expand_opts(Opts0) -> @@ -242,11 +249,6 @@ format_error({module_name,Mod,Filename}) -> errors=[], warnings=[]}). -internal(Master, Input, Opts) -> - Master ! {self(), try internal(Input, Opts) - catch error:Reason -> {error, Reason} - end}. - internal({forms,Forms}, Opts0) -> {_,Ps} = passes(forms, Opts0), Source = proplists:get_value(source, Opts0, ""), diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl index 68bc83433e..6cea783090 100644 --- a/lib/compiler/src/sys_pre_expand.erl +++ b/lib/compiler/src/sys_pre_expand.erl @@ -119,7 +119,7 @@ expand_pmod(Fs0, St0) -> get_base(As) -> case lists:keyfind(extends, 1, As) of - {extends,[Base]} when is_atom(Base) -> + {extends,_,[Base]} when is_atom(Base) -> Base; _ -> [] diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 242196c593..01042cc56f 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -823,6 +823,13 @@ bitstr({bin_element,_,E0,Size0,[Type,{unit,Unit}|Flags]}, St0) -> {_,_} -> throw(bad_binary) end, + case Size1 of + #c_var{} -> ok; + #c_literal{val=Sz} when is_integer(Sz), Sz >= 0 -> ok; + #c_literal{val=undefined} -> ok; + #c_literal{val=all} -> ok; + _ -> throw(bad_binary) + end, {#c_bitstr{val=E1,size=Size1, unit=#c_literal{val=Unit}, type=#c_literal{val=Type}, diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index c4e7b45aac..b184987625 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -278,11 +278,12 @@ expr(#c_binary{anno=A,segments=Cv}, Sub, St0) -> {#k_binary{anno=A,segs=Kv},Ep,St1} catch throw:bad_element_size -> + St1 = add_warning(get_line(A), bad_segment_size, A, St0), Erl = #c_literal{val=erlang}, Name = #c_literal{val=error}, Args = [#c_literal{val=badarg}], Error = #c_call{anno=A,module=Erl,name=Name,args=Args}, - expr(Error, Sub, St0) + expr(Error, Sub, St1) end; expr(#c_fun{anno=A,vars=Cvs,body=Cb}, Sub0, #kern{ff=OldFF,func=Func}=St0) -> FA = case OldFF of @@ -1827,7 +1828,9 @@ format_error({nomatch_shadow,Line}) -> format_error(nomatch_shadow) -> "this clause cannot match because a previous clause always matches"; format_error(bad_call) -> - "invalid module and/or function name; this call will always fail". + "invalid module and/or function name; this call will always fail"; +format_error(bad_segment_size) -> + "binary construction will fail because of a type mismatch". add_warning(none, Term, Anno, #kern{ws=Ws}=St) -> File = get_file(Anno), |