erl_bif_types.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,807 行 · 第 1/5 页

ERL
1,807
字号
%% -*- erlang-indent-level: 2 -*-%% =====================================================================%% Type information for Erlang Built-in functions (implemented in C)%%%% Copyright (C) 2002 Richard Carlsson%% Copyright (C) 2006 Richard Carlsson, Tobias Lindahl and Kostis Sagonas%%%% This library is free software; you can redistribute it and/or modify%% it under the terms of the GNU Lesser General Public License as%% published by the Free Software Foundation; either version 2 of the%% License, or (at your option) any later version.%%%% This library is distributed in the hope that it will be useful, but%% WITHOUT ANY WARRANTY; without even the implied warranty of%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU%% Lesser General Public License for more details.%%%% You should have received a copy of the GNU Lesser General Public%% License along with this library; if not, write to the Free Software%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307%% USA%%%% Author contact: richardc@it.uu.se, tobiasl@it.uu.se, kostis@it.uu.se%%%% $Id$%%%% =====================================================================-module(erl_bif_types).%-define(BITS, (hipe_rtl_arch:word_size() * 8) - ?TAG_IMMED1_SIZE).-define(BITS, 128). %This is only in bsl to convert answer to pos_inf/neg_inf.-define(TAG_IMMED1_SIZE, 4).-export([type/3, type/4, arg_types/1, arg_types/3, 	 is_known/3, infinity_add/2]).-include("../icode/hipe_icode_primops.hrl").-import(erl_types, [		    number_max/1,		    number_min/1,		    t_any/0,		    t_arity/0,		    t_atom/0,		    t_atom/1,		    t_atom_vals/1,		    t_binary/0,		    t_bool/0,		    t_byte/0,		    t_char/0,		    t_cons/0,		    t_cons/2,		    t_cons_hd/1,		    t_cons_tl/1,		    t_constant/0,		    t_fixnum/0,		    t_non_neg_fixnum/0,		    t_pos_fixnum/0,		    t_float/0,		    t_from_range/2,		    t_from_term/1,		    t_fun/0,		    t_fun/2,		    t_fun_args/1,		    t_fun_range/1,		    t_identifier/0,		    t_inf/2,		    t_integer/0,		    t_non_neg_integer/0,		    t_pos_integer/0,		    t_integers/1,		    t_is_any/1,		    t_is_atom/1,		    t_is_binary/1,		    t_is_bool/1,		    t_is_cons/1,		    t_is_constant/1,		    t_is_float/1,		    t_is_float/1,		    t_is_fun/1,		    t_is_integer/1,		    t_is_integer/1,		    t_is_nil/1,		    t_is_none/1,		    t_is_none_or_unit/1,		    t_is_number/1,		    t_is_pid/1,		    t_is_port/1,		    t_is_pos_improper_list/1,		    t_is_ref/1,		    t_is_string/1,		    t_is_subtype/2,		    t_is_tuple/1,		    t_list/0,		    t_list/1,		    t_list_elements/1,		    t_mfa/0,		    t_nil/0,		    t_none/0,		    t_nonempty_list/0,		    t_nonempty_list/1,		    t_number/0,		    t_number_vals/1,		    t_pid/0,		    t_port/0,		    t_pos_improper_list/0,		    t_pos_improper_list/2,		    t_ref/0,		    t_string/0,		    t_subtract/2,		    t_sup/1,		    t_sup/2,		    t_tuple/0,		    t_tuple/1,		    t_tuple_args/1,		    t_tuple_arity/1,		    t_tuple_subtypes/1,		    t_unit/0		   ]).-ifdef(DO_ERL_BIF_TYPES_TEST).-export([test/0]).-endif.type(M, F, A) ->  type(M, F, A, any_list(A)).%% Arguments should be checked for undefinedness, so we do not make%% unnecessary overapproximations.%%-- code ---------------------------------------------------------------------type(code, add_path, 1, Xs) ->  strict(arg_types(code, add_path, 1), Xs,	 fun (_) ->	     t_sup(t_bool(),		   t_tuple([t_atom('error'), t_atom('bad_directory')]))	 end);type(code, add_patha, 1, Xs) ->  type(code, add_path, 1, Xs);type(code, add_paths, 1, Xs) ->  type(code, add_path, 1, Xs);type(code, add_pathsa, 1, Xs) ->  type(code, add_path, 1, Xs);type(code, add_pathsz, 1, Xs) ->  type(code, add_path, 1, Xs);type(code, add_pathz, 1, Xs) ->  type(code, add_path, 1, Xs);type(code, all_loaded, 0, _) ->  t_list(t_tuple([t_atom(), t_sup([t_string(), % filename				   t_atom('preloaded'),				   t_atom('cover_compiled')])]));type(code, compiler_dir, 0, _) ->  t_string();type(code, del_path, 1, Xs) ->  strict(arg_types(code, del_path, 1), Xs,	 fun (_) ->	     t_sup(t_bool(),		   t_tuple([t_atom('error'), t_atom('bad_name')]))	 end);type(code, delete, 1, Xs) ->  strict(arg_types(code, delete, 1), Xs, fun (_) -> t_bool() end);type(code, ensure_loaded, 1, Xs) ->  type(code, load_file, 1, Xs);type(code, get_chunk, 2, Xs) ->  strict(arg_types(code, get_chunk, 2), Xs,	 fun (_) -> t_sup(t_binary(), t_atom('undefined')) end);type(code, get_object_code, 1, Xs) ->  strict(arg_types(code, get_object_code, 1), Xs,	 fun (_) ->	     t_sup(t_tuple([t_atom(), t_binary(), t_string()]),		   t_atom('error'))	 end);type(code, get_path, 0, _) ->  t_list(t_string());type(code, is_loaded, 1, Xs) ->  strict(arg_types(code, is_loaded, 1), Xs,	 fun (_) ->	     t_sup([t_tuple([t_atom('file'), t_string()]), % filename		    t_tuple([t_atom('file'), t_atom('preloaded')]),		    t_tuple([t_atom('file'), t_atom('cover_compiled')]),		    t_atom('false')])	 end);type(code, is_sticky, 1, Xs) ->  strict(arg_types(code, is_sticky, 1), Xs, fun (_) -> t_bool() end);type(code, is_module_native, 1, Xs) ->  strict(arg_types(code, is_module_native, 1), Xs,	 fun (_) -> t_sup(t_bool(), t_atom('undefined')) end);type(code, lib_dir, 0, _) ->  t_string();type(code, lib_dir, 1, Xs) ->  strict(arg_types(code, lib_dir, 1), Xs,	 fun (_) ->	     t_sup(t_string(), 		   t_tuple([t_atom('error'), t_atom('bad_name')])) 	 end);type(code, load_abs, 1, Xs) ->  type(code, load_file, 1, Xs);type(code, load_abs, 2, Xs) ->  strict(arg_types(code, load_abs, 2), Xs,	 fun ([_File,Mod]) ->	     t_sup(t_tuple([t_atom('module'), Mod]),		   t_tuple([t_atom('error'), t_load_module_error_rsn()]))	 end);type(code, load_binary, 3, Xs) ->  strict(arg_types(code, load_binary, 3), Xs,	 fun ([Mod,_File,_Bin]) ->	     t_sup(t_tuple([t_atom('module'), Mod]),		   t_tuple([t_atom('error'), t_load_module_error_rsn()]))	 end);type(code, load_file, 1, Xs) ->  strict(arg_types(code, load_file, 1), Xs,	 fun ([Mod]) ->	     t_sup(t_tuple([t_atom('module'), case t_is_atom(Mod) of						true -> Mod;						false -> t_atom()					      end]),		   t_tuple([t_atom('error'), t_load_module_error_rsn()]))	 end);type(code, load_native_partial, 2, Xs) ->  strict(arg_types(code, load_native_partial, 2), Xs,	 fun ([Mod,_Bin]) ->	     t_sup(t_tuple([t_atom('module'), Mod]),		   t_tuple([t_atom('error'), t_load_module_error_rsn()]))	 end);type(code, load_native_sticky, 3, Xs) ->  strict(arg_types(code, load_native_sticky, 3), Xs,        fun ([Mod,_Bin,_]) ->	    t_sup(t_tuple([t_atom('module'), Mod]),		  t_tuple([t_atom('error'), t_load_module_error_rsn()]))	end);type(code, module_md5, 1, Xs) ->  strict(arg_types(code, module_md5, 1), Xs,	 fun (_) -> t_sup(t_binary(), t_atom('undefined')) end);type(code, make_stub_module, 3, Xs) ->  strict(arg_types(code, make_stub_module, 3), Xs, fun ([Mod,_,_]) -> Mod end);type(code, priv_dir, 1, Xs) ->  strict(arg_types(code, priv_dir, 1), Xs,	 fun (_) ->	     t_sup(t_string(), t_tuple([t_atom('error'), t_atom('bad_name')]))	 end);type(code, purge, 1, Xs) ->  type(code, delete, 1, Xs);type(code, rehash, 0, _) -> t_atom('ok');type(code, replace_path, 2, Xs) ->  strict(arg_types(code, replace_path, 2), Xs,	 fun (_) ->	     t_sup([t_atom('true'),		    t_tuple([t_atom('error'), t_atom('bad_name')]),		    t_tuple([t_atom('error'), t_atom('bad_directory')]),		    t_tuple([t_atom('error'),			     t_tuple([t_atom('badarg'), t_any()])])])	 end);type(code, root_dir, 0, _) ->  t_string();type(code, set_path, 1, Xs) ->  strict(arg_types(code, set_path, 1), Xs,	 fun (_) ->	     t_sup([t_atom('true'),		    t_tuple([t_atom('error'), t_atom('bad_path')]),		    t_tuple([t_atom('error'), t_atom('bad_directory')])])	 end);type(code, soft_purge, 1, Xs) ->  type(code, delete, 1, Xs);type(code, stick_dir, 1, Xs) ->  strict(arg_types(code, stick_dir, 1), Xs,	 fun (_) -> t_sup(t_atom('ok'), t_atom('error')) end);type(code, stick_mod, 1, Xs) ->  strict(arg_types(code, stick_mod, 1), Xs, fun (_) -> t_atom('true') end);type(code, stop, 0, _) -> t_none();type(code, unstick_dir, 1, Xs) ->  type(code, stick_dir, 1, Xs);type(code, unstick_mod, 1, Xs) ->  type(code, stick_mod, 1, Xs);type(code, which, 1, Xs) ->  strict(arg_types(code, which, 1), Xs,	 fun (_) ->	     t_sup([t_string(),		    t_atom('preloaded'),		    t_atom('cover_compiled'),		    t_atom('non_existing')])	 end);%%-- erl_ddll -----------------------------------------------------------------type(erl_ddll, demonitor, 1, Xs) ->  type(erlang, demonitor, 1, Xs);type(erl_ddll, format_error_int, 1, Xs) ->  strict(arg_types(erl_ddll, format_error_int, 1), Xs,	 fun (_) -> t_string() end);type(erl_ddll, info, 2, Xs) ->  strict(arg_types(erl_ddll, info, 2), Xs, fun (_) -> t_atom() end);type(erl_ddll, loaded_drivers, 0, _) ->  t_tuple([t_atom('ok'), t_list(t_string())]);type(erl_ddll, monitor, 2, Xs) -> % return type is the same, though args are not  type(erlang, monitor, 2, Xs);type(erl_ddll, try_load, 3, Xs) ->  strict(arg_types(erl_ddll, try_load, 3), Xs,	 fun (_) ->	     t_sup([t_tuple([t_atom('ok'), t_atom('already_loaded')]),		    t_tuple([t_atom('ok'), t_atom('loaded')]),		    t_tuple([t_atom('ok'), t_atom('pending_driver'), t_ref()]),		    t_tuple([t_atom('error'), t_atom('inconsistent')]),		    t_tuple([t_atom('error'), t_atom('permanent')])])	 end);type(erl_ddll, try_unload, 2, Xs) ->  strict(arg_types(erl_ddll, try_unload, 2), Xs,	 fun (_) ->	     t_sup([t_tuple([t_atom('ok'), t_atom('pending_process')]),		    t_tuple([t_atom('ok'), t_atom('unloaded')]),		    t_tuple([t_atom('ok'), t_atom('pending_driver')]),		    t_tuple([t_atom('ok'), t_atom('pending_driver'), t_ref()]),		    t_tuple([t_atom('error'), t_atom('permanent')]),		    t_tuple([t_atom('error'), t_atom('not_loaded')]),		    t_tuple([t_atom('error'),			     t_atom('not_loaded_by_this_process')])])	 end);%%-- erlang -------------------------------------------------------------------type(erlang, halt, 0, _) -> t_none();type(erlang, halt, 1, _) -> t_none();type(erlang, exit, 1, _) -> t_none();%% Note that exit/2 sends an exit signal to another process.type(erlang, exit, 2, _) -> t_atom(true);type(erlang, fault, 1, _) -> t_none();type(erlang, fault, 2, _) -> t_none();type(erlang, error, 1, _) -> t_none();type(erlang, error, 2, _) -> t_none();type(erlang, throw, 1, _) -> t_none();type(erlang, hibernate, 3, _) -> t_none();type(erlang, '==', 2, Xs = [X1, X2]) ->  case t_is_atom(X1) andalso t_is_atom(X2) of    true -> type(erlang, '=:=', 2, Xs);    false ->      case t_is_integer(X1) andalso t_is_integer(X2) of	true -> type(erlang, '=:=', 2, Xs);	false -> strict(Xs, t_bool())      end  end;type(erlang, '/=', 2, Xs = [X1, X2]) ->   case t_is_atom(X1) andalso t_is_atom(X2) of    true -> type(erlang, '=/=', 2, Xs);    false ->      case t_is_integer(X1) andalso t_is_integer(X2) of	true -> type(erlang, '=/=', 2, Xs);	false -> strict(Xs, t_bool())      end  end;type(erlang, '=:=', 2, Xs = [Lhs, Rhs]) ->   Ans =    case t_is_none(t_inf(Lhs, Rhs)) of      true -> t_from_term(false);      false ->	case t_is_atom(Lhs) andalso t_is_atom(Rhs) of	  true ->	    case {t_atom_vals(Lhs), t_atom_vals(Rhs)} of	      {[X], [X]} -> t_from_term(true);	      {LhsVals, RhsVals} when LhsVals =/= any, RhsVals =/= any ->		case lists:all(fun({X, Y}) -> X =/= Y end, 			       [{X, Y} || X <- LhsVals, Y <- RhsVals]) of		  true -> t_from_term(false);		  false -> t_bool()		end;	      _ -> t_bool()	    end;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?