-- | This module represents a type-safe port of Erlang's general instructions. -- If this is your first exposure to BEAM, __I highly recommend Erik Stenman's book: -- __. -- The documentation in this module point there derives directly from there, -- the project, -- and . module Codec.Beam.Instructions ( label, func_info, on_load, line -- * Function and BIF calls , call, call_last, call_only, call_ext, call_ext_last, bif0, bif1, bif2, call_ext_only, apply, apply_last, gc_bif1, gc_bif2, gc_bif3 -- * Allocating, deallocating and returning , allocate, allocate_heap, allocate_zero, allocate_heap_zero, test_heap, init', deallocate, return', trim -- * Sending and receiving , send, remove_message, timeout, loop_rec, loop_rec_end, wait, wait_timeout, recv_mark, recv_set -- * Comparision , is_lt, is_ge, is_eq, is_ne, is_eq_exact, is_ne_exact -- * Type tests , is_integer, is_float, is_number, is_atom, is_pid, is_reference, is_port, is_nil, is_binary, is_list, is_nonempty_list, is_tuple, test_arity, is_boolean, is_function, is_function2, is_bitstr, is_map, is_tagged_tuple -- * Indexing and jumping , select_val, select_tuple_arity, jump -- * Moving, extracting, modifying , move, get_list, get_tuple_element, set_tuple_element -- * Building terms , put_list, put_tuple, put -- * Raising errors , badmatch, if_end, case_end -- * @fun@ support , call_fun, make_fun2 -- * Binary matching , bs_start_match2, bs_get_integer2, bs_get_float2, bs_get_binary2, bs_skip_bits2, bs_test_tail2, bs_save2, bs_restore2, bs_context_to_binary, bs_test_unit, bs_match_string, bs_append, bs_private_append -- * Binary construction , bs_init2, bs_put_integer, bs_put_binary, bs_put_float, bs_put_string, bs_add, bs_init_writable, bs_init_bits, bs_get_utf8, bs_skip_utf8, bs_get_utf16, bs_skip_utf16, bs_get_utf32, bs_skip_utf32, bs_utf8_size, bs_put_utf8, bs_utf16_size, bs_put_utf16, bs_put_utf32 -- * Floating point arithmetic , fclearerror, fcheckerror, fmove, fconv, fadd, fsub, fmul, fdiv, fnegate -- * Try, catch, raise , try, try_end, try_case, try_case_end, raise, catch, catch_end -- * Maps , put_map_assoc, put_map_exact, has_map_fields, get_map_elements ) where import Codec.Beam.Internal.Syntax import Data.Text (Text) -- | Label gives this code address a name and marks the start of -- a basic block. label :: Label -- ^ unique identifier -> Op label a1 = Op 1 [FromNewLabel a1] -- | Define a function M:F/A in the current module. func_info :: Text -- ^ function name -> Int -- ^ arity -> Op func_info a1 a2 = Op 2 [FromNewFunction a1 a2, FromAtom a1, FromUntagged a2] -- | Call the function at label. -- Save the next instruction as the return address in the CP register. call :: Int -- ^ arity -> Label -> Op call a1 a2 = Op 4 [FromUntagged a1, FromLabel a2] -- | Deallocate and do a tail recursive call to the function at label. -- Do not update the CP register. -- Before the call deallocate Deallocate words of stack. call_last :: Int -- ^ arity -> Label -> Int -- ^ number of stack words to deallocate -> Op call_last a1 a2 a3 = Op 5 [FromUntagged a1, FromLabel a2, FromUntagged a3] -- | Do a tail recursive call to the function at Label. -- Do not update the CP register. call_only :: Int -- ^ arity -> Label -> Op call_only a1 a2 = Op 6 [FromUntagged a1, FromLabel a2] -- | Call the function of arity pointed to by Destination. -- Save the next instruction as the return address in the CP register. call_ext :: Import -> Op call_ext a1 = Op 7 [FromUntagged (_import_arity a1), FromImport a1] -- | Deallocate and do a tail call to function -- pointed to by Destination. -- Do not update the CP register. -- Deallocate some words from the stack before the call. call_ext_last :: Import -> Int -> Op call_ext_last a1 a2 = Op 8 [FromUntagged (_import_arity a1), FromImport a1, FromUntagged a2] -- | Call the bif and store the result in register. bif0 :: (Bif0 a1, NoGC a1, IsRegister a2) => a1 -> a2 -> Op bif0 a1 a2 = Op 9 [FromImport (importBif0 a1), fromRegister a2] -- | Call the bif with the source, and store the result in register. -- On failure jump to label. bif1 :: (Bif1 a2, NoGC a2, IsSource a3, IsRegister a4) => Label -> a2 -> a3 -> a4 -> Op bif1 a1 a2 a3 a4 = Op 10 [FromLabel a1, FromImport (importBif1 a2), fromSource a3, fromRegister a4] -- | Call the bif with the sources, and store the result in register. -- On failure jump to label. bif2 :: (Bif2 a2, NoGC a2, IsSource a3, IsSource a4, IsRegister a5) => Label -> a2 -> a3 -> a4 -> a5 -> Op bif2 a1 a2 a3 a4 a5 = Op 11 [FromLabel a1, FromImport (importBif2 a2), fromSource a3, fromSource a4, fromRegister a5] -- | Allocate space for some words on the stack. If a GC is needed -- during allocation there are a number of live X registers. -- Also save the continuation pointer (CP) on the stack. allocate :: Int -- ^ stack words needed -> Int -- ^ live X registers -> Op allocate a1 a2 = Op 12 [FromUntagged a1, FromUntagged a2] -- | Allocate space for some words on the stack and ensure there is -- space for words on the heap. If a GC is needed -- save Live number of X registers. -- Also save the continuation pointer (CP) on the stack. allocate_heap :: Int -- ^ stack words needed -> Int -- ^ heap words needed -> Int -- ^ live X registers -> Op allocate_heap a1 a2 a3 = Op 13 [FromUntagged a1, FromUntagged a2, FromUntagged a3] -- | Allocate space for some words on the stack. If a GC is needed -- during allocation there are a number of live X registers. -- Clear the new stack words. (By writing NIL.) -- Also save the continuation pointer (CP) on the stack. allocate_zero :: Int -- ^ stack words needed -> Int -- ^ live X registers -> Op allocate_zero a1 a2 = Op 14 [FromUntagged a1, FromUntagged a2] -- | Allocate space for some words on the stack and ensure there is -- space for words on the heap. If a GC is needed -- save Live number of X registers. -- Clear the new stack words. (By writing NIL.) -- Also save the continuation pointer (CP) on the stack. allocate_heap_zero :: Int -- ^ stack words needed -> Int -- ^ heap words needed -> Int -- ^ live X registers -> Op allocate_heap_zero a1 a2 a3 = Op 15 [FromUntagged a1, FromUntagged a2, FromUntagged a3] -- | Ensure there is space for HeapNeed words on the heap. If a GC is needed -- save live number of X registers. test_heap :: Int -- ^ heap words needed -> Int -- ^ live number of X registers -> Op test_heap a1 a2 = Op 16 [FromUntagged a1, FromUntagged a2] -- | Clear the stack word. (By writing NIL.) init' :: Y -> Op init' a1 = Op 17 [FromY a1] -- | Restore the continuation pointer (CP) from the stack and deallocate -- N+1 words from the stack (the + 1 is for the CP). deallocate :: Int -> Op deallocate a1 = Op 18 [FromUntagged a1] -- | Return to the address in the continuation pointer (CP). return' :: Op return' = Op 19 [] -- | Send argument in x(1) as a message to the destination process in x(0). -- The message in x(1) ends up as the result of the send in x(0). send :: Op send = Op 20 [] -- | Unlink the current message from the message queue and store a -- pointer to the message in x(0). Remove any timeout. remove_message :: Op remove_message = Op 21 [] -- | Reset the save point of the mailbox and clear the timeout flag. timeout :: Op timeout = Op 22 [] -- | Loop over the message queue, if it is empty jump to label. loop_rec :: Label -> X -> Op loop_rec a1 a2 = Op 23 [FromLabel a1, FromX a2] -- | Advance the save pointer to the next message and jump back to label. loop_rec_end :: Label -> Op loop_rec_end a1 = Op 24 [FromLabel a1] -- | Suspend the processes and set the entry point to the beginning of the -- receive loop at label. wait :: Label -> Op wait a1 = Op 25 [FromLabel a1] -- | Sets up a timeout of source milliseconds and saves the address of the -- following instruction as the entry point if the timeout triggers. wait_timeout :: (IsSource a2) => Label -> a2 -> Op wait_timeout a1 a2 = Op 26 [FromLabel a1, fromSource a2] -- | Compare two terms and jump to label if first is not less than second. is_lt :: (IsSource a2, IsSource a3) => Label -> a2 -> a3 -> Op is_lt a1 a2 a3 = Op 39 [FromLabel a1, fromSource a2, fromSource a3] -- | Compare two terms and jump to label if first is less than second. is_ge :: (IsSource a2, IsSource a3) => Label -> a2 -> a3 -> Op is_ge a1 a2 a3 = Op 40 [FromLabel a1, fromSource a2, fromSource a3] -- | Compare two terms and jump to label if first is not (numerically) equal to second. is_eq :: (IsSource a2, IsSource a3) => Label -> a2 -> a3 -> Op is_eq a1 a2 a3 = Op 41 [FromLabel a1, fromSource a2, fromSource a3] -- | Compare two terms and jump to label if first is (numerically) equal to second. is_ne :: (IsSource a2, IsSource a3) => Label -> a2 -> a3 -> Op is_ne a1 a2 a3 = Op 42 [FromLabel a1, fromSource a2, fromSource a3] -- | Compare two terms and jump to label if first is not exactly equal to second. is_eq_exact :: (IsSource a2, IsSource a3) => Label -> a2 -> a3 -> Op is_eq_exact a1 a2 a3 = Op 43 [FromLabel a1, fromSource a2, fromSource a3] -- | Compare two terms and jump to label if first is exactly equal to second. is_ne_exact :: (IsSource a2, IsSource a3) => Label -> a2 -> a3 -> Op is_ne_exact a1 a2 a3 = Op 44 [FromLabel a1, fromSource a2, fromSource a3] -- | Test the type of source and jump to label if it is not an integer. is_integer :: (IsSource a2) => Label -> a2 -> Op is_integer a1 a2 = Op 45 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a float. is_float :: (IsSource a2) => Label -> a2 -> Op is_float a1 a2 = Op 46 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a number. is_number :: (IsSource a2) => Label -> a2 -> Op is_number a1 a2 = Op 47 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a atom. is_atom :: (IsSource a2) => Label -> a2 -> Op is_atom a1 a2 = Op 48 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a pid. is_pid :: (IsSource a2) => Label -> a2 -> Op is_pid a1 a2 = Op 49 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a reference. is_reference :: (IsSource a2) => Label -> a2 -> Op is_reference a1 a2 = Op 50 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a port. is_port :: (IsSource a2) => Label -> a2 -> Op is_port a1 a2 = Op 51 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not nil. is_nil :: (IsSource a2) => Label -> a2 -> Op is_nil a1 a2 = Op 52 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a binary. is_binary :: (IsSource a2) => Label -> a2 -> Op is_binary a1 a2 = Op 53 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a cons or nil. is_list :: (IsSource a2) => Label -> a2 -> Op is_list a1 a2 = Op 55 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a cons. is_nonempty_list :: (IsSource a2) => Label -> a2 -> Op is_nonempty_list a1 a2 = Op 56 [FromLabel a1, fromSource a2] -- | Test the type of source and jump to label if it is not a tuple. is_tuple :: (IsSource a2) => Label -> a2 -> Op is_tuple a1 a2 = Op 57 [FromLabel a1, fromSource a2] -- | Test the arity of (the tuple in) source and jump to label if it is not equal to arity. test_arity :: (IsSource a2) => Label -> a2 -> Int -> Op test_arity a1 a2 a3 = Op 58 [FromLabel a1, fromSource a2, FromUntagged a3] -- | Jump to the destination label corresponding to source -- in the destinations list, if no arity matches, jump to fail label. select_val :: (IsSource a1) => a1 -> Label -> [(Label, Source)] -> Op select_val a1 a2 a3 = Op 59 [fromSource a1, FromLabel a2, fromDestinations a3] -- | Check the arity of the source tuple and jump to the corresponding -- destination label, if no arity matches, jump to FailLabel. select_tuple_arity :: (IsSource a1) => a1 -> Label -> [(Label, Source)] -> Op select_tuple_arity a1 a2 a3 = Op 60 [fromSource a1, FromLabel a2, fromDestinations a3] -- | Jump to label. jump :: Label -> Op jump a1 = Op 61 [FromLabel a1] -- | Old-style catch. catch :: Y -> Label -> Op catch a1 a2 = Op 62 [FromY a1, FromLabel a2] catch_end :: Y -> Op catch_end a1 = Op 63 [FromY a1] -- | Move the source (a literal or a register) to -- the destination register. move :: (IsSource a1, IsRegister a2) => a1 -> a2 -> Op move a1 a2 = Op 64 [fromSource a1, fromRegister a2] -- | Get the head and tail (or car and cdr) parts of a list -- (a cons cell) from the initial register and put them into the registers. get_list :: (IsRegister a1, IsRegister a2, IsRegister a3) => a1 -- ^ where to get the list -> a2 -- ^ where to put the head (car) -> a3 -- ^ where to put the tail (cdr) -> Op get_list a1 a2 a3 = Op 65 [fromRegister a1, fromRegister a2, fromRegister a3] -- | Get a particular element number from the tuple in source and put -- it in the destination register. get_tuple_element :: (IsRegister a1, IsRegister a3) => a1 -- ^ where to get the tuple -> Int -- ^ target element index, __0-based__ -> a3 -- ^ where to put the element -> Op get_tuple_element a1 a2 a3 = Op 66 [fromRegister a1, FromUntagged a2, fromRegister a3] -- | Update the element at position of the tuple in register -- with the new source element. set_tuple_element :: (IsSource a1, IsRegister a2) => a1 -> a2 -> Int -> Op set_tuple_element a1 a2 a3 = Op 67 [fromSource a1, fromRegister a2, FromUntagged a3] -- | Build a list, from the front, and puts the resulting list in the register. -- Just like Erlang's @|@ or Haskell's @:@. put_list :: (IsSource a1, IsSource a2, IsRegister a3) => a1 -- ^ the new head -> a2 -- ^ the new tail -> a3 -> Op put_list a1 a2 a3 = Op 69 [fromSource a1, fromSource a2, fromRegister a3] -- | Constructs an empty tuple on the heap (size+1 words) -- and places its address into the Destination register. -- No elements are set at this moment. -- Put_tuple instruction is always followed by multiple -- 'put' instructions which destructively set its elements one by one. put_tuple :: (IsRegister a2) => Int -> a2 -> Op put_tuple a1 a2 = Op 70 [FromUntagged a1, fromRegister a2] put :: (IsSource a1) => a1 -> Op put a1 = Op 71 [fromSource a1] badmatch :: (IsSource a1) => a1 -> Op badmatch a1 = Op 72 [fromSource a1] if_end :: Op if_end = Op 73 [] case_end :: (IsSource a1) => a1 -> Op case_end a1 = Op 74 [fromSource a1] -- | Call @fun@ object (in x[Arity]) with args (in x[0..Arity-1]) -- Raises @badarity@ if the arity doesn’t match the function object. -- Raises @badfun@ if a non-function is passed. call_fun :: Int -- ^ arity -> Op call_fun a1 = Op 75 [FromUntagged a1] -- | Test the type of the source and jump to label if it is not a -- function (i.e. fun or closure). is_function :: (IsSource a2) => Label -> a2 -> Op is_function a1 a2 = Op 77 [FromLabel a1, fromSource a2] -- | Do a tail recursive call to the function at label. -- Do not update the CP register. call_ext_only :: Import -> Op call_ext_only a1 = Op 78 [FromUntagged (_import_arity a1), FromImport a1] bs_put_integer :: (IsSource a2, IsSource a5) => Label -> a2 -> Int -> Int -> a5 -> Op bs_put_integer a1 a2 a3 a4 a5 = Op 89 [FromLabel a1, fromSource a2, FromUntagged a3, FromUntagged a4, fromSource a5] bs_put_binary :: (IsSource a2, IsSource a5) => Label -> a2 -> Int -> Int -> a5 -> Op bs_put_binary a1 a2 a3 a4 a5 = Op 90 [FromLabel a1, fromSource a2, FromUntagged a3, FromUntagged a4, fromSource a5] bs_put_float :: (IsSource a2, IsSource a5) => Label -> a2 -> Int -> Int -> a5 -> Op bs_put_float a1 a2 a3 a4 a5 = Op 91 [FromLabel a1, fromSource a2, FromUntagged a3, FromUntagged a4, fromSource a5] bs_put_string :: Int -> Int -> Op bs_put_string a1 a2 = Op 92 [FromUntagged a1, FromUntagged a2] fclearerror :: Op fclearerror = Op 94 [] fcheckerror :: Label -> Op fcheckerror a1 = Op 95 [FromLabel a1] fmove :: (IsSourceF a1, IsRegisterF a2) => a1 -> a2 -> Op fmove a1 a2 = Op 96 [fromSourceF a1, fromRegisterF a2] fconv :: (IsSource a1) => a1 -> F -> Op fconv a1 a2 = Op 97 [fromSource a1, FromF a2] fadd :: F -> F -> F -> Op fadd a1 a2 a3 = Op 98 [FromLabel (Label 0), FromF a1, FromF a2, FromF a3] fsub :: F -> F -> F -> Op fsub a1 a2 a3 = Op 99 [FromLabel (Label 0), FromF a1, FromF a2, FromF a3] fmul :: F -> F -> F -> Op fmul a1 a2 a3 = Op 100 [FromLabel (Label 0), FromF a1, FromF a2, FromF a3] fdiv :: F -> F -> F -> Op fdiv a1 a2 a3 = Op 101 [FromLabel (Label 0), FromF a1, FromF a2, FromF a3] fnegate :: F -> F -> Op fnegate a1 a2 = Op 102 [FromLabel (Label 0), FromF a1, FromF a2] make_fun2 :: Lambda -> Op make_fun2 a1 = Op 103 [FromLambda a1] try :: Y -> Label -> Op try a1 a2 = Op 104 [FromY a1, FromLabel a2] try_end :: Y -> Op try_end a1 = Op 105 [FromY a1] try_case :: Y -> Op try_case a1 = Op 106 [FromY a1] try_case_end :: (IsSource a1) => a1 -> Op try_case_end a1 = Op 107 [fromSource a1] raise :: (IsSource a1, IsSource a2) => a1 -> a2 -> Op raise a1 a2 = Op 108 [fromSource a1, fromSource a2] bs_init2 :: (IsSource a2, IsRegister a6) => Label -> a2 -> Int -> Int -> Int -> a6 -> Op bs_init2 a1 a2 a3 a4 a5 a6 = Op 109 [FromLabel a1, fromSource a2, FromUntagged a3, FromUntagged a4, FromUntagged a5, fromRegister a6] bs_add :: (IsSource a2, IsSource a3, IsRegister a5) => Label -> a2 -> a3 -> Int -> a5 -> Op bs_add a1 a2 a3 a4 a5 = Op 111 [FromLabel a1, fromSource a2, fromSource a3, FromUntagged a4, fromRegister a5] -- | Apply function object (in x[arity]) with args (in x[0..arity-1]) apply :: Int -- ^ arity -> Op apply a1 = Op 112 [FromUntagged a1] -- | Same as 'apply' but does not save the CP and deallocates words apply_last :: Int -- ^ arity -> Int -- ^ words to deallocate -> Op apply_last a1 a2 = Op 113 [FromUntagged a1, FromUntagged a2] -- | Test the type of source and jump to label if it is not a boolean. is_boolean :: (IsSource a2) => Label -> a2 -> Op is_boolean a1 a2 = Op 114 [FromLabel a1, fromSource a2] -- | Test the type of the source and jump to label if it is not a -- function of the particular arity. is_function2 :: (IsSource a2, IsSource a3) => Label -> a2 -- ^ possible function -> a3 -- ^ possible arity -> Op is_function2 a1 a2 a3 = Op 115 [FromLabel a1, fromSource a2, fromSource a3] bs_start_match2 :: (IsSource a2, IsRegister a5) => Label -> a2 -> Int -> Int -> a5 -> Op bs_start_match2 a1 a2 a3 a4 a5 = Op 116 [FromLabel a1, fromSource a2, FromUntagged a3, FromUntagged a4, fromRegister a5] bs_get_integer2 :: (IsSource a4, IsRegister a7) => Label -> X -> Int -> a4 -> Int -> Int -> a7 -> Op bs_get_integer2 a1 a2 a3 a4 a5 a6 a7 = Op 117 [FromLabel a1, FromX a2, FromUntagged a3, fromSource a4, FromUntagged a5, FromUntagged a6, fromRegister a7] bs_get_float2 :: (IsSource a4, IsRegister a7) => Label -> X -> Int -> a4 -> Int -> Int -> a7 -> Op bs_get_float2 a1 a2 a3 a4 a5 a6 a7 = Op 118 [FromLabel a1, FromX a2, FromUntagged a3, fromSource a4, FromUntagged a5, FromUntagged a6, fromRegister a7] bs_get_binary2 :: (IsSource a4, IsRegister a7) => Label -> X -> Int -> a4 -> Int -> Int -> a7 -> Op bs_get_binary2 a1 a2 a3 a4 a5 a6 a7 = Op 119 [FromLabel a1, FromX a2, FromUntagged a3, fromSource a4, FromUntagged a5, FromUntagged a6, fromRegister a7] bs_skip_bits2 :: (IsSource a3) => Label -> X -> a3 -> Int -> Int -> Op bs_skip_bits2 a1 a2 a3 a4 a5 = Op 120 [FromLabel a1, FromX a2, fromSource a3, FromUntagged a4, FromUntagged a5] bs_test_tail2 :: Label -> X -> Int -> Op bs_test_tail2 a1 a2 a3 = Op 121 [FromLabel a1, FromX a2, FromUntagged a3] bs_save2 :: (IsRegister a1) => a1 -> Int -> Op bs_save2 a1 a2 = Op 122 [fromRegister a1, FromUntagged a2] bs_restore2 :: (IsRegister a1) => a1 -> Int -> Op bs_restore2 a1 a2 = Op 123 [fromRegister a1, FromUntagged a2] -- | Call the bif with the argument, and store the result in the register. -- On failure jump to label. -- Do a garbage collection if necessary to allocate space on the heap -- for the result. gc_bif1 :: (Bif1 a3, IsSource a4, IsRegister a5) => Label -- ^ jump here on failure -> Int -- ^ number of X-registers to save -> a3 -- ^ BIF, something like 'Codec.Beam.Bifs.erlang_localtime' -> a4 -- ^ argument -> a5 -- ^ where to put the result -> Op gc_bif1 a1 a2 a3 a4 a5 = Op 124 [FromLabel a1, FromUntagged a2, FromImport (importBif1 a3), fromSource a4, fromRegister a5] -- | Same as 'gc_bif1', but with two source arguments. gc_bif2 :: (Bif2 a3, IsSource a4, IsSource a5, IsRegister a6) => Label -> Int -> a3 -> a4 -> a5 -> a6 -> Op gc_bif2 a1 a2 a3 a4 a5 a6 = Op 125 [FromLabel a1, FromUntagged a2, FromImport (importBif2 a3), fromSource a4, fromSource a5, fromRegister a6] is_bitstr :: (IsSource a2) => Label -> a2 -> Op is_bitstr a1 a2 = Op 129 [FromLabel a1, fromSource a2] bs_context_to_binary :: (IsRegister a1) => a1 -> Op bs_context_to_binary a1 = Op 130 [fromRegister a1] bs_test_unit :: Label -> X -> Int -> Op bs_test_unit a1 a2 a3 = Op 131 [FromLabel a1, FromX a2, FromUntagged a3] bs_match_string :: Label -> X -> Int -> Int -> Op bs_match_string a1 a2 a3 a4 = Op 132 [FromLabel a1, FromX a2, FromUntagged a3, FromUntagged a4] bs_init_writable :: Op bs_init_writable = Op 133 [] bs_append :: (IsSource a2, IsSource a6, IsRegister a8) => Label -> a2 -> Int -> Int -> Int -> a6 -> Int -> a8 -> Op bs_append a1 a2 a3 a4 a5 a6 a7 a8 = Op 134 [FromLabel a1, fromSource a2, FromUntagged a3, FromUntagged a4, FromUntagged a5, fromSource a6, FromUntagged a7, fromRegister a8] bs_private_append :: (IsSource a2, IsSource a4, IsRegister a6) => Label -> a2 -> Int -> a4 -> Int -> a6 -> Op bs_private_append a1 a2 a3 a4 a5 a6 = Op 135 [FromLabel a1, fromSource a2, FromUntagged a3, fromSource a4, FromUntagged a5, fromRegister a6] -- | Reduce the stack usage by some number of words, -- keeping the CP on the top of the stack. trim :: Int -- ^ words to remove -> Int -- ^ words ro keep -> Op trim a1 a2 = Op 136 [FromUntagged a1, FromUntagged a2] bs_init_bits :: (IsSource a2, IsRegister a6) => Label -> a2 -> Int -> Int -> Int -> a6 -> Op bs_init_bits a1 a2 a3 a4 a5 a6 = Op 137 [FromLabel a1, fromSource a2, FromUntagged a3, FromUntagged a4, FromUntagged a5, fromRegister a6] bs_get_utf8 :: (IsRegister a5) => Label -> X -> Int -> Int -> a5 -> Op bs_get_utf8 a1 a2 a3 a4 a5 = Op 138 [FromLabel a1, FromX a2, FromUntagged a3, FromUntagged a4, fromRegister a5] bs_skip_utf8 :: Label -> X -> Int -> Int -> Op bs_skip_utf8 a1 a2 a3 a4 = Op 139 [FromLabel a1, FromX a2, FromUntagged a3, FromUntagged a4] bs_get_utf16 :: (IsRegister a5) => Label -> X -> Int -> Int -> a5 -> Op bs_get_utf16 a1 a2 a3 a4 a5 = Op 140 [FromLabel a1, FromX a2, FromUntagged a3, FromUntagged a4, fromRegister a5] bs_skip_utf16 :: Label -> X -> Int -> Int -> Op bs_skip_utf16 a1 a2 a3 a4 = Op 141 [FromLabel a1, FromX a2, FromUntagged a3, FromUntagged a4] bs_get_utf32 :: (IsRegister a5) => Label -> X -> Int -> Int -> a5 -> Op bs_get_utf32 a1 a2 a3 a4 a5 = Op 142 [FromLabel a1, FromX a2, FromUntagged a3, FromUntagged a4, fromRegister a5] bs_skip_utf32 :: Label -> X -> Int -> Int -> Op bs_skip_utf32 a1 a2 a3 a4 = Op 143 [FromLabel a1, FromX a2, FromUntagged a3, FromUntagged a4] bs_utf8_size :: (IsSource a2, IsRegister a3) => Label -> a2 -> a3 -> Op bs_utf8_size a1 a2 a3 = Op 144 [FromLabel a1, fromSource a2, fromRegister a3] bs_put_utf8 :: (IsSource a3) => Label -> Int -> a3 -> Op bs_put_utf8 a1 a2 a3 = Op 145 [FromLabel a1, FromUntagged a2, fromSource a3] bs_utf16_size :: (IsSource a2, IsRegister a3) => Label -> a2 -> a3 -> Op bs_utf16_size a1 a2 a3 = Op 146 [FromLabel a1, fromSource a2, fromRegister a3] bs_put_utf16 :: (IsSource a3) => Label -> Int -> a3 -> Op bs_put_utf16 a1 a2 a3 = Op 147 [FromLabel a1, FromUntagged a2, fromSource a3] bs_put_utf32 :: (IsSource a3) => Label -> Int -> a3 -> Op bs_put_utf32 a1 a2 a3 = Op 148 [FromLabel a1, FromUntagged a2, fromSource a3] on_load :: Op on_load = Op 149 [] -- | Save the end of the message queue and the address of -- the label so that a recv_set instruction can start -- | scanning the inbox from this position. recv_mark :: Label -> Op recv_mark a1 = Op 150 [FromLabel a1] -- | Check that the saved mark points to label and set the -- save pointer in the message queue to the last position -- of the message queue saved by the recv_mark instruction. recv_set :: Label -> Op recv_set a1 = Op 151 [FromLabel a1] -- | Same as 'gc_bif1', but with three source arguments. gc_bif3 :: (Bif3 a3, IsSource a4, IsSource a5, IsSource a6, IsRegister a7) => Label -> Int -> a3 -> a4 -> a5 -> a6 -> a7 -> Op gc_bif3 a1 a2 a3 a4 a5 a6 a7 = Op 152 [FromLabel a1, FromUntagged a2, FromImport (importBif3 a3), fromSource a4, fromSource a5, fromSource a6, fromRegister a7] line :: Int -> Op line a1 = Op 153 [FromUntagged a1] put_map_assoc :: (IsSource a2, IsRegister a3) => Label -> a2 -> a3 -> [(Source, Source)] -> Op put_map_assoc a1 a2 a3 a4 = Op 154 [FromLabel a1, fromSource a2, fromRegister a3, FromUntagged (length a4 + 1), fromPairs fromSource fromSource a4] put_map_exact :: (IsSource a2, IsRegister a3) => Label -> a2 -> a3 -> [(Source, Source)] -> Op put_map_exact a1 a2 a3 a4 = Op 155 [FromLabel a1, fromSource a2, fromRegister a3, FromUntagged (length a4 + 1), fromPairs fromSource fromSource a4] is_map :: (IsSource a2) => Label -> a2 -> Op is_map a1 a2 = Op 156 [FromLabel a1, fromSource a2] has_map_fields :: (IsSource a2) => Label -> a2 -> [Source] -> Op has_map_fields a1 a2 a3 = Op 157 [FromLabel a1, fromSource a2, FromList (map fromSource a3)] -- | Get multiple values out of a map get_map_elements :: (IsSource a2) => Label -- ^ jump here on failure -> a2 -- ^ where the map is -> [(Source, Register)] -- ^ list of (what key to use, where to put value) -> Op get_map_elements a1 a2 a3 = Op 158 [FromLabel a1, fromSource a2, fromPairs fromSource fromRegister a3] -- | Test the type of source and jumps to label if it is not a tuple. -- Test the arity of Reg and jumps to label if it is not of the given size. -- Test the first element of the tuple and jumps to label if it is not given atom. is_tagged_tuple :: (IsSource a2) => Label -> a2 -> Int -> Text -> Op is_tagged_tuple a1 a2 a3 a4 = Op 159 [FromLabel a1, fromSource a2, FromUntagged a3, FromAtom a4]