⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ops.tab

📁 OTP是开放电信平台的简称
💻 TAB
📖 第 1 页 / 共 3 页
字号:
i_fetch c ri_fetch c xi_fetch c yi_fetch r ci_fetch r xi_fetch r yi_fetch x ci_fetch x ri_fetch x xi_fetch x yi_fetch y ci_fetch y ri_fetch y xi_fetch y yi_fetch_big1 wi_fetch_big2 wi_fetch_float1 oi_fetch_float2 o%coldi_fetch s s%hot## Some more only used by the emulator#normal_exitapply_bifcall_error_handlererror_action_codecall_traced_functionreturn_trace## Instruction transformations & folded instructions.## Note: There is no 'move_return y r', since there never are any y registers# when we do move_return (if we have y registers, we must do move_deallocate_return).move S r | return => move_return S r%macro: move_return MoveReturn -nonextmove_return x rmove_return c rmove_return n rmove S r | deallocate D | return => move_deallocate_return S r D%macro: move_deallocate_return MoveDeallocateReturn -nonextmove_deallocate_return x r Pmove_deallocate_return y r Pmove_deallocate_return c r Pmove_deallocate_return n r Pdeallocate D | return => deallocate_return D%macro: deallocate_return DeallocateReturn -nonextdeallocate_return Ptest_heap Need u==1 | put_list Y=y r r => test_heap_1_put_list Need Ytest_heap_1_put_list I y# Test tuple & arity (head)is_tuple Fail=f cwo => jump Failis_tuple Fail=f S=rxy | test_arity Fail=f S=rxy Arity => is_tuple_of_arity Fail S Arity%macro:is_tuple_of_arity IsTupleOfArity -fail_actionis_tuple_of_arity f x Ais_tuple_of_arity f y Ais_tuple_of_arity f r A%macro: is_tuple IsTuple -fail_actionis_tuple f xis_tuple f yis_tuple f rtest_arity Fail=f cwo Arity => jump Fail%macro: test_arity IsArity -fail_actiontest_arity f x Atest_arity f y Atest_arity f r Ais_tuple_of_arity Fail=f Reg Arity | get_tuple_element Reg P=u==0 Dst=xy => \  is_tuple_of_arity Fail Reg Arity | extract_next_element Dst | original_reg Reg Ptest_arity Fail Reg Arity | get_tuple_element Reg P=u==0 Dst=xy => \  test_arity Fail Reg Arity | extract_next_element Dst | original_reg Reg Poriginal_reg Reg P1 | get_tuple_element Reg P2 Dst=xy | succ(P1, P2) => \  extract_next_element Dst | original_reg Reg P2get_tuple_element Reg P Dst => i_get_tuple_element Reg P Dst | original_reg Reg Poriginal_reg Reg Pos =>get_tuple_element Reg P Dst => i_get_tuple_element Reg P Dstoriginal_reg/2extract_next_element D1=xy | original_reg Reg P1 | get_tuple_element Reg P2 D2=xy | \succ(P1, P2) | succ(D1, D2) => \  extract_next_element2 D1 | original_reg Reg P2extract_next_element2 D1=xy | original_reg Reg P1 | get_tuple_element Reg P2 D2=xy | \succ(P1, P2) | succ2(D1, D2) => \  extract_next_element3 D1 | original_reg Reg P2#extract_next_element3 D1=xy | original_reg Reg P1 | get_tuple_element Reg P2 D2=xy | \#succ(P1, P2) | succ3(D1, D2) => \#  extract_next_element4 D1 | original_reg Reg P2%macro: extract_next_element ExtractNextElement -packextract_next_element xextract_next_element y%macro: extract_next_element2 ExtractNextElement2 -packextract_next_element2 xextract_next_element2 y%macro: extract_next_element3 ExtractNextElement3 -packextract_next_element3 xextract_next_element3 y#%macro: extract_next_element4 ExtractNextElement4 -pack#extract_next_element4 x#extract_next_element4 yis_integer Fail=f iw =>is_integer Fail=f oan => jump Failis_integer Fail=f S=rx | allocate Need Regs => is_integer_allocate Fail S Need Regs%macro: is_integer_allocate IsIntegerAllocate -fail_actionis_integer_allocate f x I Iis_integer_allocate f r I I%macro: is_integer IsInteger -fail_actionis_integer f xis_integer f yis_integer f ris_list Fail=f n =>is_list Fail=f cow => jump Fail%macro: is_list IsList -fail_actionis_list f ris_list f x%coldis_list f y%hotis_nonempty_list Fail=f S=rx | allocate Need Rs => is_nonempty_list_allocate Fail S Need Rs%macro:is_nonempty_list_allocate IsNonemptyListAllocate -fail_actionis_nonempty_list_allocate f x I Iis_nonempty_list_allocate f r I Iis_nonempty_list F=f r | test_heap I1 I2 => is_non_empty_list_test_heap F r I1 I2%macro: is_non_empty_list_test_heap IsNonemptyListTestHeap -fail_actionis_non_empty_list_test_heap f r I I%macro: is_nonempty_list IsNonemptyList -fail_actionis_nonempty_list f xis_nonempty_list f yis_nonempty_list f r%macro: is_atom IsAtom -fail_actionis_atom f xis_atom f r%coldis_atom f y%hotis_atom Fail=f nwoi => jump Failis_atom Fail=f a =>%macro: is_float IsFloat -fail_actionis_float f ris_float f x%coldis_float f y%hotis_float Fail=f nwai => jump Failis_float Fail=f o =>is_nil Fail=f n =>is_nil Fail=f owia => jump Fail%macro: is_nil IsNil -fail_actionis_nil f xis_nil f yis_nil f ris_binary Fail=f cwo => jump Fail%macro: is_binary IsBinary -fail_actionis_binary f ris_binary f x%coldis_binary f y%hotis_bitstr Fail=f cwo => jump Fail%macro: is_bitstr IsBitstr -fail_actionis_bitstr f ris_bitstr f x%coldis_bitstr f y%hotis_reference Fail=f cwo => jump Fail%macro: is_reference IsRef -fail_actionis_reference f ris_reference f x%coldis_reference f y%hotis_pid Fail=f cwo => jump Fail%macro: is_pid IsPid -fail_actionis_pid f ris_pid f x%coldis_pid f y%hotis_port Fail=f cwo => jump Fail%macro: is_port IsPort -fail_actionis_port f ris_port f x%coldis_port f y%hotis_boolean Fail=f a==am_true =>is_boolean Fail=f a==am_false =>is_boolean Fail=f acwo => jump Fail%cold%macro: is_boolean IsBoolean -fail_actionis_boolean f ris_boolean f xis_boolean f y%hotis_function2 Fail=f acwo Arity => jump Failis_function2 Fail=f Fun awo => jump Failis_function2 f s s%macro: is_function2 IsFunction2 -fail_action# Allocating & initializing.allocate Need Regs | init Y => allocate_init Need Regs Yinit Y1 | init Y2 => init2 Y1 Y2%macro: allocate_init AllocateInit -packallocate_init t I y################################################################## External function and bif calls.################################################################### The BIFs erlang:check_process_code/2 must be called like a function,# to ensure that c_p->i (program counter) is set correctly (an ordinary# BIF call doesn't set it).#call_ext u==2 Bif=u$bif:erlang:check_process_code/2 => i_call_ext Bifcall_ext_last u==2 Bif=u$bif:erlang:check_process_code/2 D => i_call_ext_last Bif Dcall_ext_only u==2 Bif=u$bif:erlang:check_process_code/2 => i_call_ext_only Bif## The BIFs erlang:garbage_collect/0,1 must be called like functions,# to allow them to invoke the garbage collector. (The stack pointer must# be saved and p->arity must be zeroed, which is not done on ordinary BIF calls.)#call_ext u==0 Bif=u$bif:erlang:garbage_collect/0 => i_call_ext Bifcall_ext_last u==0 Bif=u$bif:erlang:garbage_collect/0 D => i_call_ext_last Bif Dcall_ext_only u==0 Bif=u$bif:erlang:garbage_collect/0 => i_call_ext_only Bifcall_ext u==1 Bif=u$bif:erlang:garbage_collect/1 => i_call_ext Bifcall_ext_last u==1 Bif=u$bif:erlang:garbage_collect/1 D => i_call_ext_last Bif Dcall_ext_only u==1 Bif=u$bif:erlang:garbage_collect/1 => i_call_ext_only Bif## The process_info/1,2 BIF should be called like a function, to force# the emulator to set c_p->current before calling it (a BIF call doesn't# set it).## In addition, we force the use of a non-tail-recursive call.  This will ensure# that c_p->cp points into the function making the call.#call_ext u==1 Bif=u$bif:erlang:process_info/1 => i_call_ext Bifcall_ext_last u==1 Bif=u$bif:erlang:process_info/1 D => i_call_ext Bif | deallocate_return Dcall_ext_only Ar=u==1 Bif=u$bif:erlang:process_info/1 => allocate u Ar | i_call_ext Bif | deallocate_return ucall_ext u==2 Bif=u$bif:erlang:process_info/2 => i_call_ext Bifcall_ext_last u==2 Bif=u$bif:erlang:process_info/2 D => i_call_ext Bif | deallocate_return Dcall_ext_only Ar=u==2 Bif=u$bif:erlang:process_info/2 => allocate u Ar | i_call_ext Bif | deallocate_return u## The apply/2 and apply/3 BIFs are instructions.#call_ext u==2 u$func:erlang:apply/2 => i_apply_funcall_ext_last u==2 u$func:erlang:apply/2 D => i_apply_fun_last Dcall_ext_only u==2 u$func:erlang:apply/2 => i_apply_fun_onlycall_ext u==3 u$func:erlang:apply/3 => i_applycall_ext_last u==3 u$func:erlang:apply/3 D => i_apply_last Dcall_ext_only u==3 u$func:erlang:apply/3 => i_apply_only## The exit/1 and throw/1 BIFs never execute the instruction following them;# thus there is no need to generate any return instruction.#call_ext_last u==1 Bif=u$bif:erlang:exit/1 D => call_bif1 Bifcall_ext_last u==1 Bif=u$bif:erlang:throw/1 D => call_bif1 Bifcall_ext_only u==1 Bif=u$bif:erlang:exit/1 => call_bif1 Bifcall_ext_only u==1 Bif=u$bif:erlang:throw/1 => call_bif1 Bif## The error/1 and error/2 BIFs (and their old aliases fault/1 and# fault/2) never execute the instruction following them;# thus there is no need to generate any return instruction.# However, they generate stack backtraces, so if the call instruction# is call_ext_only/2 instruction, we explicitly do an allocate/2 to store# the continuation pointer on the stack.#call_ext_last u==1 Bif=u$bif:erlang:error/1 D => call_bif1 Bifcall_ext_last u==1 Bif=u$bif:erlang:fault/1 D => call_bif1 Bifcall_ext_last u==2 Bif=u$bif:erlang:error/2 D => call_bif2 Bifcall_ext_last u==2 Bif=u$bif:erlang:fault/2 D => call_bif2 Bifcall_ext_only Ar=u==1 Bif=u$bif:erlang:error/1 => \  allocate u Ar | call_bif1 Bifcall_ext_only Ar=u==1 Bif=u$bif:erlang:fault/1 => \  allocate u Ar | call_bif1 Bifcall_ext_only Ar=u==2 Bif=u$bif:erlang:error/2 => \  allocate u Ar | call_bif2 Bifcall_ext_only Ar=u==2 Bif=u$bif:erlang:fault/2 => \  allocate u Ar | call_bif2 Bif## The yield/0 BIF is an instruction#call_ext u==0 u$func:erlang:yield/0 => i_yieldcall_ext_last u==0 u$func:erlang:yield/0 D => i_yield | deallocate_return Dcall_ext_only u==0 u$func:erlang:yield/0 => i_yield | return## The hibernate/3 BIF is an instruction.#call_ext u==3 u$func:erlang:hibernate/3 => i_hibernatecall_ext_last u==3 u$func:erlang:hibernate/3 D => i_hibernatecall_ext_only u==3 u$func:erlang:hibernate/3 => i_hibernate## Hybrid memory architecture need special cons and tuple instructions# that allocate on the message area. These looks like BIFs in the BEAM code.#call_ext u==2 u$func:hybrid:cons/2 => i_global_conscall_ext_last u==2 u$func:hybrid:cons/2 D => i_global_cons | deallocate_return Dcall_ext_only Ar=u==2 u$func:hybrid:cons/2 => i_global_cons | returncall_ext u==1 u$func:hybrid:tuple/1 => i_global_tuplecall_ext_last u==1 u$func:hybrid:tuple/1 D => i_global_tuple | deallocate_return Dcall_ext_only Ar=u==1 u$func:hybrid:tuple/1 => i_global_tuple | returncall_ext u==1 u$func:hybrid:copy/1 => i_global_copycall_ext_last u==1 u$func:hybrid:copy/1 D => i_global_copy | deallocate_return Dcall_ext_only u==1 Ar=u$func:hybrid:copy/1 => i_global_copy | return## The general case for BIFs that have no special instructions.# A BIF used in the tail must be followed by a return instruction.## To make stack backtraces work correctly, we make sure that the continuation# pointer is always stored on the stack.call_ext u==0 Bif=u$is_bif => call_bif0 Bifcall_ext u==1 Bif=u$is_bif => call_bif1 Bifcall_ext u==2 Bif=u$is_bif => call_bif2 Bifcall_ext u==3 Bif=$is_bif => call_bif3 Bifcall_ext_last u==0 Bif=u$is_bif D => call_bif0 Bif | deallocate_return Dcall_ext_last u==1 Bif=u$is_bif D => call_bif1 Bif | deallocate_return Dcall_ext_last u==2 Bif=u$is_bif D => call_bif2 Bif | deallocate_return Dcall_ext_last u==3 Bif=u$is_bif D => call_bif3 Bif | deallocate_return Dcall_ext_only u==0 Bif=u$is_bif => call_bif0 Bif | returncall_ext_only Ar=u==1 Bif=u$is_bif => \  allocate u Ar | call_bif1 Bif | deallocate_return ucall_ext_only Ar=u==2 Bif=u$is_bif => \  allocate u Ar | call_bif2 Bif | deallocate_return ucall_ext_only Ar=u==3 Bif=u$is_bif => \  allocate u Ar | call_bif3 Bif | deallocate_return u## Any remaining calls are calls to Erlang functions, not BIFs.# We rename the instructions to internal names.  This is necessary,# to avoid an end-less loop, because we want to call a few BIFs# with call instructions.

⌨️ 快捷键说明

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